summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vincent.sanders@collabora.co.uk>2012-11-21 15:21:42 +0000
committerVincent Sanders <vincent.sanders@collabora.co.uk>2012-11-21 15:21:42 +0000
commit93c89193c1f2a29b00741d1494f262642108abe2 (patch)
tree9a7f5b8527dce50168dd4f6ac4105877bcde4d4f
parent607ae9bceedd28fdf3cab01b820916ef2406d2eb (diff)
downloadnsgenbind-93c89193c1f2a29b00741d1494f262642108abe2.tar.gz
nsgenbind-93c89193c1f2a29b00741d1494f262642108abe2.tar.bz2
make property shared status and type handling selection generic
-rw-r--r--src/jsapi-libdom-property.c181
-rw-r--r--src/nsgenbind-ast.c26
-rw-r--r--src/nsgenbind-ast.h16
-rw-r--r--src/nsgenbind-lexer.l2
-rw-r--r--src/nsgenbind-parser.y54
-rw-r--r--src/webidl-parser.y8
-rw-r--r--test/data/bindings/window.bnd4
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 <text> TOK_IDENTIFIER
%token <text> TOK_STRING_LITERAL
@@ -59,6 +61,9 @@ char *errtxt;
%type <text> CBlock
+%type <number> Modifiers
+%type <number> Modifier
+
%type <node> Statement
%type <node> Statements
%type <node> IdlFile
@@ -72,12 +77,13 @@ char *errtxt;
%type <node> Private
%type <node> Internal
%type <node> Interface
-%type <node> Unshared
+%type <node> Shared
%type <node> Operation
%type <node> Api
%type <node> Getter
%type <node> 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 %{