From 4a75f7ee606deeffd9a89d82983bf6e9edb8f27b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 2 Feb 2014 22:59:04 +0000 Subject: make function specifier and body generation use the interface map --- src/jsapi-libdom-function.c | 252 +++++++++++++++++--------------------------- src/jsapi-libdom-infmap.c | 13 ++- src/jsapi-libdom.h | 50 ++++++--- 3 files changed, 140 insertions(+), 175 deletions(-) diff --git a/src/jsapi-libdom-function.c b/src/jsapi-libdom-function.c index 5540b0e..af9c215 100644 --- a/src/jsapi-libdom-function.c +++ b/src/jsapi-libdom-function.c @@ -17,101 +17,85 @@ #include "webidl-ast.h" #include "jsapi-libdom.h" -static int output_function_body(struct binding *binding, struct webidl_node *node); - -static int webidl_func_spec_cb(struct webidl_node *node, void *ctx) +static int webidl_operator_spec(struct binding *binding, + struct binding_interface *inf, + struct webidl_node *node) { - struct binding *binding = ctx; struct webidl_node *ident_node; - ident_node = webidl_node_find(webidl_node_getnode(node), - NULL, - webidl_cmp_node_type, - (void *)WEBIDL_NODE_TYPE_IDENT); - + ident_node = webidl_node_find_type(webidl_node_getnode(node), + NULL, + WEBIDL_NODE_TYPE_IDENT); if (ident_node == NULL) { /* operation without identifier - must have special keyword * http://www.w3.org/TR/WebIDL/#idl-operations */ } else { fprintf(binding->outfile, - "\tJSAPI_FS(%s, 0, JSPROP_ENUMERATE ),\n", + "\tJSAPI_FS(%s, %s, 0, JSPROP_ENUMERATE ),\n", + inf->name, webidl_node_gettext(ident_node)); /* @todo number of args to that FN_FS() call should be correct */ } return 0; } - -static int generate_function_spec(struct binding *binding, const char *interface); - - -static int -generate_function_spec(struct binding *binding, const char *interface) +int output_function_spec(struct binding *binding) { - 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; - } - - members_node = webidl_node_find(webidl_node_getnode(interface_node), - NULL, - webidl_cmp_node_type, - (void *)WEBIDL_NODE_TYPE_LIST); - while (members_node != NULL) { - - fprintf(binding->outfile,"\t/**** %s ****/\n", interface); - - /* for each function emit a JSAPI_FS()*/ - webidl_node_for_each_type(webidl_node_getnode(members_node), - WEBIDL_NODE_TYPE_OPERATION, - webidl_func_spec_cb, - binding); - - members_node = webidl_node_find(webidl_node_getnode(interface_node), - members_node, - webidl_cmp_node_type, - (void *)WEBIDL_NODE_TYPE_LIST); - } + int inf; + int res; + struct webidl_node *list_node; + struct webidl_node *op_node; /* operation on list node */ - /* 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); + /* generate functions for each interface in the map */ + for (inf = 0; inf < binding->interfacec; inf++) { + if (binding->interfaces[inf].own_functions == 0) { + continue; + } - if (inherit_node != NULL) { - res = generate_function_spec(binding, - webidl_node_gettext(inherit_node)); - } + fprintf(binding->outfile, + "static JSFunctionSpec JSClass_%s_functions[] = {\n", + binding->interfaces[inf].name); - return res; -} + /* iterate each list within an interface */ + list_node = webidl_node_find_type( + webidl_node_getnode(binding->interfaces[inf].widl_node), + NULL, + WEBIDL_NODE_TYPE_LIST); -int output_function_spec(struct binding *binding) -{ - int res; + while (list_node != NULL) { + /* iterate through operations in a list */ + op_node = webidl_node_find_type( + webidl_node_getnode(list_node), + NULL, + WEBIDL_NODE_TYPE_OPERATION); + + while (op_node != NULL) { + res = webidl_operator_spec( + binding, + &binding->interfaces[inf], + op_node); + if (res != 0) { + return res; + } + + op_node = webidl_node_find_type( + webidl_node_getnode(list_node), + op_node, + WEBIDL_NODE_TYPE_OPERATION); + } - fprintf(binding->outfile, - "static JSFunctionSpec jsclass_functions[] = {\n"); - res = generate_function_spec(binding, binding->interface); + list_node = webidl_node_find_type( + webidl_node_getnode(binding->interfaces[inf].widl_node), + list_node, + WEBIDL_NODE_TYPE_LIST); + } - fprintf(binding->outfile, "\tJSAPI_FS_END\n};\n\n"); + fprintf(binding->outfile, "\tJSAPI_FS_END\n};\n\n"); - return res; + } + return 0; } static int output_return(struct binding *binding, @@ -736,10 +720,10 @@ output_private_get(struct binding *binding, const char *argname) return ret; } -static int -webidl_operator_body_cb(struct webidl_node *node, void *ctx) +static int webidl_operator_body(struct binding *binding, + struct binding_interface *inf, + struct webidl_node *node) { - struct binding *binding = ctx; struct webidl_node *ident_node; struct genbind_node *operation_node; @@ -761,9 +745,10 @@ webidl_operator_body_cb(struct webidl_node *node, void *ctx) /* normal operation with identifier */ fprintf(binding->outfile, - "static JSBool JSAPI_FUNC(%s, JSContext *cx, uintN argc, jsval *vp)\n", + "static JSBool JSAPI_FUNC(%s, %s, JSContext *cx, uintN argc, jsval *vp)\n" + "{\n", + inf->name, webidl_node_gettext(ident_node)); - fprintf(binding->outfile, "{\n"); /* return value declaration */ output_return_declaration(binding, "jsret", webidl_node_getnode(node)); @@ -797,90 +782,51 @@ webidl_operator_body_cb(struct webidl_node *node, void *ctx) return 0; } -static int -output_interface_functions(struct binding *binding, - struct webidl_node *interface_node) -{ - struct webidl_node *members_node; - - members_node = webidl_node_find_type( - webidl_node_getnode(interface_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (members_node != NULL) { - /* for each function emit a JSAPI_FS()*/ - webidl_node_for_each_type(webidl_node_getnode(members_node), - WEBIDL_NODE_TYPE_OPERATION, - webidl_operator_body_cb, - binding); - - members_node = webidl_node_find_type( - webidl_node_getnode(interface_node), - members_node, - WEBIDL_NODE_TYPE_LIST); - } - return 0; -} - -/* callback to emit implements operator bodys */ -static int webidl_implements_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct webidl_node *interface_node; - - interface_node = webidl_node_find_type_ident(binding->wi_ast, - WEBIDL_NODE_TYPE_INTERFACE, - webidl_node_gettext(node)); - - return output_function_body(binding, interface_node); -} /* exported interface documented in jsapi-libdom.h */ -static int -output_function_body(struct binding *binding, - struct webidl_node *interface_node) +int output_function_bodies(struct binding *binding) { - struct webidl_node *inherit_node; - int res = 0; - - res = output_interface_functions(binding, interface_node); + int inf; + int res; + struct webidl_node *list_node; + struct webidl_node *op_node; /* operation on list node */ + + /* generate functions for each interface in the map */ + for (inf = 0; inf < binding->interfacec; inf++) { + /* iterate each list within an interface */ + list_node = webidl_node_find_type( + webidl_node_getnode(binding->interfaces[inf].widl_node), + NULL, + WEBIDL_NODE_TYPE_LIST); - fprintf(binding->outfile, - "/**** %s ****/\n", - webidl_node_gettext( - webidl_node_find_type( - webidl_node_getnode(interface_node), + while (list_node != NULL) { + /* iterate through operations in a list */ + op_node = webidl_node_find_type( + webidl_node_getnode(list_node), NULL, - WEBIDL_NODE_TYPE_IDENT))); - - /* check for inherited nodes and insert them too */ - inherit_node = webidl_node_find_type( - webidl_node_getnode(interface_node), - NULL, - WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE); - - if (inherit_node != NULL) { - res = webidl_implements_cb(inherit_node, binding); - } + WEBIDL_NODE_TYPE_OPERATION); + + while (op_node != NULL) { + res = webidl_operator_body( + binding, + &binding->interfaces[inf], + op_node); + if (res != 0) { + return res; + } + + op_node = webidl_node_find_type( + webidl_node_getnode(list_node), + op_node, + WEBIDL_NODE_TYPE_OPERATION); + } - return res; -} -int -output_function_bodies(struct binding *binding) -{ - int inf; - int res = 0; - - for (inf=0; inf < binding->interfacec; inf++) { - if (binding->interfaces[inf].inherit_idx == -1) { - res = output_function_body(binding, - binding->interfaces[inf].widl_node); - } else { - res = output_interface_functions(binding, - binding->interfaces[inf].widl_node); + list_node = webidl_node_find_type( + webidl_node_getnode(binding->interfaces[inf].widl_node), + list_node, + WEBIDL_NODE_TYPE_LIST); } } - return res; + return 0; } diff --git a/src/jsapi-libdom-infmap.c b/src/jsapi-libdom-infmap.c index d0ffbd8..09fce1e 100644 --- a/src/jsapi-libdom-infmap.c +++ b/src/jsapi-libdom-infmap.c @@ -159,12 +159,11 @@ interface_topoligical_sort(struct binding_interface *srcinf, int infc) return dstinf; } -/* build interface map and return the first interface */ -int -build_interface_map(struct genbind_node *binding_node, - struct webidl_node *webidl_ast, - int *interfacec_out, - struct binding_interface **interfaces_out) +/* exported interface documented in jsapi-libdom.h */ +int build_interface_map(struct genbind_node *binding_node, + struct webidl_node *webidl_ast, + int *interfacec_out, + struct binding_interface **interfaces_out) { int interfacec; int inf; /* interface loop counter */ @@ -263,7 +262,7 @@ build_interface_map(struct genbind_node *binding_node, } interfaces = reinterfaces; - /* setup all fileds in new interface */ + /* setup all fields in new interface */ /* this interface is not in the binding and * will not be exported diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index cf27318..2925866 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -12,16 +12,22 @@ struct options; struct binding_interface { - const char *name; /* name of interface */ - struct genbind_node *node; /* node of interface in binding */ - struct webidl_node *widl_node; /* node of interface in webidl */ - const char *inherit_name; /* name of interface this inherits from */ - int own_properties; /* the number of properties the interface has */ - int own_functions; /* the number of functions the interface has */ - - int inherit_idx; /* index into binding map of inherited interface or -1 for not in map */ - int refcount; /* number of entries in map that refer to this interface */ - int output_idx; /* for interfaces that will be output (node is valid) this is the output array index */ + const char *name; /**< name of interface */ + struct genbind_node *node; /**< node of interface in binding */ + struct webidl_node *widl_node; /**< node of interface in webidl */ + const char *inherit_name; /**< name of interface this inherits from */ + int own_properties; /**< the number of properties the interface has */ + int own_functions; /**< the number of functions the interface has */ + + int inherit_idx; /**< index into binding map of inherited + * interface or -1 for not in map + */ + int refcount; /**< number of entries in map that refer to this + * interface + */ + int output_idx; /**< for interfaces that will be output (node + * is valid) this is the output array index + */ }; struct binding { @@ -59,11 +65,24 @@ struct binding { /** Generate binding between jsapi and netsurf libdom */ int jsapi_libdom_output(struct options *options, struct genbind_node *genbind_ast, struct genbind_node *binding_node); -/** build interface mapping */ +/** Build interface map. + * + * Generate a map of all interfaces referenced from a binding and + * their relationships to each other. + * + * The map will contain all the interfaces both directly referenced by + * the binding and all those inherited through the WebIDL. + * + * The map is topoligicaly sorted to ensure no forward inheritance + * references. + * + * The map contains an monotinicaly incrementing index for all + * interfaces referenced in the binding (i.e. those to be exported). + */ int build_interface_map(struct genbind_node *binding_node, - struct webidl_node *webidl_ast, - int *interfacec_out, - struct binding_interface **interfaces_out); + struct webidl_node *webidl_ast, + int *interfacec_out, + struct binding_interface **interfaces_out); /** output code block from a node */ @@ -75,7 +94,8 @@ int output_jsclasses(struct binding *binding); /* Generate jsapi native function specifiers */ int output_function_spec(struct binding *binding); -/* Generate jsapi native function bodys +/** + * Generate jsapi native function bodies. * * web IDL describes methods as operators * http://www.w3.org/TR/WebIDL/#idl-operations -- cgit v1.2.1