/* * Get the listener IP address */ int CVmObjHTTPServer::getp_get_ip(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *oargc) { static CVmNativeCodeDesc desc(0); if (get_prop_check_argc(retval, oargc, &desc)) return TRUE; /* return the IP address */ char *ip, *addr; int port; if (get_listener_addr(addr, ip, port)) { /* got it - return the string value */ G_interpreter->push_string(vmg_ ip); G_stk->pop(retval); /* free the source strings */ lib_free_str(addr); lib_free_str(ip); } else { /* no IP address - return nil */ retval->set_nil(); } /* handled */ return TRUE; }
/* * Get a property */ int CVmObjAnonFn::get_prop(VMG_ vm_prop_id_t prop, vm_val_t *val, vm_obj_id_t self, vm_obj_id_t *source_obj, uint *argc) { /* * if the property is the special ObjectCallProp property, return * our first element */ if (prop == G_predef->obj_call_prop && prop != VM_INVALID_PROP) { static CVmNativeCodeDesc desc(0); /* check for arguments */ if (get_prop_check_argc(val, argc, &desc)) return TRUE; /* return our first element */ get_element(0, val); /* we're the source object */ *source_obj = self; /* success */ return TRUE; } /* it's not one of our own - inherit default handling */ return CVmObjVector::get_prop(vmg_ prop, val, self, source_obj, argc); }
/* * property evaluator - get 'invokee' from the frame */ int CVmObjFrameDesc::getp_get_invokee(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *argc) { /* check arguments */ static CVmNativeCodeDesc desc(0); if (get_prop_check_argc(retval, argc, &desc)) return TRUE; /* get 'invokee' from the frame */ get_frame_ref(vmg0_)->get_invokee(vmg_ retval); /* handled */ return TRUE; }
/* * property evaluator - determine if the frame is still alive */ int CVmObjFrameDesc::getp_is_active(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *argc) { /* check arguments */ static CVmNativeCodeDesc desc(0); if (get_prop_check_argc(retval, argc, &desc)) return TRUE; /* the frame is valid if we still have a frame pointer */ retval->set_logical(get_frame_ref(vmg0_)->is_active()); /* handled */ return TRUE; }
/* * Shut down the server */ int CVmObjHTTPServer::getp_shutdown(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *oargc) { uint argc = (oargc != 0 ? *oargc : 0); static CVmNativeCodeDesc desc(0, 1); if (get_prop_check_argc(retval, oargc, &desc)) return TRUE; /* check arguments */ int wait = FALSE; if (argc >= 1) wait = CVmBif::pop_bool_val(vmg0_); /* if we have a listener, tell it to shut down */ vm_httpsrv_ext *ext = get_ext(); if (ext != 0 && ext->l != 0) { /* add a reference on the listener while we're using it */ ext->l->add_ref(); /* shut down the server */ ext->l->shutdown(); /* if we're waiting, wait for the listener thread to exit */ if (wait) ext->l->get_thread()->wait(); /* * Return true if the thread is done, nil if it's still running. * The main listener thread waits for all of its launched server * threads to exit before it itself exits, so once the listener * thread is done, we can be sure that all of its launched threads * are done as well. */ retval->set_logical(ext->l->get_thread()->test()); /* done with the listener */ ext->l->release_ref(); } else { /* there is no server, so it's already shut down */ retval->set_true(); } /* handled */ return TRUE; }
/* * static method: isIntrinsicClass(x) */ int CVmObjClass::s_getp_is_int_class(VMG_ vm_val_t *result, uint *argc) { /* check arguments */ static CVmNativeCodeDesc desc(1); if (get_prop_check_argc(result, argc, &desc)) return TRUE; /* return true if we have an object of type intrinsic class */ vm_val_t *v = G_stk->get(0); result->set_logical(v->typ == VM_OBJ && is_intcls_obj(vmg_ v->val.obj)); /* discard the argument */ G_stk->discard(); /* handled */ return TRUE; }
/* * Create an iterator */ int CVmObjCollection::getp_create_iter(VMG_ vm_val_t *retval, const vm_val_t *self_val, uint *argc) { static CVmNativeCodeDesc desc(0); /* check arguments */ if (get_prop_check_argc(retval, argc, &desc)) return TRUE; /* push a self-reference for gc protection */ G_stk->push(self_val); /* create the iterator */ new_iterator(vmg_ retval, self_val); /* discard the gc protection */ G_stk->discard(); /* handled */ return TRUE; }
/* * Get the port number */ int CVmObjHTTPServer::getp_get_port(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *oargc) { static CVmNativeCodeDesc desc(0); if (get_prop_check_argc(retval, oargc, &desc)) return TRUE; /* return the port number */ char *addr, *ip; int port; if (get_listener_addr(addr, ip, port)) { retval->set_int(port); lib_free_str(addr); lib_free_str(ip); } else retval->set_nil(); /* handled */ return TRUE; }
/* * Get the listener address */ int CVmObjHTTPServer::getp_get_addr(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *oargc) { static CVmNativeCodeDesc desc(0); if (get_prop_check_argc(retval, oargc, &desc)) return TRUE; /* if we have an address string saved, return it */ vm_httpsrv_ext *ext = get_ext(); if (ext != 0 && ext->addr != 0) { /* got it - return the string value */ G_interpreter->push_string(vmg_ ext->addr); G_stk->pop(retval); } else { /* no address value - return nil */ retval->set_nil(); } /* handled */ return TRUE; }
/* * property evaluator - get a lookup table of the local variables, with * their current values, keyed by name */ int CVmObjFrameDesc::getp_get_vars(VMG_ vm_obj_id_t self, vm_val_t *retval, uint *argc) { /* check arguments */ static CVmNativeCodeDesc desc(0); if (get_prop_check_argc(retval, argc, &desc)) return TRUE; /* create our lookup table object */ retval->set_obj(CVmObjLookupTable::create(vmg_ FALSE, 32, 64)); CVmObjLookupTable *tab = (CVmObjLookupTable *) vm_objp(vmg_ retval->val.obj); /* get our extension */ vm_framedesc_ext *ext = get_ext(); /* get our underlying frame ref and its extension */ CVmObjFrameRef *fr = get_frame_ref(vmg0_); vm_frameref_ext *fext = fr->get_ext(); /* set up pointer to this method's debug records */ CVmDbgTablePtr dp; if (!dp.set(fext->entryp)) return TRUE; /* set up a pointer to our frame */ CVmDbgFramePtr dfp; dp.set_frame_ptr(vmg_ &dfp, ext->frame_idx); /* push the table for gc protection */ G_stk->push(retval); /* walk up the list of frames from innermost to outermost */ for (;;) { /* set up a pointer to the first symbol */ CVmDbgFrameSymPtr sym; dfp.set_first_sym_ptr(vmg_ &sym); /* scan this frame's local symbol list */ int sym_cnt = dfp.get_sym_count(); for (int i = 0 ; i < sym_cnt ; ++i, sym.inc(vmg0_)) { /* set up a string value for the key */ vm_val_t key; sym.get_str_val(vmg_ &key); G_stk->push(&key); /* * If this entry isn't already in the table, add it. Don't * bother if it already exists: we work from inner to outer * scopes, and inner scopes hide things in outer scopes, so if * we find an entry in the table already it means that it was * an inner-scope entry that hides the one we're processing * now. */ vm_val_t val; if (!tab->index_check(vmg_ &val, &key)) { /* get the value */ fr->get_local_val(vmg_ &val, &sym); /* add the entry to the table */ tab->add_entry(vmg_ &key, &val); } /* done with the key for gc protection */ G_stk->discard(); } /* move up to the enclosing frame */ int parent = dfp.get_enclosing_frame(); if (parent == 0) break; /* set up dfp to point to the parent fraem */ dp.set_frame_ptr(vmg_ &dfp, parent); } /* discard the table ref we pushed for gc protection */ G_stk->discard(); /* handled */ return TRUE; }