From 26bbe37c6f0b99f23736380ba55f156f22bdaf06 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Mon, 29 Oct 2012 23:45:29 +0000 Subject: implement basic property getter functionality --- src/jsapi-libdom-operator.c | 5 ++++ src/jsapi-libdom-property.c | 67 ++++++++++++++++++++++++++++++++++++++++++--- src/jsapi-libdom.c | 9 ------ src/nsgenbind-ast.c | 8 ++++++ src/nsgenbind-ast.h | 2 ++ src/nsgenbind-lexer.l | 4 +++ src/nsgenbind-parser.y | 34 +++++++++++++++++++++++ 7 files changed, 116 insertions(+), 13 deletions(-) diff --git a/src/jsapi-libdom-operator.c b/src/jsapi-libdom-operator.c index d5e037a..303c9da 100644 --- a/src/jsapi-libdom-operator.c +++ b/src/jsapi-libdom-operator.c @@ -362,6 +362,11 @@ static int webidl_operator_body_cb(struct webidl_node *node, void *ctx) output_code_block(binding, genbind_node_getnode(operation_node)); + } else { + fprintf(stderr, + "Warning: function/operation %s.%s has no implementation\n", + binding->interface, + webidl_node_gettext(ident_node)); } /* set return value an return true */ diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c index 8d8afa2..c2c6c6a 100644 --- a/src/jsapi-libdom-property.c +++ b/src/jsapi-libdom-property.c @@ -129,6 +129,7 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx) struct binding *binding = ctx; struct webidl_node *ident_node; struct webidl_node *modifier_node; + struct genbind_node *property_node; ident_node = webidl_node_find(webidl_node_getnode(node), NULL, @@ -160,13 +161,71 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx) "}\n\n"); } + /* property getter */ fprintf(binding->outfile, - "static JSBool JSAPI_PROPERTYGET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n", + "static JSBool JSAPI_PROPERTYGET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n" + "{\n", webidl_node_gettext(ident_node)); + + /* return value */ + fprintf(binding->outfile, "\tjsval jsretval = JSVAL_NULL;\n"); + + /* get context */ + fprintf(binding->outfile, + "\tstruct jsclass_private *private;\n" + "\n" + "\tprivate = JS_GetInstancePrivate(cx,\n" + "\t\tobj,\n" + "\t\t&JSClass_%s,\n" + "\t\tNULL);\n" + "\tif (private == NULL)\n" + "\t\treturn JS_FALSE;\n\n", + binding->interface); + + property_node = genbind_node_find_type_ident(binding->gb_ast, + NULL, + GENBIND_NODE_TYPE_GETTER, + webidl_node_gettext(ident_node)); + + if (property_node != NULL) { + /* binding source block */ + output_code_block(binding, genbind_node_getnode(property_node)); + } else { + /* examine internal variables and see if they are gettable */ + struct genbind_node *binding_node; + struct genbind_node *internal_node = NULL; + + binding_node = genbind_node_find_type(binding->gb_ast, + NULL, + GENBIND_NODE_TYPE_BINDING); + + if (binding_node != NULL) { + internal_node = genbind_node_find_type_ident(genbind_node_getnode(binding_node), + NULL, + GENBIND_NODE_TYPE_BINDING_INTERNAL, + webidl_node_gettext(ident_node)); + + } + + if (internal_node != NULL) { + /** @todo fetching from internal entries ought to be type sensitive */ + fprintf(binding->outfile, + "\tjsretval = OBJECT_TO_JSVAL(private->%s);\n", + webidl_node_gettext(ident_node)); + } else { + fprintf(stderr, + "Warning: property/attribute getter %s.%s has no implementation\n", + binding->interface, + webidl_node_gettext(ident_node)); + } + + } + + fprintf(binding->outfile, - "{\n" - " JS_SET_RVAL(cx, vp, JSVAL_NULL);\n" - " return JS_TRUE;\n"); + "\tJS_SET_RVAL(cx, vp, jsretval);\n" + "\treturn JS_TRUE;\n"); + fprintf(binding->outfile, "}\n\n"); diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index 8a688b0..36ed6b6 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -159,15 +159,6 @@ generate_function_spec(struct binding *binding, const char *interface) } - - - - - - - - - static int webidl_private_cb(struct genbind_node *node, void *ctx) { struct binding *binding = ctx; diff --git a/src/nsgenbind-ast.c b/src/nsgenbind-ast.c index e192d74..e633439 100644 --- a/src/nsgenbind-ast.c +++ b/src/nsgenbind-ast.c @@ -198,6 +198,8 @@ struct genbind_node *genbind_node_getnode(struct genbind_node *node) case GENBIND_NODE_TYPE_BINDING_INTERNAL: case GENBIND_NODE_TYPE_OPERATION: case GENBIND_NODE_TYPE_API: + case GENBIND_NODE_TYPE_GETTER: + case GENBIND_NODE_TYPE_SETTER: return node->r.node; default: @@ -247,6 +249,12 @@ static const char *genbind_node_type_to_str(enum genbind_node_type type) case GENBIND_NODE_TYPE_API: return "API"; + case GENBIND_NODE_TYPE_GETTER: + return "Getter"; + + case GENBIND_NODE_TYPE_SETTER: + return "Setter"; + case GENBIND_NODE_TYPE_CBLOCK: return "CBlock"; diff --git a/src/nsgenbind-ast.h b/src/nsgenbind-ast.h index 0006153..54a49d2 100644 --- a/src/nsgenbind-ast.h +++ b/src/nsgenbind-ast.h @@ -24,6 +24,8 @@ enum genbind_node_type { GENBIND_NODE_TYPE_BINDING_INTERFACE, GENBIND_NODE_TYPE_API, GENBIND_NODE_TYPE_OPERATION, + GENBIND_NODE_TYPE_GETTER, + GENBIND_NODE_TYPE_SETTER, }; diff --git a/src/nsgenbind-lexer.l b/src/nsgenbind-lexer.l index 040d7e9..61aee7e 100644 --- a/src/nsgenbind-lexer.l +++ b/src/nsgenbind-lexer.l @@ -100,6 +100,10 @@ operation return TOK_OPERATION; api return TOK_API; +getter return TOK_GETTER; + +setter return TOK_SETTER; + {cblockopen} BEGIN(cblock); {identifier} { diff --git a/src/nsgenbind-parser.y b/src/nsgenbind-parser.y index ea0a625..1ffab7a 100644 --- a/src/nsgenbind-parser.y +++ b/src/nsgenbind-parser.y @@ -45,6 +45,8 @@ char *errtxt; %token TOK_API %token TOK_BINDING %token TOK_OPERATION +%token TOK_GETTER +%token TOK_SETTER %token TOK_INTERFACE %token TOK_TYPE %token TOK_PRIVATE @@ -71,6 +73,8 @@ char *errtxt; %type Interface %type Operation %type Api +%type Getter +%type Setter %% @@ -113,6 +117,10 @@ Statement Operation | Api + | + Getter + | + Setter ; /* [3] load a web IDL file */ @@ -189,6 +197,32 @@ Api $2)); } +Getter + : + TOK_GETTER TOK_IDENTIFIER CBlock + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_GETTER, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, + genbind_new_node(GENBIND_NODE_TYPE_CBLOCK, + NULL, + $3), + $2)); + } + +Setter + : + TOK_SETTER TOK_IDENTIFIER CBlock + { + $$ = genbind_new_node(GENBIND_NODE_TYPE_SETTER, + NULL, + genbind_new_node(GENBIND_NODE_TYPE_IDENT, + genbind_new_node(GENBIND_NODE_TYPE_CBLOCK, + NULL, + $3), + $2)); + } + Binding : TOK_BINDING TOK_IDENTIFIER '{' BindingArgs '}' -- cgit v1.2.3