From 819943b7eaa3de48d80a20008250b9e2ea911aaa Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Fri, 22 May 2020 17:31:37 +0100 Subject: duktape: Guess at and support more than pointer init arguments Signed-off-by: Daniel Silverstone --- src/duk-libdom-interface.c | 67 +++++++++++++++++++++++++++++++++++++++++++--- src/ir.h | 8 ++++++ 2 files changed, 72 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/duk-libdom-interface.c b/src/duk-libdom-interface.c index f6be419..e10b734 100644 --- a/src/duk-libdom-interface.c +++ b/src/duk-libdom-interface.c @@ -417,12 +417,28 @@ output_interface_constructor(struct opctx *outc, struct ir_entry *interfacee) outputf(outc, "\t%s_%s___init(ctx, priv", DLPFX, interfacee->class_name); + for (init_argc = 1; init_argc <= interfacee->class_init_argc; init_argc++) { - outputf(outc, - ", duk_get_pointer(ctx, %d)", - init_argc); + switch (interfacee->class_init_argt[init_argc-1]) { + case IR_INIT_ARG_BOOL: + outputf(outc, + ", duk_get_bool(ctx, %d)", + init_argc); + break; + case IR_INIT_ARG_UNSIGNED: + case IR_INIT_ARG_INT: + outputf(outc, + ", duk_get_int(ctx, %d)", + init_argc); + break; + case IR_INIT_ARG_POINTER: + outputf(outc, + ", duk_get_pointer(ctx, %d)", + init_argc); + break; + } } outputf(outc, ");\n"); @@ -557,6 +573,46 @@ output_interface_inherit_init(struct opctx *outc, return 0; } +static enum ir_init_argtype +guess_argtype_from(struct genbind_node *param_node) +{ + const char *type_cdata = NULL; + struct genbind_node *typename_node; + bool unsigned_ = false; + bool int_ = false; + bool bool_ = false; + + typename_node = genbind_node_find_type(genbind_node_getnode(param_node), + NULL, + GENBIND_NODE_TYPE_NAME); + while (typename_node != NULL) { + type_cdata = genbind_node_gettext(typename_node); + if (strcmp(type_cdata, "unsigned") == 0) { + unsigned_ = true; + } else if (strcmp(type_cdata, "int") == 0) { + int_ = true; + } else if (strcmp(type_cdata, "bool") == 0) { + bool_ = true; + } + typename_node = genbind_node_find_type( + genbind_node_getnode(param_node), + typename_node, + GENBIND_NODE_TYPE_NAME); + } + + if (type_cdata[0] == '*') { + return IR_INIT_ARG_POINTER; + } else if (unsigned_) { + return IR_INIT_ARG_UNSIGNED; + } else if (int_) { + return IR_INIT_ARG_INT; + } else if (bool_) { + return IR_INIT_ARG_BOOL; + } + + /* If we have no better idea do this */ + return IR_INIT_ARG_POINTER; +} static int output_interface_init_declaration(struct opctx *outc, @@ -575,6 +631,7 @@ output_interface_init_declaration(struct opctx *outc, /* count the number of arguments on the initializer */ interfacee->class_init_argc = 0; + interfacee->class_init_argt = NULL; /* output the paramters on the method (if any) */ param_node = genbind_node_find_type( @@ -582,6 +639,10 @@ output_interface_init_declaration(struct opctx *outc, NULL, GENBIND_NODE_TYPE_PARAMETER); while (param_node != NULL) { interfacee->class_init_argc++; + interfacee->class_init_argt = realloc(interfacee->class_init_argt, + interfacee->class_init_argc * sizeof(enum ir_init_argtype)); + interfacee->class_init_argt[interfacee->class_init_argc - 1] = + guess_argtype_from(param_node); outputf(outc, ", "); output_ctype(outc, param_node, true); diff --git a/src/ir.h b/src/ir.h index 6b848ea..72e2137 100644 --- a/src/ir.h +++ b/src/ir.h @@ -123,6 +123,13 @@ enum ir_entry_type { IR_ENTRY_TYPE_DICTIONARY, }; +enum ir_init_argtype { + IR_INIT_ARG_POINTER, + IR_INIT_ARG_UNSIGNED, + IR_INIT_ARG_INT, + IR_INIT_ARG_BOOL, +}; + /** top level entry info common to interfaces and dictionaries */ struct ir_entry { const char *name; /** IDL name */ @@ -158,6 +165,7 @@ struct ir_entry { int class_init_argc; /**< The number of parameters on the class * initializer. */ + enum ir_init_argtype *class_init_argt; /**< The types of the initialiser parameters */ }; /** intermediate representation of WebIDL and binding data */ -- cgit v1.2.3