static JSBool jserl_send(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) { vm_ptr vm = (vm_ptr) JS_GetContextPrivate(cx); ErlNifEnv* env; job_ptr job; ENTERM mesg; if(argc < 0) { return JS_FALSE; } assert(vm != NULL && "Context has no vm."); env = enif_alloc_env(); mesg = vm_mk_message(env, to_erl(env, cx, argv[0])); // If pid is not alive, raise an error. // XXX: Can I make this uncatchable? if(!enif_send(NULL, &(vm->curr_job->pid), env, mesg)) { JS_ReportError(cx, "Context closing."); return JS_FALSE; } job = queue_receive(vm->jobs); if(job->type == job_close) { // XXX: Can I make this uncatchable? job_destroy(job); JS_ReportError(cx, "Context closing."); return JS_FALSE; } assert(job->type == job_response && "Invalid message response."); *rval = to_js(job->env, cx, job->args); job_destroy(job); return JS_TRUE; }
ENTERM vm_eval(JSContext* cx, JSObject* gl, job_ptr job) { ENTERM resp; const char* script; size_t length; jsval rval; int cnt; int i; script = (const char*) job->script.data; length = job->script.size; for(i = 0, cnt = 0; i < length; i++) { if(script[i] == '\n') cnt += 1; } if(!JS_EvaluateScript(cx, gl, script, length, "", cnt, &rval)) { if(job->error != 0) { resp = vm_mk_error(job->env, job->error); } else { resp = vm_mk_error(job->env, util_mk_atom(job->env, "unknown")); } } else { resp = vm_mk_ok(job->env, to_erl(job->env, cx, rval)); } return enif_make_tuple2(job->env, job->ref, resp); }
int main(int argc,char **argv) { return to_erl(argc,argv); }
ENTERM vm_call(JSContext* cx, JSObject* gl, job_ptr job) { ENTERM resp; ENTERM head; ENTERM tail; jsval func; jsval args[256]; jsval rval; jsid idp; int argc; // Get the function object. func = to_js(job->env, cx, job->name); if(func == JSVAL_VOID) { resp = vm_mk_error(job->env, util_mk_atom(job->env, "invalid_name")); goto send; } if(!JS_ValueToId(cx, func, &idp)) { resp = vm_mk_error(job->env, util_mk_atom(job->env, "internal_error")); goto send; } if(!JS_GetPropertyById(cx, gl, idp, &func)) { resp = vm_mk_error(job->env, util_mk_atom(job->env, "bad_property")); goto send; } if(JS_TypeOfValue(cx, func) != JSTYPE_FUNCTION) { resp = vm_mk_error(job->env, util_mk_atom(job->env, "not_a_function")); goto send; } // Creating function arguments. if(enif_is_empty_list(job->env, job->args)) { argc = 0; } else { if(!enif_get_list_cell(job->env, job->args, &head, &tail)) { resp = vm_mk_error(job->env, util_mk_atom(job->env, "invalid_argv")); goto send; } argc = 0; do { args[argc++] = to_js(job->env, cx, head); } while(enif_get_list_cell(job->env, tail, &head, &tail) && argc < 256); } // Call function if(!JS_CallFunctionValue(cx, gl, func, argc, args, &rval)) { if(job->error != 0) { resp = vm_mk_error(job->env, job->error); } else { resp = vm_mk_error(job->env, util_mk_atom(job->env, "unknown")); } } else { resp = vm_mk_ok(job->env, to_erl(job->env, cx, rval)); } send: return enif_make_tuple2(job->env, job->ref, resp); }