From 93c89193c1f2a29b00741d1494f262642108abe2 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 21 Nov 2012 15:21:42 +0000 Subject: make property shared status and type handling selection generic --- src/jsapi-libdom-property.c | 181 +++++++++++++++++++++++++++--------------- src/nsgenbind-ast.c | 26 +++++- src/nsgenbind-ast.h | 16 +++- src/nsgenbind-lexer.l | 2 + src/nsgenbind-parser.y | 54 ++++++++++--- src/webidl-parser.y | 8 +- test/data/bindings/window.bnd | 4 +- 7 files changed, 204 insertions(+), 87 deletions(-) diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c index 866d8e6..5502030 100644 --- a/src/jsapi-libdom-property.c +++ b/src/jsapi-libdom-property.c @@ -21,11 +21,47 @@ static int generate_property_spec(struct binding *binding, const char *interface static int generate_property_body(struct binding *binding, const char *interface); +/* search binding for property sharing modifier */ +static enum genbind_type_modifier +get_binding_shared_modifier(struct binding *binding, const char *type, const char *ident) +{ + struct genbind_node *shared_node; + struct genbind_node *shared_mod_node; + + /* look for node matching the ident first */ + shared_node = genbind_node_find_type_ident(binding->binding_list, + NULL, + GENBIND_NODE_TYPE_BINDING_SHARED, + ident); + + /* look for a node matching the type */ + if (shared_node == NULL) { + shared_node = genbind_node_find_type_ident(binding->binding_list, + NULL, + GENBIND_NODE_TYPE_BINDING_SHARED, + type); + + } + + + if (shared_node != NULL) { + /* no explicit shared status */ + shared_mod_node = genbind_node_find_type(genbind_node_getnode(shared_node), + NULL, + GENBIND_NODE_TYPE_MODIFIER); + if (shared_mod_node != NULL) { + return genbind_node_getint(shared_mod_node); + } + } + return GENBIND_TYPE_NONE; +} + static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) { struct binding *binding = ctx; - struct genbind_node *unshared_node; + struct webidl_node *type_node; + const char *type = NULL; struct webidl_node *ident_node; const char *ident; struct webidl_node *modifier_node; @@ -41,6 +77,18 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) return -1; } + + /* get type name */ + 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); + type = webidl_node_gettext(ident_node); + + + /* generate JSAPI_PS macro entry */ modifier_node = webidl_node_find_type(webidl_node_getnode(node), NULL, WEBIDL_NODE_TYPE_MODIFIER); @@ -51,45 +99,42 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx) fprintf(binding->outfile, "\tJSAPI_PS(\"%s\", ", ident); } - unshared_node = genbind_node_find_type_ident(binding->binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_UNSHARED, - ident); + /* generate property shared status */ + switch (get_binding_shared_modifier(binding, type, 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); + default: + case GENBIND_TYPE_NONE: + /* shared property without type handler + * + * js doesnt provide storage and setter/getter must + * perform all GC management. + */ + fprintf(binding->outfile, + "%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED", + ident); + break; - ident_node = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); + case GENBIND_TYPE_TYPE: + /* shared property with a type handler */ + fprintf(binding->outfile, + "%s, 0, JSPROP_ENUMERATE | JSPROP_SHARED", + type); + break; - if (ident_node != NULL) { - unshared_node = genbind_node_find_type_type(binding->binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_UNSHARED, - webidl_node_gettext(ident_node)); - } + case GENBIND_TYPE_UNSHARED: + /* unshared property without type handler */ + fprintf(binding->outfile, + "%s, 0, JSPROP_ENUMERATE", + ident); + break; + + case GENBIND_TYPE_TYPE_UNSHARED: + /* unshared property with a type handler */ + fprintf(binding->outfile, + "%s, 0, JSPROP_ENUMERATE", + type); + break; - 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"); @@ -538,7 +583,9 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx) struct webidl_node *ident_node; const char *ident; struct webidl_node *type_node; + const char *type = NULL; int ret; + enum genbind_type_modifier shared_mod; ident_node = webidl_node_find_type(webidl_node_getnode(node), NULL, @@ -551,31 +598,28 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx) return -1; } - /* do not generate individual getters/setters for an unshared type */ + /* get type name */ 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) { - struct genbind_node *unshared_node; - unshared_node = genbind_node_find_type_type(binding->binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_UNSHARED, - webidl_node_gettext(ident_node)); - if (unshared_node != NULL) { - return 0; + type = webidl_node_gettext(ident_node); + + /* find shared modifiers */ + shared_mod = get_binding_shared_modifier(binding, type, ident); + + /* only generate individual getters/setters if there is not a + * type handler + */ + if ((shared_mod & GENBIND_TYPE_TYPE) == 0) { + ret = output_property_setter(binding, node, ident); + if (ret == 0) { + /* property getter */ + ret = output_property_getter(binding, node, ident); } } - - ret = output_property_setter(binding, node, ident); - if (ret == 0) { - /* property getter */ - ret = output_property_getter(binding, node, ident); - } return ret; } @@ -652,21 +696,30 @@ generate_property_body(struct binding *binding, const char *interface) return res; } - - -int unshared_property_cb(struct genbind_node *node, void *ctx) +/* callback to emit property handlers for whole types */ +static int typehandler_property_cb(struct genbind_node *node, void *ctx) { struct binding *binding = ctx; - struct genbind_node *type_node; + struct genbind_node *ident_node; struct genbind_node *property_node; const char *type; + struct genbind_node *mod_node; + enum genbind_type_modifier share_mod; + + mod_node = genbind_node_find_type(genbind_node_getnode(node), + NULL, + GENBIND_NODE_TYPE_MODIFIER); + share_mod = genbind_node_getint(mod_node); + if ((share_mod & GENBIND_TYPE_TYPE) != GENBIND_TYPE_TYPE) { + /* not a type handler */ + return 0; + } - /* only need to generate property body for unshared types */ - type_node = genbind_node_find_type(genbind_node_getnode(node), + ident_node = genbind_node_find_type(genbind_node_getnode(node), NULL, - GENBIND_NODE_TYPE_TYPE); - type = genbind_node_gettext(type_node); - if (type== NULL) { + GENBIND_NODE_TYPE_IDENT); + type = genbind_node_gettext(ident_node); + if (type == NULL) { return 0; } @@ -726,8 +779,8 @@ output_property_body(struct binding *binding) if (res == 0) { res = genbind_node_for_each_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_UNSHARED, - unshared_property_cb, + GENBIND_NODE_TYPE_BINDING_SHARED, + typehandler_property_cb, binding); } diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c index df6c608..fba7dcb 100644 --- a/src/nsgenbind-ast.c +++ b/src/nsgenbind-ast.c @@ -32,6 +32,7 @@ struct genbind_node { void *value; struct genbind_node *node; char *text; + int number; /* node data is an integer */ } r; }; @@ -140,6 +141,10 @@ genbind_node_find_type_ident(struct genbind_node *node, struct genbind_node *found_node; struct genbind_node *ident_node; + if (ident == NULL) { + return NULL; + } + found_node = genbind_node_find_type(node, prev, type); @@ -223,7 +228,7 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node) case GENBIND_NODE_TYPE_BINDING: case GENBIND_NODE_TYPE_BINDING_PRIVATE: case GENBIND_NODE_TYPE_BINDING_INTERNAL: - case GENBIND_NODE_TYPE_BINDING_UNSHARED: + case GENBIND_NODE_TYPE_BINDING_SHARED: case GENBIND_NODE_TYPE_OPERATION: case GENBIND_NODE_TYPE_API: case GENBIND_NODE_TYPE_GETTER: @@ -238,6 +243,21 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node) } +int genbind_node_getint(struct genbind_node *node) +{ + if (node != NULL) { + switch(node->type) { + case GENBIND_NODE_TYPE_MODIFIER: + return node->r.number; + + default: + break; + } + } + return -1; + +} + static const char *genbind_node_type_to_str(enum genbind_node_type type) { switch(type) { @@ -274,8 +294,8 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type) case GENBIND_NODE_TYPE_BINDING_INTERFACE: return "Interface"; - case GENBIND_NODE_TYPE_BINDING_UNSHARED: - return "Unshared"; + case GENBIND_NODE_TYPE_BINDING_SHARED: + return "Shared"; case GENBIND_NODE_TYPE_OPERATION: return "Operation"; diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h index 544582c..cddf608 100644 --- a/src/nsgenbind-ast.h +++ b/src/nsgenbind-ast.h @@ -11,8 +11,9 @@ enum genbind_node_type { GENBIND_NODE_TYPE_ROOT = 0, - GENBIND_NODE_TYPE_IDENT, /* generic identifier string */ - GENBIND_NODE_TYPE_TYPE, /* generic type string */ + GENBIND_NODE_TYPE_IDENT, /**< generic identifier string */ + GENBIND_NODE_TYPE_TYPE, /**< generic type string */ + GENBIND_NODE_TYPE_MODIFIER, /**< node modifier */ GENBIND_NODE_TYPE_CBLOCK, GENBIND_NODE_TYPE_WEBIDLFILE, @@ -23,13 +24,21 @@ enum genbind_node_type { GENBIND_NODE_TYPE_BINDING_PRIVATE, GENBIND_NODE_TYPE_BINDING_INTERNAL, GENBIND_NODE_TYPE_BINDING_INTERFACE, - GENBIND_NODE_TYPE_BINDING_UNSHARED, + GENBIND_NODE_TYPE_BINDING_SHARED, GENBIND_NODE_TYPE_API, GENBIND_NODE_TYPE_OPERATION, GENBIND_NODE_TYPE_GETTER, GENBIND_NODE_TYPE_SETTER, }; +/* modifier flags */ +enum genbind_type_modifier { + GENBIND_TYPE_NONE = 0, + GENBIND_TYPE_TYPE = 1, /**< identifies a type handler */ + GENBIND_TYPE_UNSHARED = 2, /**< unshared item */ + GENBIND_TYPE_TYPE_UNSHARED = 3, /**< identifies a unshared type handler */ +}; + struct genbind_node; @@ -113,5 +122,6 @@ int genbind_node_for_each_type(struct genbind_node *node, enum genbind_node_type char *genbind_node_gettext(struct genbind_node *node); struct genbind_node *genbind_node_getnode(struct genbind_node *node); +int genbind_node_getint(struct genbind_node *node); #endif diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l index aea68ee..313d37b 100644 --- a/src/nsgenbind-lexer.l +++ b/src/nsgenbind-lexer.l @@ -98,6 +98,8 @@ internal return TOK_INTERNAL; unshared return TOK_UNSHARED; +shared return TOK_SHARED; + operation return TOK_OPERATION; api return TOK_API; diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y index 6364bf7..b104f2f 100644 --- a/src/nsgenbind-parser.y +++ b/src/nsgenbind-parser.y @@ -34,8 +34,9 @@ char *errtxt; %union { - char* text; - struct genbind_node *node; + char* text; + struct genbind_node *node; + int number; } %token TOK_IDLFILE @@ -52,6 +53,7 @@ char *errtxt; %token TOK_PRIVATE %token TOK_INTERNAL %token TOK_UNSHARED +%token TOK_SHARED %token TOK_IDENTIFIER %token TOK_STRING_LITERAL @@ -59,6 +61,9 @@ char *errtxt; %type CBlock +%type Modifiers +%type Modifier + %type Statement %type Statements %type IdlFile @@ -72,12 +77,13 @@ char *errtxt; %type Private %type Internal %type Interface -%type Unshared +%type Shared %type Operation %type Api %type Getter %type Setter + %% Input @@ -255,7 +261,7 @@ BindingArg | Interface | - Unshared + Shared ; Type @@ -294,18 +300,44 @@ Interface } ; -Unshared +Shared : - TOK_UNSHARED TOK_TYPE TOK_IDENTIFIER ';' + TOK_SHARED Modifiers TOK_IDENTIFIER ';' { - $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_UNSHARED, NULL, - genbind_new_node(GENBIND_NODE_TYPE_TYPE, NULL, $3)); + $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_SHARED, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_MODIFIER, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, + NULL, + $3), + (void *)$2)); + } + ; + +Modifiers + : + /* empty */ + { + $$ = 0; } | - TOK_UNSHARED TOK_IDENTIFIER ';' + Modifiers Modifier { - $$ = genbind_new_node(GENBIND_NODE_TYPE_BINDING_UNSHARED, NULL, - genbind_new_node(GENBIND_NODE_TYPE_IDENT, NULL, $2)); + $$ |= $2; } ; + +Modifier + : + TOK_TYPE + { + $$ = GENBIND_TYPE_TYPE; + } + | + TOK_UNSHARED + { + $$ = GENBIND_TYPE_UNSHARED; + } + ; + %% diff --git a/src/webidl-parser.y b/src/webidl-parser.y index 683a1a2..f719110 100644 --- a/src/webidl-parser.y +++ b/src/webidl-parser.y @@ -41,11 +41,11 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str) %union { - int attr; - long value; + int attr; + long value; bool isit; - char* text; - struct webidl_node *node; + char* text; + struct webidl_node *node; } diff --git a/test/data/bindings/window.bnd b/test/data/bindings/window.bnd index 42b40f4..7b411b1 100644 --- a/test/data/bindings/window.bnd +++ b/test/data/bindings/window.bnd @@ -31,8 +31,8 @@ binding window { internal "JSObject *" console; internal "JSObject *" location; - unshared type EventHandler; - unshared foo; + shared unshared type EventHandler; + shared unshared foo; } api mark %{ -- cgit v1.2.3