From 6f54ba5f6a2008191c2bb3435f8015ae70bcf156 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 25 Nov 2012 19:14:02 +0000 Subject: generate and use tinyid enum for properties --- src/jsapi-libdom-property.c | 205 +++++++++++++++++++++++++++++++++++++++----- src/jsapi-libdom.c | 45 ++++++---- src/jsapi-libdom.h | 17 +++- 3 files changed, 228 insertions(+), 39 deletions(-) diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c index 4e67120..87cbc10 100644 --- a/src/jsapi-libdom-property.c +++ b/src/jsapi-libdom-property.c @@ -17,6 +17,7 @@ #include "webidl-ast.h" #include "jsapi-libdom.h" +static int generate_property_tinyid(struct binding *binding, const char *interface); static int generate_property_spec(struct binding *binding, const char *interface); static int generate_property_body(struct binding *binding, const char *interface); @@ -52,6 +53,17 @@ output_property_name_get_vars(struct binding *binding, const char *argname) argname, argname, argname, argname); } +/* generate vars for property tinyid getter */ +static inline int +output_property_tinyid_get_vars(struct binding *binding, const char *argname) +{ + /* get property name */ + return fprintf(binding->outfile, + "\tjsval %s_jsval;\n" + "\tint8_t %s = JSAPI_PROP_TINYID_END;\n", + argname, argname); +} + /* generate property name getter */ static inline int output_property_name_get(struct binding *binding, const char *argname) @@ -67,6 +79,135 @@ output_property_name_get(struct binding *binding, const char *argname) argname,argname,argname,argname,argname,argname,argname); } +/* generate property name getter */ +static inline int +output_property_tinyid_get(struct binding *binding, const char *argname) +{ + /* get property name */ + return fprintf(binding->outfile, + "\t /* obtain property tinyid */\n" + "\tJSAPI_PROP_IDVAL(cx, &%s_jsval);\n" + "\t%s = JSVAL_TO_INT(%s_jsval);\n\n", + argname, argname, argname); +} + + +/******************************** tinyid ********************************/ + +static int +webidl_property_tinyid_cb(struct webidl_node *node, void *ctx) +{ + struct binding *binding = ctx; + struct webidl_node *ident_node; + const char *ident; + + ident_node = webidl_node_find_type(webidl_node_getnode(node), + NULL, + WEBIDL_NODE_TYPE_IDENT); + ident = webidl_node_gettext(ident_node); + if (ident == NULL) { + /* properties must have an operator + * http://www.w3.org/TR/WebIDL/#idl-attributes + */ + return -1; + } + + fprintf(binding->outfile, "\tJSAPI_PROP_TINYID_%s,\n", ident); + + return 0; +} + +/* callback to emit implements property spec */ +static int +webidl_property_tinyid_implements_cb(struct webidl_node *node, void *ctx) +{ + struct binding *binding = ctx; + + return generate_property_tinyid(binding, webidl_node_gettext(node)); +} + +static int +generate_property_tinyid(struct binding *binding, const char *interface) +{ + struct webidl_node *interface_node; + struct webidl_node *members_node; + struct webidl_node *inherit_node; + int res = 0; + + /* find interface in webidl with correct ident attached */ + interface_node = webidl_node_find_type_ident(binding->wi_ast, + WEBIDL_NODE_TYPE_INTERFACE, + interface); + + if (interface_node == NULL) { + fprintf(stderr, + "Unable to find interface %s in loaded WebIDL\n", + interface); + return -1; + } + + /* generate property entries for each list (partial interfaces) */ + members_node = webidl_node_find_type(webidl_node_getnode(interface_node), + NULL, + WEBIDL_NODE_TYPE_LIST); + + while (members_node != NULL) { + + fprintf(binding->outfile,"\t/**** %s ****/\n", interface); + + /* for each property emit a JSAPI_PS() */ + webidl_node_for_each_type(webidl_node_getnode(members_node), + WEBIDL_NODE_TYPE_ATTRIBUTE, + webidl_property_tinyid_cb, + binding); + + members_node = webidl_node_find_type(webidl_node_getnode(interface_node), + members_node, + WEBIDL_NODE_TYPE_LIST); + } + + /* check for inherited nodes and insert them too */ + inherit_node = webidl_node_find(webidl_node_getnode(interface_node), + NULL, + webidl_cmp_node_type, + (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE); + + if (inherit_node != NULL) { + res = generate_property_tinyid(binding, webidl_node_gettext(inherit_node)); + } + + if (res == 0) { + res = webidl_node_for_each_type(webidl_node_getnode(interface_node), + WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, + webidl_property_tinyid_implements_cb, + binding); + } + + return res; +} + +/* exported interface documented in jsapi-libdom.h */ +int +output_property_tinyid(struct binding *binding) +{ + int res; + + fprintf(binding->outfile, + "enum property_tinyid {\n"); + + res = generate_property_tinyid(binding, binding->interface); + + fprintf(binding->outfile, + "\tJSAPI_PROP_TINYID_END,\n" + "};\n\n"); + + return res; +} + + + +/******************************** specifier ********************************/ + /* search binding for property sharing modifier */ static enum genbind_type_modifier @@ -141,9 +282,9 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) WEBIDL_NODE_TYPE_MODIFIER); if (webidl_node_getint(modifier_node) == WEBIDL_TYPE_READONLY) { - fprintf(binding->outfile, "\tJSAPI_PS_RO(\"%s\", ", ident); + fprintf(binding->outfile, "\tJSAPI_PS_RO(\"%s\",\n", ident); } else { - fprintf(binding->outfile, "\tJSAPI_PS(\"%s\", ", ident); + fprintf(binding->outfile, "\tJSAPI_PS(\"%s\",\n", ident); } /* generate property shared status */ @@ -156,34 +297,44 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) * js doesnt provide storage and setter/getter must * perform all GC management. */ - fprintf(binding->outfile, - "%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED", + fprintf(binding->outfile, + "\t\t%s,\n" + "\t\tJSAPI_PROP_TINYID_%s,\n" + "\t\tJSPROP_SHARED | ", + ident, ident); break; case GENBIND_TYPE_TYPE: /* shared property with a type handler */ - fprintf(binding->outfile, - "%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED", - type); + fprintf(binding->outfile, + "\t\t%s,\n" + "\t\tJSAPI_PROP_TINYID_%s,\n" + "\t\tJSPROP_SHARED | ", + type, + ident); break; case GENBIND_TYPE_UNSHARED: /* unshared property without type handler */ fprintf(binding->outfile, - "%s, 0, JSPROP_ENUMERATE", - ident); + "\t\t%s,\n" + "\t\tJSAPI_PROP_TINYID_%s,\n" + "\t\t", + ident, ident); break; case GENBIND_TYPE_TYPE_UNSHARED: /* unshared property with a type handler */ fprintf(binding->outfile, - "%s, 0, JSPROP_ENUMERATE", - type); + "\t\t%s,\n" + "\t\tJSAPI_PROP_TINYID_%s,\n" + "\t\t", + type, ident); break; } - fprintf(binding->outfile, "),\n"); + fprintf(binding->outfile, "JSPROP_ENUMERATE),\n"); return 0; } @@ -258,7 +409,9 @@ generate_property_spec(struct binding *binding, const char *interface) return res; } -/* generate property specifier structure */ + + +/* exported interface documented in jsapi-libdom.h */ int output_property_spec(struct binding *binding) { @@ -274,6 +427,10 @@ output_property_spec(struct binding *binding) return res; } + +/******************************** body ********************************/ + + static int output_return(struct binding *binding, const char *ident, struct webidl_node *node) @@ -733,21 +890,26 @@ generate_property_body(struct binding *binding, const char *interface) /* setter for type handler */ -static int output_property_type_setter(struct binding *binding, struct genbind_node *node, const char *type) +static int +output_property_type_setter(struct binding *binding, + struct genbind_node *node, + const char *type) { struct genbind_node *property_node; + node = node;/* currently unused */ fprintf(binding->outfile, - "static JSBool JSAPI_PROP_SETTER(%s, JSContext *cx, JSObject *obj, jsval *vp)\n" + "static JSBool\n" + "JSAPI_PROP_SETTER(%s, JSContext *cx, JSObject *obj, jsval *vp)\n" "{\n", type); /* property name vars */ - output_property_name_get_vars(binding, "propname"); + output_property_tinyid_get_vars(binding, "tinyid"); /* context data */ output_private_get(binding, "private"); /* property name */ - output_property_name_get(binding, "propname"); + output_property_tinyid_get(binding, "tinyid"); /* output binding code block */ property_node = genbind_node_find_type_ident(binding->gb_ast, @@ -772,18 +934,19 @@ static int output_property_type_setter(struct binding *binding, struct genbind_n static int output_property_type_getter(struct binding *binding, struct genbind_node *node, const char *type) { struct genbind_node *property_node; + node = node;/* currently unused */ fprintf(binding->outfile, "static JSBool JSAPI_PROP_GETTER(%s, JSContext *cx, JSObject *obj, jsval *vp)\n" "{\n", type); - /* property name vars */ - output_property_name_get_vars(binding, "propname"); + /* property tinyid vars */ + output_property_tinyid_get_vars(binding, "tinyid"); /* context data */ output_private_get(binding, "private"); - /* property name */ - output_property_name_get(binding, "propname"); + /* property tinyid */ + output_property_tinyid_get(binding, "tinyid"); /* output binding code block */ property_node = genbind_node_find_type_ident(binding->gb_ast, diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 0ac16e8..3e0bf08 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -414,24 +414,28 @@ output_class_new(struct binding *binding) static int output_jsclass(struct binding *binding) { + /* forward declare the resolver */ if (binding->resolve != NULL) { - /* forward declare the resolver */ fprintf(binding->outfile, "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n"); } + /* forward declare the GC mark operation */ if (binding->mark != NULL) { fprintf(binding->outfile, "static JSAPI_MARKOP(jsclass_mark);\n\n"); } + /* forward declare the finalizer */ if (binding->has_private || (binding->finalise != NULL)) { - - /* forward declare the finalizer */ fprintf(binding->outfile, "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n\n"); } + /* forward declare property list */ + fprintf(binding->outfile, + "static JSPropertySpec jsclass_properties[];\n\n"); + /* output the class */ fprintf(binding->outfile, "JSClass JSClass_%s = {\n" @@ -696,62 +700,73 @@ int jsapi_libdom_output(char *outfilename, struct genbind_node *genbind_ast) /* get general binding information used in output */ binding = binding_new(outfilename, genbind_ast); if (binding == NULL) { - return 4; + return 40; } res = output_header_comments(binding); if (res) { - return 5; + return 50; } res = output_preamble(binding); if (res) { - return 6; + return 60; } res = output_private_declaration(binding); if (res) { - return 7; + return 70; } res = output_jsclass(binding); if (res) { - return 8; + return 80; } + res = output_property_tinyid(binding); + if (res) { + return 85; + } + + /* operator and atrtribute body generation */ + res = output_operator_body(binding, binding->interface); if (res) { - return 9; + return 90; } res = output_property_body(binding); if (res) { - return 10; + return 100; } + /* operator and atrtribute specifier generation */ + res = output_function_spec(binding); if (res) { - return 11; + return 110; } res = output_property_spec(binding); if (res) { - return 12; + return 120; } + /* binding specific operations (destructors etc.) */ + res = output_api_operations(binding); if (res) { - return 13; + return 130; } res = output_class_init(binding); if (res) { - return 14; + return 140; } res = output_class_new(binding); if (res) { - return 15; + return 150; } fclose(binding->outfile); diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index 86214f4..8af39b2 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -27,9 +27,15 @@ struct binding { FILE *outfile ; /* output file */ }; +/** Generate binding between jsapi and netsurf libdom */ +int jsapi_libdom_output(char *outfile, struct genbind_node *genbind_root); + /** output code block from a node */ void output_code_block(struct binding *binding, struct genbind_node *codelist); +/* Generate jsapi native function specifiers */ +int output_function_spec(struct binding *binding); + /* Generate jsapi native function bodys * * web IDL describes methods as operators @@ -46,15 +52,20 @@ void output_code_block(struct binding *binding, struct genbind_node *codelist); * @param interface The interface to generate operator bodys for */ int output_operator_body(struct binding *binding, const char *interface); -int output_function_spec(struct binding *binding); + +/** generate property tinyid enum */ +int output_property_tinyid(struct binding *binding); + +/** generate property specifier structure */ int output_property_spec(struct binding *binding); + +/** generate property function bodies */ int output_property_body(struct binding *binding); +/** generate property definitions for constants */ int output_const_defines(struct binding *binding, const char *interface); -/** Generate binding between jsapi and netsurf libdom */ -int jsapi_libdom_output(char *outfile, struct genbind_node *genbind_root); -- cgit v1.2.3