From 19f0eb49df62e8094d6c8fcd5f8d7522b07ec3d3 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 20 Nov 2012 17:52:21 +0000 Subject: implement unshared output in property specifier --- src/jsapi-libdom-property.c | 111 +++++++++++++++++++++++++++++++------------- src/jsapi-libdom.h | 4 +- src/nsgenbind-ast.c | 33 ++++++++++++- src/nsgenbind-ast.h | 39 ++++++++++++++-- src/webidl-ast.c | 18 ++++--- 5 files changed, 159 insertions(+), 46 deletions(-) diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c index d96228a..9fbd281 100644 --- a/src/jsapi-libdom-property.c +++ b/src/jsapi-libdom-property.c @@ -21,36 +21,83 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) { struct binding *binding = ctx; + struct genbind_node *binding_node; + struct genbind_node *unshared_node; + struct webidl_node *type_node; struct webidl_node *ident_node; + const char *ident; struct webidl_node *modifier_node; - ident_node = webidl_node_find(webidl_node_getnode(node), - NULL, - webidl_cmp_node_type, - (void *)WEBIDL_NODE_TYPE_IDENT); - - modifier_node = webidl_node_find(webidl_node_getnode(node), - NULL, - webidl_cmp_node_type, - (void *)WEBIDL_NODE_TYPE_MODIFIER); + binding_node = genbind_node_find_type(binding->gb_ast, + NULL, + GENBIND_NODE_TYPE_BINDING); + if (binding_node == NULL) { + return -1; + } + ident_node = webidl_node_find_type(webidl_node_getnode(node), + NULL, + WEBIDL_NODE_TYPE_IDENT); if (ident_node == NULL) { /* properties must have an operator * http://www.w3.org/TR/WebIDL/#idl-attributes */ - return 1; + return -1; } - + ident = webidl_node_gettext(ident_node); + + modifier_node = webidl_node_find_type(webidl_node_getnode(node), + NULL, + WEBIDL_NODE_TYPE_MODIFIER); + if (webidl_node_getint(modifier_node) == WEBIDL_TYPE_READONLY) { - fprintf(binding->outfile, - "\tJSAPI_PS_RO(%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED),\n", - webidl_node_gettext(ident_node)); + fprintf(binding->outfile, "\tJSAPI_PS_RO("); } else { - fprintf(binding->outfile, - "\tJSAPI_PS(%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED),\n", - webidl_node_gettext(ident_node)); + fprintf(binding->outfile, "\tJSAPI_PS("); + } + + unshared_node = genbind_node_find_type_ident(genbind_node_getnode(binding_node), + NULL, + GENBIND_NODE_TYPE_BINDING_UNSHARED, + ident); + + if (unshared_node != NULL) { + /* not a shared property */ + fprintf(binding->outfile, "%s, 0, JSPROP_ENUMERATE", ident); + } else { + /* examine if the property is of a unshared type */ + type_node = webidl_node_find_type(webidl_node_getnode(node), + NULL, + WEBIDL_NODE_TYPE_TYPE); + + ident_node = webidl_node_find_type(webidl_node_getnode(type_node), + NULL, + WEBIDL_NODE_TYPE_IDENT); + + if (ident_node != NULL) { + unshared_node = genbind_node_find_type_type(genbind_node_getnode(binding_node), + NULL, + GENBIND_NODE_TYPE_BINDING_UNSHARED, + webidl_node_gettext(ident_node)); + } + + if (unshared_node != NULL) { + /* property is not shared because of its type */ + fprintf(binding->outfile, + "%s, 0, JSPROP_ENUMERATE", + webidl_node_gettext(ident_node)); + } else { + /* property is shared + * js doesnt provide storage and setter/getter must + * perform all GC management. + */ + fprintf(binding->outfile, + "%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED", + ident); + } } - + fprintf(binding->outfile, "),\n"); + return 0; } @@ -303,14 +350,14 @@ static int output_return_declaration(struct binding *binding, type_mod = webidl_node_find_type(webidl_node_getnode(type_node), NULL, WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && + if ((type_mod != NULL) && (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, - "\tuint16_t %s = 0;\n", + fprintf(binding->outfile, + "\tuint16_t %s = 0;\n", ident); } else { - fprintf(binding->outfile, - "\tint16_t %s = 0;\n", + fprintf(binding->outfile, + "\tint16_t %s = 0;\n", ident); } @@ -325,14 +372,14 @@ static int output_return_declaration(struct binding *binding, type_mod = webidl_node_find_type(webidl_node_getnode(type_node), NULL, WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && + if ((type_mod != NULL) && (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, - "\tuint32_t %s = 0;\n", + fprintf(binding->outfile, + "\tuint32_t %s = 0;\n", ident); } else { - fprintf(binding->outfile, - "\tint32_t %s = 0;\n", + fprintf(binding->outfile, + "\tint32_t %s = 0;\n", ident); } @@ -368,14 +415,14 @@ static int output_return_declaration(struct binding *binding, return 0; } -static int -output_property_placeholder(struct binding *binding, - struct webidl_node* oplist, +static int +output_property_placeholder(struct binding *binding, + struct webidl_node* oplist, const char *ident) { oplist=oplist; - WARN(WARNING_UNIMPLEMENTED, + WARN(WARNING_UNIMPLEMENTED, "property %s.%s has no implementation\n", binding->interface, ident); diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index cb9f40d..8d005c8 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -10,8 +10,8 @@ #define nsgenbind_jsapi_libdom_h struct binding { - struct genbind_node *gb_ast; - struct webidl_node *wi_ast; + struct genbind_node *gb_ast; /* root node of binding AST */ + struct webidl_node *wi_ast; /* root node of webidl AST */ const char *name; /* name of the binding */ const char *interface; /* webidl interface binding is for */ diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c index 09ce8ce..a8a8361 100644 --- a/src/nsgenbind-ast.c +++ b/src/nsgenbind-ast.c @@ -118,7 +118,7 @@ genbind_node_find(struct genbind_node *node, return NULL; } -/* exported interface defined in nsgenbind-ast.h */ +/* exported interface documented in nsgenbind-ast.h */ struct genbind_node * genbind_node_find_type(struct genbind_node *node, struct genbind_node *prev, @@ -130,6 +130,7 @@ genbind_node_find_type(struct genbind_node *node, (void *)type); } +/* exported interface documented in nsgenbind-ast.h */ struct genbind_node * genbind_node_find_type_ident(struct genbind_node *node, struct genbind_node *prev, @@ -143,7 +144,7 @@ genbind_node_find_type_ident(struct genbind_node *node, while (found_node != NULL) { - + /* look for an ident node */ ident_node = genbind_node_find_type(genbind_node_getnode(found_node), NULL, GENBIND_NODE_TYPE_IDENT); @@ -154,7 +155,35 @@ genbind_node_find_type_ident(struct genbind_node *node, /* look for next matching node */ found_node = genbind_node_find_type(node, found_node, type); + } + return found_node; +} + +/* exported interface documented in nsgenbind-ast.h */ +struct genbind_node * +genbind_node_find_type_type(struct genbind_node *node, + struct genbind_node *prev, + enum genbind_node_type type, + const char *ident) +{ + struct genbind_node *found_node; + struct genbind_node *ident_node; + found_node = genbind_node_find_type(node, prev, type); + + + while (found_node != NULL) { + /* look for a type node */ + ident_node = genbind_node_find_type(genbind_node_getnode(found_node), + NULL, + GENBIND_NODE_TYPE_TYPE); + if (ident_node != NULL) { + if (strcmp(ident_node->r.text, ident) == 0) + break; + } + + /* look for next matching node */ + found_node = genbind_node_find_type(node, found_node, type); } return found_node; } diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h index 5ae21b4..544582c 100644 --- a/src/nsgenbind-ast.h +++ b/src/nsgenbind-ast.h @@ -52,7 +52,6 @@ int genbind_ast_dump(struct genbind_node *ast, int indent); /** Depth first left hand search using user provided comparison * * @param node The node to start the search from - * @param prev The node at which to stop the search, either NULL to * search the full tree depth (initial search) or the result * of a previous search to continue. @@ -65,17 +64,51 @@ genbind_node_find(struct genbind_node *node, genbind_callback_t *cb, void *ctx); +/** Depth first left hand search returning nodes of the specified type + * + * @param node The node to start the search from + * @param prev The node at which to stop the search, either NULL to + * search the full tree depth (initial search) or the result + * of a previous search to continue. + * @param nodetype The type of node to seach for + */ struct genbind_node * genbind_node_find_type(struct genbind_node *node, struct genbind_node *prev, - enum genbind_node_type type); + enum genbind_node_type nodetype); +/** Depth first left hand search returning nodes of the specified type + * and a ident child node with matching text + * + * @param node The node to start the search from + * @param prev The node at which to stop the search, either NULL to + * search the full tree depth (initial search) or the result + * of a previous search to continue. + * @param nodetype The type of node to seach for + * @param ident The text to match the ident child node to + */ struct genbind_node * genbind_node_find_type_ident(struct genbind_node *node, struct genbind_node *prev, - enum genbind_node_type type, + enum genbind_node_type nodetype, const char *ident); +/** Depth first left hand search returning nodes of the specified type + * and a type child node with matching text + * + * @param node The node to start the search from + * @param prev The node at which to stop the search, either NULL to + * search the full tree depth (initial search) or the result + * of a previous search to continue. + * @param nodetype The type of node to seach for + * @param type The text to match the type child node to + */ +struct genbind_node * +genbind_node_find_type_type(struct genbind_node *node, + struct genbind_node *prev, + enum genbind_node_type nodetype, + const char *type); + int genbind_node_for_each_type(struct genbind_node *node, enum genbind_node_type type, genbind_callback_t *cb, void *ctx); char *genbind_node_gettext(struct genbind_node *node); diff --git a/src/webidl-ast.c b/src/webidl-ast.c index bc4ab01..ba9d44f 100644 --- a/src/webidl-ast.c +++ b/src/webidl-ast.c @@ -214,15 +214,19 @@ webidl_node_find_type_ident(struct webidl_node *root_node, char *webidl_node_gettext(struct webidl_node *node) { - switch(node->type) { - case WEBIDL_NODE_TYPE_IDENT: - case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE: - case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS: - return node->r.text; + if (node != NULL) { - default: - return NULL; + switch(node->type) { + case WEBIDL_NODE_TYPE_IDENT: + case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE: + case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS: + return node->r.text; + + default: + break; + } } + return NULL; } int -- cgit v1.2.3