summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-07-30 17:28:06 +0100
committerVincent Sanders <vince@kyllikki.org>2015-07-30 17:28:06 +0100
commit4b723a410bc1a3355d401b95ac390f377b5d77b8 (patch)
treed36944de88d393973185ff357d6dded93e756166
parent1fcab4d37de137bbc346e6ed82d92ed97f2024cf (diff)
downloadnsgenbind-4b723a410bc1a3355d401b95ac390f377b5d77b8.tar.gz
nsgenbind-4b723a410bc1a3355d401b95ac390f377b5d77b8.tar.bz2
Clean up code generation functions
-rw-r--r--src/duk-libdom.c407
1 files changed, 221 insertions, 186 deletions
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 173d22f..a883f7c 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -34,6 +34,207 @@
" */"
/**
+ * 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, PRIVATE_MAGIC)\n\n");
+
+ 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, PRIVATE_MAGIC);\n",idx);
+ 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 code that gets a prototype by name
+ */
+static int output_get_prototype(FILE* outf, const char *interface_name)
+{
+ char *proto_name;
+ int pnamelen;
+
+ /* duplicate the interface name in upper case */
+ pnamelen = strlen(interface_name) + 1; /* allow for null byte */
+ proto_name = malloc(pnamelen);
+ for ( ; pnamelen >= 0; pnamelen--) {
+ proto_name[pnamelen] = toupper(interface_name[pnamelen]);
+ }
+ fprintf(outf, "\t/* get prototype */\n");
+ fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%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, INIT_MAGIC);\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
+
+ return 0;
+}
+
+static int
+output_dump_stack(FILE* outf)
+{
+ if (options->dbglog) {
+ /* dump stack */
+ fprintf(outf, "\tduk_push_context_dump(ctx);\n");
+ fprintf(outf, "\tLOG(\"Stack: %%s\", duk_to_string(ctx, -1));\n");
+ fprintf(outf, "\tduk_pop(ctx);\n");
+ }
+ return 0;
+}
+
+/**
+ * generate code that adds a method in a prototype
+ */
+static int
+output_add_method(FILE* outf, char *class_name, char *method, int argc)
+{
+ fprintf(outf, "\t/* Add a method */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
+ fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
+ DLPFX, class_name, method);
+ if (argc == -1) {
+ fprintf(outf, "DUK_VARARGS);\n");
+ } else {
+ fprintf(outf, "%d);\n", argc);
+ }
+ output_dump_stack(outf);
+ fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to populate a read/write property on a prototype
+ */
+static int
+output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add read/write property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
+ DLPFX, class_name, property);
+ fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to populate a readonly property on a prototype
+ */
+static int
+output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
+{
+ fprintf(outf, "\t/* Add readonly property */\n");
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
+ fprintf(outf,
+ "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
+ DLPFX, class_name, property);
+ fprintf(outf,
+ "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+
+ return 0;
+}
+
+/**
+ * Generate source to add a constant int value on a prototype
+ */
+static int
+output_prototype_constant_int(FILE *outf, const char *constant_name, int value)
+{
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constant_name);
+ fprintf(outf, "\tduk_push_int(ctx, %d);\n", value);
+ fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
+ fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
+ fprintf(outf, "\tduk_pop(ctx)\n\n");
+ return 0;
+}
+
+/**
+ * generate code that gets a private pointer for a method
+ */
+static int
+output_get_method_private(FILE* outf, char *class_name)
+{
+ fprintf(outf, "\t/* Get private data for method */\n");
+ fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
+ fprintf(outf, "\tduk_push_this(ctx);\n");
+ fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
+ fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
+ fprintf(outf, "\tduk_pop_2(ctx);\n");
+ fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
+ return 0;
+}
+
+/**
* Generate a C class name for the interface.
*
* The IDL interface names are camelcase and not similar to libdom naming so it
@@ -119,35 +320,6 @@ output_cdata(FILE* outf,
}
/**
- * Output code to create a private structure
- *
- */
-static int output_duckky_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, PRIVATE_MAGIC)\n\n");
-
- return 0;
-}
-
-/**
- * generate code that gets a private pointer
- */
-static int output_ducky_safe_get_private(FILE* outf, char *class_name, int idx)
-{
- fprintf(outf,
- "\t%s_private_t *priv = dukky_get_private(ctx, %d);\n",
- class_name, idx);
- fprintf(outf, "\tif (priv == NULL) return 0;\n\n");
- return 0;
-}
-
-
-/**
* generate the interface constructor
*/
static int
@@ -161,7 +333,7 @@ output_interface_constructor(FILE* outf, struct interface_map_entry *interfacee)
DLPFX, interfacee->class_name);
fprintf(outf,"{\n");
- output_duckky_create_private(outf, interfacee->class_name);
+ output_create_private(outf, interfacee->class_name);
/* generate call to initialisor */
fprintf(outf,
@@ -195,7 +367,7 @@ output_interface_destructor(FILE* outf, struct interface_map_entry *interfacee)
DLPFX, interfacee->class_name);
fprintf(outf,"{\n");
- output_ducky_safe_get_private(outf, interfacee->class_name, 0);
+ output_safe_get_private(outf, interfacee->class_name, 0);
/* generate call to finaliser */
fprintf(outf,
@@ -419,89 +591,6 @@ output_interface_fini(FILE* outf,
return 0;
}
-/**
- * generate code that gets a prototype by name
- */
-static int output_get_prototype(FILE* outf, const char *interface_name)
-{
- char *proto_name;
- int pnamelen;
-
- /* duplicate the interface name in upper case */
- pnamelen = strlen(interface_name) + 1; /* allow for null byte */
- proto_name = malloc(pnamelen);
- for ( ; pnamelen >= 0; pnamelen--) {
- proto_name[pnamelen] = toupper(interface_name[pnamelen]);
- }
- fprintf(outf, "\t/* get prototype */\n");
- fprintf(outf, "\tduk_get_global_string(ctx, PROTO_MAGIC);\n");
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, PROTO_NAME(%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, INIT_MAGIC);\n");
- fprintf(outf, "\tduk_pop(ctx);\n\n");
-
- return 0;
-}
-
-/**
- * generate code that adds a method in a prototype
- */
-static int
-output_add_method(FILE* outf, char *class_name, char *method, int argc)
-{
- fprintf(outf, "\t/* Add a method */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
- fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
- DLPFX, class_name, method);
- if (argc == -1) {
- fprintf(outf, "DUK_VARARGS);\n");
-
- } else {
- fprintf(outf, "%d);\n", argc);
- }
- fprintf(outf, "\tDUKKY_DUMP_STACK(ctx);\n");
- fprintf(outf, "\tduk_def_prop(ctx, -3,\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
/**
* count the number of arguments to an operation
@@ -554,7 +643,6 @@ output_prototype_method(FILE* outf,
output_add_method(outf, interfacee->class_name, op_name, op_argc);
return 0;
-
}
/**
@@ -600,47 +688,8 @@ output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
}
return 0;
-
}
-static int
-output_populate_rw_property(FILE* outf, const char *class_name, const char *property)
-{
- fprintf(outf, "\t/* Add read/write property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
- DLPFX, class_name, property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
- DLPFX, class_name, property);
- fprintf(outf, "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
-
-static int
-output_populate_ro_property(FILE* outf, const char *class_name, const char *property)
-{
- fprintf(outf, "\t/* Add readonly property */\n");
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", property);
- fprintf(outf,
- "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
- DLPFX, class_name, property);
- fprintf(outf,
- "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
-
- return 0;
-}
static int
output_prototype_attribute(FILE *outf,
@@ -651,11 +700,10 @@ output_prototype_attribute(FILE *outf,
return output_populate_ro_property(outf,
interfacee->class_name,
attributee->name);
- } else {
- return output_populate_rw_property(outf,
- interfacee->class_name,
- attributee->name);
}
+ return output_populate_rw_property(outf,
+ interfacee->class_name,
+ attributee->name);
}
/**
@@ -665,14 +713,17 @@ static int
output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
{
int attrc;
+ int res = 0;
for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- output_prototype_attribute(outf,
- interfacee,
- interfacee->attributev + attrc);
+ res = output_prototype_attribute(outf,interfacee,
+ interfacee->attributev + attrc);
+ if (res != 0) {
+ break;
+ }
}
- return 0;
+ return res;
}
/**
@@ -693,14 +744,8 @@ output_prototype_constant(FILE *outf,
NULL,
WEBIDL_NODE_TYPE_LITERAL_INT));
+ output_prototype_constant_int(outf, constante->name, *value);
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", constante->name);
- fprintf(outf, "\tduk_push_int(ctx, %d);\n", *value);
- fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
- fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
- fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
return 0;
}
@@ -711,12 +756,17 @@ static int
output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
{
int attrc;
+ int res = 0;
for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- output_prototype_constant(outf, interfacee->constantv + attrc);
+ res = output_prototype_constant(outf,
+ interfacee->constantv + attrc);
+ if (res != 0) {
+ break;
+ }
}
- return 0;
+ return res;
}
/**
@@ -766,21 +816,6 @@ output_interface_prototype(FILE* outf,
return 0;
}
-/**
- * generate code that gets a private pointer for a method
- */
-static int
-output_get_method_private(FILE* outf, char *class_name)
-{
- fprintf(outf, "\t/* Get private data for method */\n");
- fprintf(outf, "\t%s_private_t *priv = NULL;\n", class_name);
- fprintf(outf, "\tduk_push_this(ctx);\n");
- fprintf(outf, "\tduk_get_prop_string(ctx, -1, PRIVATE_MAGIC);\n");
- fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
- fprintf(outf, "\tduk_pop_2(ctx);\n");
- fprintf(outf, "\tif (priv == NULL) return 0; /* can do? No can do. */\n\n");
- return 0;
-}
/**
* generate a single class method for an interface operation