summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-08-30 09:14:38 +0100
committerVincent Sanders <vince@kyllikki.org>2015-08-30 09:14:38 +0100
commit83956295f66576becbf5de8cef915cd0d54f409b (patch)
treeb8040d623ed6d0998ddb23224f364cc1b4be2460
parentd6f41574a18866ebfbb8b61f9afcd0a0de2d40cf (diff)
downloadnsgenbind-83956295f66576becbf5de8cef915cd0d54f409b.tar.gz
nsgenbind-83956295f66576becbf5de8cef915cd0d54f409b.tar.bz2
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.
-rw-r--r--src/duk-libdom-dictionary.c766
-rw-r--r--src/duk-libdom-interface.c45
-rw-r--r--src/duk-libdom.c90
-rw-r--r--src/duk-libdom.h10
-rw-r--r--src/webidl-ast.c19
-rw-r--r--src/webidl-ast.h2
6 files changed, 421 insertions, 511 deletions
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
@@ -20,11 +20,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
*/
int output_tool_preface(FILE* outf);
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;
};
@@ -299,6 +300,22 @@ webidl_node_getint(struct webidl_node *node)
}
/* 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)
{
return node->type;
@@ -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 */