From 83956295f66576becbf5de8cef915cd0d54f409b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 30 Aug 2015 09:14:38 +0100 Subject: Change dictionary generation to produce C accessors. This generates routines which correctly handle reading a member from a dictionary and returning it as the correct c type. Currently the types "any", "user" and "sequence" remain unhandled. --- src/duk-libdom-dictionary.c | 766 +++++++++++++++++++------------------------- src/duk-libdom-interface.c | 45 ++- src/duk-libdom.c | 90 +----- src/duk-libdom.h | 10 + src/webidl-ast.c | 19 +- src/webidl-ast.h | 2 + 6 files changed, 421 insertions(+), 511 deletions(-) (limited to 'src') diff --git a/src/duk-libdom-dictionary.c b/src/duk-libdom-dictionary.c index 6aae0ca..69ce8aa 100644 --- a/src/duk-libdom-dictionary.c +++ b/src/duk-libdom-dictionary.c @@ -27,464 +27,290 @@ #define MAGICPFX "\\xFF\\xFFNETSURF_DUKTAPE_" -/** - * Output code to create a private structure - * - */ -static int output_create_private(FILE* outf, char *class_name) -{ - fprintf(outf, "\t/* create private data and attach to instance */\n"); - fprintf(outf, "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n", - class_name); - fprintf(outf, "\tif (priv == NULL) return 0;\n"); - fprintf(outf, "\tduk_push_pointer(ctx, priv);\n"); - fprintf(outf, - "\tduk_put_prop_string(ctx, 0, %s_magic_string_private);\n\n", - DLPFX); - - return 0; -} /** - * generate code that gets a private pointer - */ -static int output_safe_get_private(FILE* outf, char *class_name, int idx) -{ - fprintf(outf, - "\t%s_private_t *priv;\n", class_name); - fprintf(outf, - "\tduk_get_prop_string(ctx, %d, %s_magic_string_private);\n", - idx, DLPFX); - fprintf(outf, - "\tpriv = duk_get_pointer(ctx, -1);\n"); - fprintf(outf, - "\tduk_pop(ctx);\n"); - fprintf(outf, - "\tif (priv == NULL) return 0;\n\n"); - - return 0; -} - - -/** - * generate the dictionary constructor + * get default value as a string */ static int -output_dictionary_constructor(FILE* outf, struct ir_entry *dictionarye) +get_member_default_str(struct ir_entry *dictionarye, + struct ir_operation_argument_entry *membere, + enum webidl_type member_type, + char **defl_out) { - int init_argc; - - /* constructor definition */ - fprintf(outf, - "static duk_ret_t %s_%s___constructor(duk_context *ctx)\n", - DLPFX, dictionarye->class_name); - fprintf(outf,"{\n"); - - output_create_private(outf, dictionarye->class_name); - - /* generate call to initialisor */ - fprintf(outf, - "\t%s_%s___init(ctx, priv", - DLPFX, dictionarye->class_name); - for (init_argc = 1; - init_argc <= dictionarye->class_init_argc; - init_argc++) { - fprintf(outf, ", duk_get_pointer(ctx, %d)", init_argc); - } - fprintf(outf, ");\n"); - - - fprintf(outf, "\tduk_set_top(ctx, 1);\n"); - fprintf(outf, "\treturn 1;\n"); - - fprintf(outf, "}\n\n"); - - return 0; -} - -/** - * generate a duktape prototype name - */ -static char *get_prototype_name(const char *dictionary_name) -{ - char *proto_name; - int pnamelen; - int pfxlen; - - /* duplicate the dictionary name in upper case */ - pfxlen = SLEN(MAGICPFX) + SLEN("PROTOTYPE_"); - pnamelen = strlen(dictionary_name) + 1; - - proto_name = malloc(pnamelen + pfxlen); - snprintf(proto_name, pnamelen + pfxlen, "%sPROTOTYPE_%s", MAGICPFX, dictionary_name); - for (pnamelen-- ; pnamelen >= 0; pnamelen--) { - proto_name[pnamelen + pfxlen] = toupper(dictionary_name[pnamelen]); + struct webidl_node *lit_node; + enum webidl_node_type lit_type; + int *lit_int; + float *lit_flt; + + lit_node = webidl_node_getnode( + webidl_node_find_type( + webidl_node_getnode(membere->node), + NULL, + WEBIDL_NODE_TYPE_OPTIONAL)); + if (lit_node == NULL) { + *defl_out = NULL; + return 0; } - return proto_name; -} - - -/** - * generate code that gets a prototype by name - */ -static int output_get_prototype(FILE* outf, const char *dictionary_name) -{ - char *proto_name; - - proto_name = get_prototype_name(dictionary_name); - - fprintf(outf, - "\t/* get prototype */\n"); - fprintf(outf, - "\tduk_get_global_string(ctx, %s_magic_string_prototypes);\n", - DLPFX); - fprintf(outf, - "\tduk_get_prop_string(ctx, -1, \"%s\");\n", - proto_name); - fprintf(outf, - "\tduk_replace(ctx, -2);\n"); - - free(proto_name); - - return 0; -} - - -/** - * generate code that sets a destructor in a prototype - */ -static int output_set_destructor(FILE* outf, char *class_name, int idx) -{ - fprintf(outf, "\t/* Set the destructor */\n"); - fprintf(outf, "\tduk_dup(ctx, %d);\n", idx); - fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n", - DLPFX, class_name); - fprintf(outf, "\tduk_set_finalizer(ctx, -2);\n"); - fprintf(outf, "\tduk_pop(ctx);\n\n"); - - return 0; -} - -/** - * generate code that sets a constructor in a prototype - */ -static int -output_set_constructor(FILE* outf, char *class_name, int idx, int argc) -{ - fprintf(outf, "\t/* Set the constructor */\n"); - fprintf(outf, "\tduk_dup(ctx, %d);\n", idx); - fprintf(outf, "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n", - DLPFX, class_name, 1 + argc); - fprintf(outf, "\tduk_put_prop_string(ctx, -2, \"%sINIT\");\n", - MAGICPFX); - fprintf(outf, "\tduk_pop(ctx);\n\n"); - return 0; -} - -/** - * generate the dictionary prototype creator - */ -static int -output_dictionary_prototype(FILE* outf, - struct ir *ir, - struct ir_entry *dictionarye, - struct ir_entry *inherite) -{ - struct genbind_node *proto_node; + lit_type = webidl_node_gettype(lit_node); - /* find the prototype method on the class */ - proto_node = genbind_node_find_method(dictionarye->class, - NULL, - GENBIND_METHOD_TYPE_PROTOTYPE); + switch (lit_type) { - /* prototype definition */ - fprintf(outf, "duk_ret_t %s_%s___proto(duk_context *ctx)\n", - DLPFX, dictionarye->class_name); - fprintf(outf,"{\n"); - - /* Output any binding data first */ - if (output_cdata(outf, proto_node, GENBIND_NODE_TYPE_CDATA) != 0) { - fprintf(outf,"\n"); - } - - /* generate prototype chaining if dictionary has a parent */ - if (inherite != NULL) { - fprintf(outf, - "\t/* Set this prototype's prototype (left-parent) */\n"); - output_get_prototype(outf, inherite->name); - fprintf(outf, "\tduk_set_prototype(ctx, 0);\n\n"); + case WEBIDL_NODE_TYPE_LITERAL_BOOL: + if (member_type != WEBIDL_TYPE_BOOL) { + fprintf(stderr, + "Dictionary %s:%s literal boolean type mismatch\n", + dictionarye->name, + membere->name); + return -1; + } + lit_int = webidl_node_getint(lit_node); + if (*lit_int == 0) { + *defl_out = strdup("false"); + } else { + *defl_out = strdup("true"); + } + break; + + case WEBIDL_NODE_TYPE_LITERAL_NULL: + *defl_out = strdup("NULL"); + break; + + case WEBIDL_NODE_TYPE_LITERAL_STRING: + *defl_out = strdup(webidl_node_gettext(lit_node)); + break; + + case WEBIDL_NODE_TYPE_LITERAL_INT: + lit_int = webidl_node_getint(lit_node); + *defl_out = malloc(128); + sprintf(*defl_out, "%d", *lit_int); + break; + + case WEBIDL_NODE_TYPE_LITERAL_FLOAT: + lit_flt = webidl_node_getfloat(lit_node); + *defl_out = malloc(128); + sprintf(*defl_out, "%f", *lit_flt); + break; + + default: + *defl_out = NULL; + break; } - /* dictionary members*/ - - - /* generate setting of destructor */ - output_set_destructor(outf, dictionarye->class_name, 0); - - /* generate setting of constructor */ - output_set_constructor(outf, - dictionarye->class_name, - 0, - dictionarye->class_init_argc); - - fprintf(outf,"\treturn 1; /* The prototype object */\n"); - - fprintf(outf, "}\n\n"); - return 0; } /** - * generate the dictionary destructor + * generate a single class method for an interface operation */ static int -output_dictionary_destructor(FILE* outf, struct ir_entry *dictionarye) +output_member_acessor(FILE* outf, + struct ir_entry *dictionarye, + struct ir_operation_argument_entry *membere) { - /* destructor definition */ - fprintf(outf, - "static duk_ret_t %s_%s___destructor(duk_context *ctx)\n", - DLPFX, dictionarye->class_name); - fprintf(outf,"{\n"); - - output_safe_get_private(outf, dictionarye->class_name, 0); - - /* generate call to finaliser */ - fprintf(outf, - "\t%s_%s___fini(ctx, priv);\n", - DLPFX, dictionarye->class_name); - - fprintf(outf,"\tfree(priv);\n"); - fprintf(outf,"\treturn 0;\n"); - - fprintf(outf, "}\n\n"); + struct webidl_node *type_node; + enum webidl_type *argument_type; + char *defl; /* default for member */ + int res; - return 0; -} + type_node = webidl_node_find_type( + webidl_node_getnode(membere->node), + NULL, + WEBIDL_NODE_TYPE_TYPE); -/** - * generate an initialisor call to parent dictionary - */ -static int -output_dictionary_inherit_init(FILE* outf, - struct ir_entry *dictionarye, - struct ir_entry *inherite) -{ - struct genbind_node *init_node; - struct genbind_node *inh_init_node; - struct genbind_node *param_node; - struct genbind_node *inh_param_node; - - /* only need to call parent initialisor if there is one */ - if (inherite == NULL) { - return 0; + if (type_node == NULL) { + fprintf(stderr, "%s:%s has no type\n", + dictionarye->name, + membere->name); + return -1; } - /* find the initialisor method on the class (if any) */ - init_node = genbind_node_find_method(dictionarye->class, - NULL, - GENBIND_METHOD_TYPE_INIT); - - - inh_init_node = genbind_node_find_method(inherite->class, - NULL, - GENBIND_METHOD_TYPE_INIT); - - - - fprintf(outf, "\t%s_%s___init(ctx, &priv->parent", - DLPFX, inherite->class_name); - - /* for each parameter in the parent find a matching named - * parameter to pass and cast if necessary - */ - - inh_param_node = genbind_node_find_type( - genbind_node_getnode(inh_init_node), - NULL, GENBIND_NODE_TYPE_PARAMETER); - while (inh_param_node != NULL) { - char *param_name; - param_name = genbind_node_gettext( - genbind_node_find_type( - genbind_node_getnode(inh_param_node), - NULL, - GENBIND_NODE_TYPE_IDENT)); - - param_node = genbind_node_find_type_ident( - genbind_node_getnode(init_node), + argument_type = (enum webidl_type *)webidl_node_getint( + webidl_node_find_type( + webidl_node_getnode(type_node), NULL, - GENBIND_NODE_TYPE_PARAMETER, - param_name); - if (param_node == NULL) { - fprintf(stderr, "class \"%s\" (dictionary %s) parent class \"%s\" (dictionary %s) initialisor requires a parameter \"%s\" with compatible identifier\n", - dictionarye->class_name, - dictionarye->name, - inherite->class_name, - inherite->name, - param_name); - return -1; - } else { - char *param_type; - char *inh_param_type; - - fprintf(outf, ", "); - - /* cast the parameter if required */ - param_type = genbind_node_gettext( - genbind_node_find_type( - genbind_node_getnode(param_node), - NULL, - GENBIND_NODE_TYPE_TYPE)); - - inh_param_type = genbind_node_gettext( - genbind_node_find_type( - genbind_node_getnode(inh_param_node), - NULL, - GENBIND_NODE_TYPE_TYPE)); - - if (strcmp(param_type, inh_param_type) != 0) { - fprintf(outf, "(%s)", inh_param_type); - } - - /* output the parameter identifier */ - output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT); - } + WEBIDL_NODE_TYPE_TYPE_BASE)); - inh_param_node = genbind_node_find_type( - genbind_node_getnode(inh_init_node), - inh_param_node, GENBIND_NODE_TYPE_METHOD); + if (argument_type == NULL) { + fprintf(stderr, + "%s:%s has no type base\n", + dictionarye->name, + membere->name); + return -1; } - fprintf(outf, ");\n"); - - return 0; -} - -static int -output_dictionary_init_declaration(FILE* outf, - struct ir_entry *dictionarye, - struct genbind_node *init_node) -{ - struct genbind_node *param_node; - - if (dictionarye->refcount == 0) { - fprintf(outf, "static "); - } - fprintf(outf, - "void %s_%s___init(duk_context *ctx, %s_private_t *priv", - DLPFX, dictionarye->class_name, dictionarye->class_name); - - /* count the number of arguments on the initializer */ - dictionarye->class_init_argc = 0; - - /* output the paramters on the method (if any) */ - param_node = genbind_node_find_type( - genbind_node_getnode(init_node), - NULL, GENBIND_NODE_TYPE_PARAMETER); - while (param_node != NULL) { - dictionarye->class_init_argc++; - fprintf(outf, ", "); - output_cdata(outf, param_node, GENBIND_NODE_TYPE_TYPE); - output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT); - - param_node = genbind_node_find_type( - genbind_node_getnode(init_node), - param_node, GENBIND_NODE_TYPE_PARAMETER); + /* get default text */ + res = get_member_default_str(dictionarye, membere, *argument_type, &defl); + if (res != 0) { + return res; } - fprintf(outf,")"); + switch (*argument_type) { - return 0; -} + case WEBIDL_TYPE_STRING: + fprintf(outf, + "const char *\n" + "%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n" + "{\n", + DLPFX, dictionarye->class_name, membere->name); + + if (defl == NULL) { + fprintf(outf, + "\tconst char *ret = NULL; /* No default */\n"); + } else { + fprintf(outf, + "\tconst char *ret = \"%s\"; /* Default value of %s */\n", + defl, membere->name); + } -static int -output_dictionary_init(FILE* outf, - struct ir_entry *dictionarye, - struct ir_entry *inherite) -{ - struct genbind_node *init_node; - int res; + fprintf(outf, + "\t/* ... obj@idx ... */\n" + "\tduk_get_prop_string(ctx, idx, \"%s\");\n" + "\t/* ... obj@idx ... value/undefined */\n" + "\tif (!duk_is_undefined(ctx, -1)) {\n" + "\t\t/* Note, this throws a duk_error if it's not a string */\n" + "\t\tret = duk_require_string(ctx, -1);\n" + "\t}\n" + "\tduk_pop(ctx);\n" + "\treturn ret;\n" + "}\n\n", + membere->name); + + break; + + case WEBIDL_TYPE_BOOL: + fprintf(outf, + "duk_bool_t\n" + "%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n" + "{\n", + DLPFX, dictionarye->class_name, membere->name); + + if (defl == NULL) { + fprintf(outf, + "\tduk_bool_t ret = false; /* No default */\n"); + } else { + fprintf(outf, + "\tduk_bool_t ret = %s; /* Default value of %s */\n", + defl, membere->name); + } - /* find the initialisor method on the class (if any) */ - init_node = genbind_node_find_method(dictionarye->class, - NULL, - GENBIND_METHOD_TYPE_INIT); + fprintf(outf, + "\t/* ... obj@idx ... */\n" + "\tduk_get_prop_string(ctx, idx, \"%s\");\n" + "\t/* ... obj@idx ... value/undefined */\n" + "\tif (!duk_is_undefined(ctx, -1)) {\n" + "\t\t/* Note, this throws a duk_error if it's not a boolean */\n" + "\t\tret = duk_require_boolean(ctx, -1);\n" + "\t}\n" + "\tduk_pop(ctx);\n" + "\treturn ret;\n" + "}\n\n", + membere->name); + + break; + + case WEBIDL_TYPE_SHORT: + case WEBIDL_TYPE_LONG: + case WEBIDL_TYPE_LONGLONG: + fprintf(outf, + "duk_int_t\n" + "%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n" + "{\n", + DLPFX, dictionarye->class_name, membere->name); - /* initialisor definition */ - output_dictionary_init_declaration(outf, dictionarye, init_node); + if (defl == NULL) { + fprintf(outf, "\tduk_int_t ret = 0; /* No default */\n"); + } else { + fprintf(outf, + "\tduk_int_t ret = %s; /* Default value of %s */\n", + defl, membere->name); + } - fprintf(outf,"\n{\n"); + fprintf(outf, + "\t/* ... obj@idx ... */\n" + "\tduk_get_prop_string(ctx, idx, \"%s\");\n" + "\t/* ... obj@idx ... value/undefined */\n" + "\tif (!duk_is_undefined(ctx, -1)) {\n" + "\t\t/* Note, this throws a duk_error if it's not a int */\n" + "\t\tret = duk_require_int(ctx, -1);\n" + "\t}\n" + "\tduk_pop(ctx);\n" + "\treturn ret;\n" + "}\n\n", + membere->name); + break; + + case WEBIDL_TYPE_FLOAT: + case WEBIDL_TYPE_DOUBLE: + fprintf(outf, + "duk_double_t\n" + "%s_%s_get_%s(duk_context *ctx, duk_idx_t idx)\n", + DLPFX, dictionarye->class_name, membere->name); - /* if this dictionary inherits ensure we call its initialisor */ - res = output_dictionary_inherit_init(outf, dictionarye, inherite); - if (res != 0) { - return res; - } + fprintf(outf, + "{\n" + "\tduk_double_t ret = %s; /* Default value of %s */\n" + "\t/* ... obj@idx ... */\n" + "\tduk_get_prop_string(ctx, idx, \"%s\");\n", + defl, membere->name, membere->name); - /* generate log statement */ - if (options->dbglog) { fprintf(outf, - "\tLOG(\"Initialise %%p (priv=%%p)\", duk_get_heapptr(ctx, 0), priv);\n" ); + "\t/* ... obj@idx ... value/undefined */\n" + "\tif (!duk_is_undefined(ctx, -1)) {\n" + "\t\t/* Note, this throws a duk_error if it's not a number */\n" + "\t\tret = duk_require_number(ctx, -1);\n" + "\t}\n" + "\tduk_pop(ctx);\n" + "\treturn ret;\n" + "}\n\n"); + break; + + default: + WARN(WARNING_UNIMPLEMENTED, + "Dictionary %s:%s unhandled type (%d)\n", + dictionarye->name, + membere->name, + *argument_type); + fprintf(outf, + "/* Dictionary %s:%s unhandled type (%d) */\n\n", + dictionarye->name, + membere->name, + *argument_type); } - /* output the initaliser code from the binding */ - output_cdata(outf, init_node, GENBIND_NODE_TYPE_CDATA); - - fprintf(outf, "}\n\n"); + if (defl != NULL) { + free(defl); + } return 0; - } static int -output_dictionary_fini(FILE* outf, - struct ir_entry *dictionarye, - struct ir_entry *inherite) +output_member_acessors(FILE* outf, struct ir_entry *dictionarye) { - struct genbind_node *fini_node; - - /* find the finaliser method on the class (if any) */ - fini_node = genbind_node_find_method(dictionarye->class, - NULL, - GENBIND_METHOD_TYPE_FINI); - - /* finaliser definition */ - if (dictionarye->refcount == 0) { - fprintf(outf, "static "); - } - fprintf(outf, - "void %s_%s___fini(duk_context *ctx, %s_private_t *priv)\n", - DLPFX, dictionarye->class_name, dictionarye->class_name); - fprintf(outf,"{\n"); - - /* generate log statement */ - if (options->dbglog) { - fprintf(outf, - "\tLOG(\"Finalise %%p\", duk_get_heapptr(ctx, 0));\n" ); - } - - /* output the finialisor code from the binding */ - output_cdata(outf, fini_node, GENBIND_NODE_TYPE_CDATA); + int memberc; + int res = 0; - /* if this dictionary inherits ensure we call its finaliser */ - if (inherite != NULL) { - fprintf(outf, - "\t%s_%s___fini(ctx, &priv->parent);\n", - DLPFX, inherite->class_name); + for (memberc = 0; + memberc < dictionarye->u.dictionary.memberc; + memberc++) { + res = output_member_acessor( + outf, + dictionarye, + dictionarye->u.dictionary.memberv + memberc); + if (res != 0) { + break; + } } - fprintf(outf, "}\n\n"); - return 0; + return res; } -/** - * generate a source file to implement a dictionary using duk and libdom. - */ +/* exported function documented in duk-libdom.h */ int output_dictionary(struct ir *ir, struct ir_entry *dictionarye) { FILE *ifacef; - struct ir_entry *inherite; int res = 0; /* open output file */ @@ -493,9 +319,6 @@ int output_dictionary(struct ir *ir, struct ir_entry *dictionarye) return -1; } - /* find parent dictionary entry */ - inherite = ir_inherit_entry(ir, dictionarye); - /* tool preface */ output_tool_preface(ifacef); @@ -520,34 +343,8 @@ int output_dictionary(struct ir *ir, struct ir_entry *dictionarye) fprintf(ifacef, "\n"); - /* initialisor */ - res = output_dictionary_init(ifacef, dictionarye, inherite); - if (res != 0) { - goto op_error; - } - - /* finaliser */ - res = output_dictionary_fini(ifacef, dictionarye, inherite); - if (res != 0) { - goto op_error; - } - - /* constructor */ - res = output_dictionary_constructor(ifacef, dictionarye); - if (res != 0) { - goto op_error; - } - - /* destructor */ - res = output_dictionary_destructor(ifacef, dictionarye); - if (res != 0) { - goto op_error; - } - /** todo property handlers */ - - /* prototype */ - res = output_dictionary_prototype(ifacef, ir, dictionarye, inherite); + res = output_member_acessors(ifacef, dictionarye); if (res != 0) { goto op_error; } @@ -575,3 +372,102 @@ op_error: return res; } + +/** + * generate a single class method declaration for an interface operation + */ +static int +output_member_declaration(FILE* outf, + struct ir_entry *dictionarye, + struct ir_operation_argument_entry *membere) +{ + struct webidl_node *type_node; + enum webidl_type *argument_type; + + type_node = webidl_node_find_type( + webidl_node_getnode(membere->node), + NULL, + WEBIDL_NODE_TYPE_TYPE); + + if (type_node == NULL) { + fprintf(stderr, "%s:%s has no type\n", + dictionarye->name, + membere->name); + return -1; + } + + argument_type = (enum webidl_type *)webidl_node_getint( + webidl_node_find_type( + webidl_node_getnode(type_node), + NULL, + WEBIDL_NODE_TYPE_TYPE_BASE)); + + if (argument_type == NULL) { + fprintf(stderr, + "%s:%s has no type base\n", + dictionarye->name, + membere->name); + return -1; + } + + + switch (*argument_type) { + + case WEBIDL_TYPE_STRING: + fprintf(outf, + "const char *%s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n", + DLPFX, dictionarye->class_name, membere->name); + break; + + case WEBIDL_TYPE_BOOL: + fprintf(outf, + "duk_bool_t %s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n", + DLPFX, dictionarye->class_name, membere->name); + break; + + case WEBIDL_TYPE_SHORT: + case WEBIDL_TYPE_LONG: + case WEBIDL_TYPE_LONGLONG: + fprintf(outf, + "duk_int_t %s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n", + DLPFX, dictionarye->class_name, membere->name); + break; + + case WEBIDL_TYPE_FLOAT: + case WEBIDL_TYPE_DOUBLE: + fprintf(outf, + "duk_double_t %s_%s_get_%s(duk_context *ctx, duk_idx_t idx);\n", + DLPFX, dictionarye->class_name, membere->name); + break; + + default: + fprintf(outf, + "/* Dictionary %s:%s unhandled type (%d) */\n", + dictionarye->name, + membere->name, + *argument_type); + } + + return 0; +} + +/* exported function documented in duk-libdom.h */ +int output_dictionary_declaration(FILE* outf, struct ir_entry *dictionarye) +{ + int memberc; + int res = 0; + + for (memberc = 0; + memberc < dictionarye->u.dictionary.memberc; + memberc++) { + res = output_member_declaration( + outf, + dictionarye, + dictionarye->u.dictionary.memberv + memberc); + if (res != 0) { + break; + } + } + + return res; +} diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c index 3ac7d83..aa44d38 100644 --- a/src/duk-libdom-interface.c +++ b/src/duk-libdom-interface.c @@ -792,7 +792,7 @@ output_interface_elipsis_operation(FILE* outf, * operation with elipsis should go */ WARN(WARNING_UNIMPLEMENTED, - "Elipsis parameetrs not checked: method %s::%s();", + "Elipsis parameters not checked: method %s::%s();", interfacee->name, operatione->name); output_get_method_private(outf, interfacee->class_name); @@ -1339,3 +1339,46 @@ op_error: return res; } +/* exported function documented in duk-libdom.h */ +int output_interface_declaration(FILE* outf, struct ir_entry *interfacee) +{ + struct genbind_node *init_node; + + /* do not generate prototype declarations for interfaces marked no + * output + */ + if (interfacee->u.interface.noobject) { + return 0; + } + + /* prototype declaration */ + fprintf(outf, "duk_ret_t %s_%s___proto(duk_context *ctx);\n", + DLPFX, interfacee->class_name); + + /* if the interface has no references (no other interface inherits from + * it) there is no reason to export the initalisor/finaliser as no + * other class constructor/destructor should call them. + */ + if (interfacee->refcount < 1) { + fprintf(outf, "\n"); + + return 0; + } + + /* finaliser declaration */ + fprintf(outf, + "void %s_%s___fini(duk_context *ctx, %s_private_t *priv);\n", + DLPFX, interfacee->class_name, interfacee->class_name); + + /* find the initialisor method on the class (if any) */ + init_node = genbind_node_find_method(interfacee->class, + NULL, + GENBIND_METHOD_TYPE_INIT); + + /* initialisor definition */ + output_interface_init_declaration(outf, interfacee, init_node); + + fprintf(outf, ";\n\n"); + + return 0; +} diff --git a/src/duk-libdom.c b/src/duk-libdom.c index 02b41b3..f72bc96 100644 --- a/src/duk-libdom.c +++ b/src/duk-libdom.c @@ -132,14 +132,14 @@ static FILE *open_header(struct ir *ir, const char *name) return NULL; } + /* tool preface */ + output_tool_preface(hdrf); + /* binding preface */ output_cdata(hdrf, ir->binding_node, GENBIND_NODE_TYPE_PREFACE); - /* tool preface */ - output_tool_preface(hdrf); - /* header guard */ fprintf(hdrf, "\n#ifndef %s_%s_h\n", DLPFX, name); fprintf(hdrf, "#define %s_%s_h\n\n", DLPFX, name); @@ -172,43 +172,6 @@ static int close_header(struct ir *ir, } - - -static int -output_interface_init_declaration(FILE* outf, - struct ir_entry *interfacee, - struct genbind_node *init_node) -{ - struct genbind_node *param_node; - - fprintf(outf, - "void %s_%s___init(duk_context *ctx, %s_private_t *priv", - DLPFX, interfacee->class_name, interfacee->class_name); - - /* count the number of arguments on the initializer */ - interfacee->class_init_argc = 0; - - /* output the paramters on the method (if any) */ - param_node = genbind_node_find_type( - genbind_node_getnode(init_node), - NULL, GENBIND_NODE_TYPE_PARAMETER); - while (param_node != NULL) { - interfacee->class_init_argc++; - fprintf(outf, ", "); - output_cdata(outf, param_node, GENBIND_NODE_TYPE_TYPE); - output_cdata(outf, param_node, GENBIND_NODE_TYPE_IDENT); - - param_node = genbind_node_find_type( - genbind_node_getnode(init_node), - param_node, GENBIND_NODE_TYPE_PARAMETER); - } - - fprintf(outf,")"); - - return 0; -} - - /** * generate private header */ @@ -314,44 +277,19 @@ output_prototype_header(struct ir *ir) protof = open_header(ir, "prototype"); for (idx = 0; idx < ir->entryc; idx++) { - struct ir_entry *interfacee; - struct genbind_node *init_node; - - interfacee = ir->entries + idx; + struct ir_entry *entry; - /* do not generate prototype declarations for interfaces marked - * no output - */ - if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) && - (interfacee->u.interface.noobject)) { - continue; - } + entry = ir->entries + idx; - /* prototype declaration */ - fprintf(protof, "duk_ret_t %s_%s___proto(duk_context *ctx);\n", - DLPFX, interfacee->class_name); + switch (entry->type) { + case IR_ENTRY_TYPE_INTERFACE: + output_interface_declaration(protof, entry); + break; - /* if the interface has no references (no other interface - * inherits from it) there is no reason to export the - * initalisor/finaliser as no other class - * constructor/destructor should call them. - */ - if (interfacee->refcount > 0) { - /* finaliser declaration */ - fprintf(protof, - "void %s_%s___fini(duk_context *ctx, %s_private_t *priv);\n", - DLPFX, interfacee->class_name, interfacee->class_name); - - /* find the initialisor method on the class (if any) */ - init_node = genbind_node_find_method(interfacee->class, - NULL, - GENBIND_METHOD_TYPE_INIT); - - /* initialisor definition */ - output_interface_init_declaration(protof, interfacee, init_node); - fprintf(protof, ";\n\n"); + case IR_ENTRY_TYPE_DICTIONARY: + output_dictionary_declaration(protof, entry); + break; } - fprintf(protof, "\n"); } close_header(ir, protof, "prototype"); @@ -612,6 +550,10 @@ output_binding_src(struct ir *ir) interfacee = ir->entries + idx; + if (interfacee->type == IR_ENTRY_TYPE_DICTIONARY) { + continue; + } + /* do not generate prototype calls for interfaces marked * no output */ diff --git a/src/duk-libdom.h b/src/duk-libdom.h index 84fc497..79b440e 100644 --- a/src/duk-libdom.h +++ b/src/duk-libdom.h @@ -19,11 +19,21 @@ int duk_libdom_output(struct ir *ir); */ int output_interface(struct ir *ir, struct ir_entry *interfacee); +/** + * generate a declaration to implement a dictionary using duk and libdom. + */ +int output_interface_declaration(FILE* outf, struct ir_entry *interfacee); + /** * generate a source file to implement a dictionary using duk and libdom. */ int output_dictionary(struct ir *ir, struct ir_entry *dictionarye); +/** + * generate a declaration to implement a dictionary using duk and libdom. + */ +int output_dictionary_declaration(FILE* outf, struct ir_entry *dictionarye); + /** * generate preface block for nsgenbind */ diff --git a/src/webidl-ast.c b/src/webidl-ast.c index dc78e1f..e9dda2d 100644 --- a/src/webidl-ast.c +++ b/src/webidl-ast.c @@ -34,6 +34,7 @@ struct webidl_node { void *value; struct webidl_node *node; /* node has a list of nodes */ char *text; /* node data is text */ + float *flt; int number; /* node data is an integer */ } r; }; @@ -298,6 +299,22 @@ webidl_node_getint(struct webidl_node *node) return NULL; } +/* exported interface defined in webidl-ast.h */ +float * +webidl_node_getfloat(struct webidl_node *node) +{ + if (node != NULL) { + switch(node->type) { + case WEBIDL_NODE_TYPE_LITERAL_FLOAT: + return node->r.flt; + + default: + break; + } + } + return NULL; +} + /* exported interface defined in webidl-ast.h */ enum webidl_node_type webidl_node_gettype(struct webidl_node *node) { @@ -398,7 +415,7 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type) return "Literal (bool)"; case WEBIDL_NODE_TYPE_LITERAL_FLOAT: - return "Literal (string)"; + return "Literal (float)"; case WEBIDL_NODE_TYPE_LITERAL_STRING: return "Literal (string)"; diff --git a/src/webidl-ast.h b/src/webidl-ast.h index 0872965..9ae2ebb 100644 --- a/src/webidl-ast.h +++ b/src/webidl-ast.h @@ -105,6 +105,8 @@ struct webidl_node *webidl_node_add(struct webidl_node *node, struct webidl_node char *webidl_node_gettext(struct webidl_node *node); struct webidl_node *webidl_node_getnode(struct webidl_node *node); int *webidl_node_getint(struct webidl_node *node); +float *webidl_node_getfloat(struct webidl_node *node); + enum webidl_node_type webidl_node_gettype(struct webidl_node *node); /* node searches */ -- cgit v1.2.3