Re: [jsapigen-devel] [PATCH 1/3] Make native calls compatible with spidermonkey 1.8.5
Status: Beta
Brought to you by:
tdz
From: Thomas Z. <td...@us...> - 2012-07-08 15:06:45
|
Hi Vincent, I applied this patch to my tree. Thanks a lot! In case you're interested, you can find a review below. Am Samstag, den 30.06.2012, 13:30 +0100 schrieb Vincent Sanders: > From: Vincent Sanders <vi...@co...> > > The spidermonkey native calling convention changed. This change allows > the generated output to be compiled using this new API. > > Also changed is the constructor object creation, the constructor is now > expected to create its own object requiring a forward declaration of the > class structure. > > This change does not introduce a distinct constructor element (like > finalizers etc.) though given the number of checks on is_constructor > this might be desirable. > > Signed-off-by: Vincent Sanders <vi...@ky...> > --- > src/jsapi.c | 25 ++++++++++++++++++++----- > src/jsapiout.c | 31 ++++++++++++++++++++++++++----- > src/native.c | 1 + > src/native.h | 1 + > src/symtabs.c | 2 ++ > 5 files changed, 50 insertions(+), 10 deletions(-) > > diff --git a/src/jsapi.c b/src/jsapi.c > index d2bc833..0af8e46 100644 > --- a/src/jsapi.c > +++ b/src/jsapi.c > @@ -1589,15 +1589,30 @@ jsapi_build_hlcltab() > "#define JS_EndRequest(cx)\n" > "#define JS_SuspendRequest(cx)\n" > "#define JS_ResumeRequest(cx, saveDepth)\n" > - "#endif\n" > - "#endif\n" > + "#endif /* JS_VERSION */\n" > + "#endif /* JS_THREADSAFE */\n" > + "\n" > /* Function macros */ > "#ifndef JS_FS\n" > - "#define JS_FS(name, call, nargs, flags, extra) {name, call, nargs, flags, extra}\n" > + "#define JJ_JS_FS(name, call, nargs, flags, extra) {name, call, nargs, flags, extra}\n" > + "#elif JS_VERSION >= 185\n" > + "#define JJ_JS_FS(name, call, nargs, flags, extra) JS_FS(name, call, nargs, flags)\n" > + "#else\n" > + "#define JJ_JS_FS(name, call, nargs, flags, extra) JS_FS(name, call, nargs, flags, extra)\n" > "#endif\n" > "#ifndef JS_FS_END\n" > - "#define JS_FS_END {NULL, NULL, 0, 0, 0}\n" > - "#endif\n"}; > + "#define JJ_JS_FS_END JJ_JS_FS(NULL, NULL, 0, 0, 0)\n" > + "#else\n" > + "#define JJ_JS_FS_END JS_FS_END\n" > + "#endif\n" I know I introduced this code block in the first place, but I think a better way would be to get rid of such defines and handle the differences in the generated code below. > + "\n" > + /* native entry macro */ > + "#if JS_VERSION >= 185\n" > + "#define JJ_JSNative(name) name(JSContext *cx, uintN argc, jsval *vp)\n" > + "#else\n" > + "#define JJ_JSNative(name) name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)\n" > + "#endif\n" Same here. > +}; > > static int regexit = 0; > > diff --git a/src/jsapiout.c b/src/jsapiout.c > index 5df6aa1..db741d6 100644 > --- a/src/jsapiout.c > +++ b/src/jsapiout.c > @@ -1187,9 +1187,30 @@ jsapi_out_enter_native(const struct hlcl *hlcl, struct jsapi_state *state, FILE > nat = hlcl->data.p.p; > assert(nat); > > - return sigfprintf(f, "static JSBool\n" > - "%s(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)\n" > - "{\n", nat->symbol); > + /* forward declare class for constructors */ > + if (nat->attrib.is_constructor && nat->class) { > + sigfprintf(f, "static JSClass %s_class;\n", nat->class->ns); > + } > + > + sigfprintf(f, > + "static JSBool\n" > + "JJ_JSNative(%s)\n" > + "{\n" > + "#if JS_VERSION >= 185\n" > + " jsval *argv = JS_ARGV(cx, vp);\n" > + " jsval *rval = vp;\n", nat->symbol); > + > + if (nat->attrib.is_constructor && nat->class) { I think this should also be handled at runtime via JS_IsConstruction(). Just in case someone uses the generated code for both cases. > + sigfprintf(f, > + " JSObject *obj = JS_NewObject(cx, &%s_class, NULL, NULL);\n" > + " *vp = OBJECT_TO_JSVAL(obj);\n" > + "#endif\n", > + nat->class->ns); > + } else { > + sigfprintf(f, > + " JSObject *obj = JS_THIS_OBJECT(cx, vp);\n" > + "#endif\n"); > + } > } One idea I had to handle the differences in the argument retrieval is to introduce IR tokens or retrieving objects, return values, arguments, etc. These would be called after having entered the native function and would generate the respective JS_VERSION-dependent code blocks. > static int > @@ -1474,7 +1495,7 @@ jsapi_out_leave_func_table(const struct hlcl *hlcl, struct jsapi_state *state, F > assert(state); > assert(f); > > - return sigfprintf(f, " JS_FS_END\n" > + return sigfprintf(f, " JJ_JS_FS_END\n" > "};\n"); > } > > @@ -1491,7 +1512,7 @@ jsapi_out_func_spec(const struct hlcl *hlcl, struct jsapi_state *state, FILE * f > nat = hlcl->data.p.p; > assert(nat); > > - return sigfprintf(f, " JS_FS(\"%s\", %s, %ld, 0, %ld),\n", > + return sigfprintf(f, " JJ_JS_FS(\"%s\", %s, %ld, 0, %ld),\n", > nat->name, > nat->symbol, > nat->argtablen, > diff --git a/src/native.c b/src/native.c > index 9f9b6bd..6d0fb29 100644 > --- a/src/native.c > +++ b/src/native.c > @@ -45,6 +45,7 @@ native_init(struct native *nat) > nat->argtablen = 0; > nat->call = NULL; > nat->nroots = 0; > + nat->class = NULL; > > return 0; > } > diff --git a/src/native.h b/src/native.h > index 42c39ef..6352e39 100644 > --- a/src/native.h > +++ b/src/native.h > @@ -26,6 +26,7 @@ struct native > const char *call; > char *symbol; > unsigned long nroots; > + struct class *class; > }; > > int > diff --git a/src/symtabs.c b/src/symtabs.c > index 332d2ca..5051a2f 100644 > --- a/src/symtabs.c > +++ b/src/symtabs.c > @@ -1217,6 +1217,8 @@ symtabs_construct_leave(struct ast_node *node) > > class->construct = nat-jjnativetab; > > + nat->class = class; > + > return 0; > } Besides the mentioned points, there were several white-space errors and non-expanded tabs. Anyway, thanks again for the patch. Best regards, Thomas -- GnuPG: http://tdz.users.sourceforge.net/tdz.asc Fingerprint: 16FF F599 82F8 E5AA 18C6 5220 D9DA D7D4 4EF1 DF08 jsapigen - A free glue-code generator for Mozilla SpiderMonkey. See http://jsapigen.sourceforge.net for more information. |