ERL_NIF_TERM to_erl(ErlNifEnv* env, JSContext* cx, jsval val) { ERL_NIF_TERM ret = util_mk_atom(env, "undefined"); if(!to_erl_intern(env, cx, val, &ret)) { return util_mk_atom(env, "undefined"); } return ret; }
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); }
ENTERM vm_mk_message(ErlNifEnv* env, ENTERM data) { ENTERM message = util_mk_atom(env, "message"); return enif_make_tuple2(env, message, data); }
ENTERM vm_mk_error(ErlNifEnv* env, ENTERM reason) { ENTERM error = util_mk_atom(env, "error"); return enif_make_tuple2(env, error, reason); }
ENTERM vm_mk_ok(ErlNifEnv* env, ENTERM reason) { ENTERM ok = util_mk_atom(env, "ok"); return enif_make_tuple2(env, ok, reason); }
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); }
int to_erl_atom(ErlNifEnv* env, const char* atom, ERL_NIF_TERM* term) { *term = util_mk_atom(env, atom); return OK; }