From f81238dcdc56a93b553aa1fe63dcc5a81f5ee45d Mon Sep 17 00:00:00 2001 From: Nicolas R Dufour Date: Sat, 14 May 2011 17:58:00 -0400 Subject: [PATCH 1/3] Porting to spidermonkey 1.8.5 --- c_src/to_erl.c | 6 +++--- c_src/vm.c | 15 ++++++++------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/c_src/to_erl.c b/c_src/to_erl.c index 04592db..a284770 100644 --- a/c_src/to_erl.c +++ b/c_src/to_erl.c @@ -26,7 +26,7 @@ to_erl_string(ErlNifEnv* env, JSContext* cx, jsval val, ERL_NIF_TERM* term) size_t len; str = JS_ValueToString(cx, val); - data = JS_GetStringBytesZ(cx, str); + data = JS_EncodeString(cx, str); if(data == NULL) return ERROR; len = strlen(data); @@ -106,7 +106,7 @@ to_erl_object(ErlNifEnv* env, JSContext* cx, JSObject* obj, ERL_NIF_TERM* term) length = 0; while(JS_NextProperty(cx, iter, &idp)) { - if(idp == JSVAL_VOID) break; + if(idp == JSID_VOID) break; length += 1; } @@ -119,7 +119,7 @@ to_erl_object(ErlNifEnv* env, JSContext* cx, JSObject* obj, ERL_NIF_TERM* term) index = 0; while(JS_NextProperty(cx, iter, &idp)) { - if(idp == JSVAL_VOID) + if(idp == JSID_VOID) { list = enif_make_list_from_array(env, array, length); *term = enif_make_tuple1(env, list); diff --git a/c_src/vm.c b/c_src/vm.c index 246c9d2..9bd8f5f 100644 --- a/c_src/vm.c +++ b/c_src/vm.c @@ -51,7 +51,7 @@ static JSClass global_class = { JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_PropertyStub, + JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, @@ -109,7 +109,7 @@ static JSClass jserl_class = { JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_PropertyStub, + JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, @@ -118,12 +118,13 @@ static JSClass jserl_class = { }; static JSBool -jserl_send(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) +jserl_send(JSContext* cx, uintN argc, jsval* vp) { vm_ptr vm = (vm_ptr) JS_GetContextPrivate(cx); ErlNifEnv* env; job_ptr job; ENTERM mesg; + jsval* argv = JS_ARGV(cx, vp); if(argc < 0) { @@ -154,7 +155,7 @@ jserl_send(JSContext* cx, JSObject* obj, uintN argc, jsval* argv, jsval* rval) assert(job->type == job_response && "Invalid message response."); - *rval = to_js(job->env, cx, job->args); + JS_SET_RVAL(cx, vp, to_js(job->env, cx, job->args)); job_destroy(job); return JS_TRUE; @@ -257,8 +258,8 @@ vm_run(void* arg) flags |= JSOPTION_COMPILE_N_GO; flags |= JSOPTION_XML; JS_SetOptions(cx, JS_GetOptions(cx) | flags); - - gl = JS_NewObject(cx, &global_class, NULL, NULL); + + gl = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); if(gl == NULL) { fprintf(stderr, "Failed to create global object.\n"); @@ -430,7 +431,7 @@ vm_call(JSContext* cx, JSObject* gl, job_ptr job) jsval rval; jsid idp; int argc; - + // Get the function object. func = to_js(job->env, cx, job->name); From 6e05b2ddcbd0e859473ac55fcd1e7bf8e6860bc7 Mon Sep 17 00:00:00 2001 From: benoitc Date: Fri, 20 May 2011 18:23:57 +0200 Subject: [PATCH 2/3] compat with old spidermonkey > 1.8.0rc1 --- c_src/to_erl.c | 7 ++++++ c_src/vm.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++- c_src/vm.h | 5 +++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/c_src/to_erl.c b/c_src/to_erl.c index a284770..aad97f5 100644 --- a/c_src/to_erl.c +++ b/c_src/to_erl.c @@ -8,6 +8,13 @@ #define OK 1 #define ERROR 0 +#ifndef JSID_VOID +#include +#define JSID_VOID JSVAL_VOID +#endif + + + int to_erl_intern(ErlNifEnv* env, JSContext* cx, jsval val, ERL_NIF_TERM* term); int diff --git a/c_src/vm.c b/c_src/vm.c index 9bd8f5f..b1b3293 100644 --- a/c_src/vm.c +++ b/c_src/vm.c @@ -8,6 +8,7 @@ #include "util.h" #include "vm.h" + typedef enum { job_unknown, @@ -45,13 +46,18 @@ struct vm_t int alive; }; + static JSClass global_class = { "global", JSCLASS_GLOBAL_FLAGS, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, +#ifdef JS185 JS_StrictPropertyStub, +#else + JS_PropertyStub, +#endif JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, @@ -59,6 +65,7 @@ static JSClass global_class = { JSCLASS_NO_OPTIONAL_MEMBERS }; + void* vm_run(void* arg); ENTERM vm_eval(JSContext* cx, JSObject* gl, job_ptr job); ENTERM vm_call(JSContext* cx, JSObject* gl, job_ptr job); @@ -109,7 +116,11 @@ static JSClass jserl_class = { JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, +#ifdef JS185 JS_StrictPropertyStub, +#else + JS_PropertyStub, +#endif JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, @@ -117,6 +128,7 @@ static JSClass jserl_class = { JSCLASS_NO_OPTIONAL_MEMBERS }; +#ifdef JS185 static JSBool jserl_send(JSContext* cx, uintN argc, jsval* vp) { @@ -154,12 +166,54 @@ jserl_send(JSContext* cx, uintN argc, jsval* vp) } assert(job->type == job_response && "Invalid message response."); - JS_SET_RVAL(cx, vp, to_js(job->env, cx, job->args)); job_destroy(job); return JS_TRUE; } +#else +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; +} +#endif int install_jserl(JSContext* cx, JSObject* gl) @@ -259,7 +313,11 @@ vm_run(void* arg) flags |= JSOPTION_XML; JS_SetOptions(cx, JS_GetOptions(cx) | flags); +#ifdef JS185 gl = JS_NewCompartmentAndGlobalObject(cx, &global_class, NULL); +#else + gl = JS_NewObject(cx, &global_class, NULL, NULL); +#endif if(gl == NULL) { fprintf(stderr, "Failed to create global object.\n"); diff --git a/c_src/vm.h b/c_src/vm.h index 57232cf..2b7d55b 100644 --- a/c_src/vm.h +++ b/c_src/vm.h @@ -9,6 +9,11 @@ #include "alias.h" + +#ifdef JS_NewCompartmentAndGlobalObject +#define JS185 1 +#endif + typedef struct vm_t* vm_ptr; vm_ptr vm_init(ErlNifResourceType* res_type, JSRuntime* runtime, size_t stack_size); From 28c883d1ce5a150df24a1efeffba4d039a22f46f Mon Sep 17 00:00:00 2001 From: benoitc Date: Sat, 21 May 2011 07:33:34 +0200 Subject: [PATCH 3/3] fix tests on none smp platforms --- test/004-basic-calls.t | 2 +- test/005-erl-to-js.t | 2 +- test/006-js-to-erl.t | 2 +- test/007-js-send-message.t | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/004-basic-calls.t b/test/004-basic-calls.t index 1f326b4..3d28e22 100755 --- a/test/004-basic-calls.t +++ b/test/004-basic-calls.t @@ -1,5 +1,5 @@ #!/usr/bin/env escript -%%! -pa ./test/ -pa ./ebin/ +%%! -smp +K true -pa ./test/ -pa ./ebin/ % This file is part of Emonk released under the MIT license. % See the LICENSE file for more information. diff --git a/test/005-erl-to-js.t b/test/005-erl-to-js.t index 6fed28a..aa45103 100755 --- a/test/005-erl-to-js.t +++ b/test/005-erl-to-js.t @@ -1,5 +1,5 @@ #!/usr/bin/env escript -%%! -pa ./test/ -pa ./ebin/ +%%! -smp +K true -pa ./test/ -pa ./ebin/ % This file is part of Emonk released under the MIT license. % See the LICENSE file for more information. diff --git a/test/006-js-to-erl.t b/test/006-js-to-erl.t index cf7c27e..f4ba89c 100755 --- a/test/006-js-to-erl.t +++ b/test/006-js-to-erl.t @@ -1,5 +1,5 @@ #!/usr/bin/env escript -%%! -pa ./test/ -pa ./ebin/ +%%! -smp +K true -pa ./test/ -pa ./ebin/ % This file is part of Emonk released under the MIT license. % See the LICENSE file for more information. diff --git a/test/007-js-send-message.t b/test/007-js-send-message.t index d5c6eda..e3399cf 100755 --- a/test/007-js-send-message.t +++ b/test/007-js-send-message.t @@ -1,5 +1,5 @@ #!/usr/bin/env escript -%%! -pa ./test/ -pa ./ebin/ +%%! -smp +K true -pa ./test/ -pa ./ebin/ % This file is part of Emonk released under the MIT license. % See the LICENSE file for more information.