summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2015-07-29 16:22:36 +0100
committerVincent Sanders <vince@kyllikki.org>2015-07-29 16:22:36 +0100
commit0c5f196017056b257c4c5a28338f90ada379310a (patch)
treeb523e4a5ec71b194f7cbce3ec462301a845ba621
parentcb23f1f911523752db095781d0d5fa3e334f1aa5 (diff)
downloadnsgenbind-0c5f196017056b257c4c5a28338f90ada379310a.tar.gz
nsgenbind-0c5f196017056b257c4c5a28338f90ada379310a.tar.bz2
Generate constant values on the class prototype
-rw-r--r--src/duk-libdom.c51
-rw-r--r--src/interface-map.c92
-rw-r--r--src/interface-map.h13
3 files changed, 156 insertions, 0 deletions
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index f7a1a5f..00f1bbc 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -664,6 +664,54 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
}
/**
+ * output constants on the prototype
+ *
+ * \todo This implementation assumes the constant is a literal int and should
+ * check the type node base value.
+ */
+static int
+output_prototype_constant(FILE *outf,
+ struct interface_map_entry *interfacee,
+ struct interface_map_constant_entry *constante)
+{
+ int *value;
+
+ value = webidl_node_getint(
+ webidl_node_find_type(
+ webidl_node_getnode(constante->node),
+ NULL,
+ WEBIDL_NODE_TYPE_LITERAL_INT));
+
+
+ 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;
+}
+
+/**
+ * generate prototype constant definitions
+ */
+static int
+output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
+{
+ int attrc;
+
+ for (attrc = 0; attrc < interfacee->constantc; attrc++) {
+ output_prototype_constant(outf,
+ interfacee,
+ interfacee->constantv + attrc);
+ }
+
+ return 0;
+
+}
+
+/**
* generate the interface prototype creator
*/
static int
@@ -691,6 +739,9 @@ output_interface_prototype(FILE* outf,
/* generate setting of attributes */
output_prototype_attributes(outf, interfacee);
+ /* generate setting of constants */
+ output_prototype_constants(outf, interfacee);
+
/* generate setting of destructor */
output_set_destructor(outf, interfacee->class_name, 0);
diff --git a/src/interface-map.c b/src/interface-map.c
index 6a77b6a..2ac1871 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -114,6 +114,8 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
dstinf[idx].operationv = srcinf[inf].operationv;
dstinf[idx].attributec = srcinf[inf].attributec;
dstinf[idx].attributev = srcinf[inf].attributev;
+ dstinf[idx].constantc = srcinf[inf].constantc;
+ dstinf[idx].constantv = srcinf[inf].constantv;
dstinf[idx].class = srcinf[inf].class;
/* reduce refcount on inherit index if !=-1 */
@@ -302,6 +304,78 @@ attribute_map_new(struct webidl_node *interface,
return 0;
}
+static int
+constant_map_new(struct webidl_node *interface,
+ int *constantc_out,
+ struct interface_map_constant_entry **constantv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *constant_node; /* constant node */
+ struct interface_map_constant_entry *cure; /* current entry */
+ struct interface_map_constant_entry *constantv;
+ int constantc;
+
+ /* enumerate constants */
+ constantc = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_CONST);
+
+ if (constantc < 1) {
+ *constantc_out = 0;
+ *constantv_out = NULL; /* no constants so empty map */
+ return 0;
+ }
+
+ *constantc_out = constantc;
+
+ constantv = calloc(constantc,
+ sizeof(struct interface_map_constant_entry));
+ if (constantv == NULL) {
+ return -1;
+ };
+ cure = constantv;
+
+ /* iterate each list node within the interface */
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ while (list_node != NULL) {
+ /* iterate through constants on list */
+ constant_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_CONST);
+
+ while (constant_node != NULL) {
+ cure->node = constant_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(constant_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure++;
+
+ /* move to next constant */
+ constant_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ constant_node,
+ WEBIDL_NODE_TYPE_CONST);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *constantv_out = constantv; /* resulting constants map */
+
+ return 0;
+}
+
int interface_map_new(struct genbind_node *genbind,
struct webidl_node *webidl,
struct interface_map **index_out)
@@ -363,6 +437,11 @@ int interface_map_new(struct genbind_node *genbind,
&ecur->attributec,
&ecur->attributev);
+ /* enumerate and map the interface constants */
+ constant_map_new(node,
+ &ecur->constantc,
+ &ecur->constantv);
+
/* move to next interface */
node = webidl_node_find_type(webidl, node,
WEBIDL_NODE_TYPE_INTERFACE);
@@ -458,6 +537,19 @@ int interface_map_dump(struct interface_map *index)
}
}
}
+ if (ecur->constantc > 0) {
+ int idx;
+
+ fprintf(dumpf, " %d constants\n",
+ ecur->constantc);
+
+ for (idx = 0; idx < ecur->constantc; idx++) {
+ struct interface_map_constant_entry *cone;
+ cone = ecur->constantv + idx;
+ fprintf(dumpf, " %s\n",
+ cone->name);
+ }
+ }
ecur++;
}
diff --git a/src/interface-map.h b/src/interface-map.h
index 9d66dfb..8ce6c01 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -12,12 +12,14 @@
struct genbind_node;
struct webidl_node;
+/** map entry for operations on an interface */
struct interface_map_operation_entry {
const char *name; /** operation name */
struct webidl_node *node; /**< AST operation node */
struct genbind_node *method; /**< method from binding (if any) */
};
+/** map entry for attributes on an interface */
struct interface_map_attribute_entry {
const char *name; /** attribute name */
struct webidl_node *node; /**< AST attribute node */
@@ -26,6 +28,13 @@ struct interface_map_attribute_entry {
struct genbind_node *setter; /**< getter from binding (if any) */
};
+/** map entry for constants on an interface */
+struct interface_map_constant_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST constant node */
+};
+
+/** map entry for an interface */
struct interface_map_entry {
const char *name; /** interface name */
struct webidl_node *node; /**< AST interface node */
@@ -37,6 +46,9 @@ struct interface_map_entry {
int attributec; /**< number of attributes on interface */
struct interface_map_attribute_entry *attributev;
+ int constantc; /**< number of constants on interface */
+ struct interface_map_constant_entry *constantv;
+
int inherit_idx; /**< index into map of inherited interface or -1 for
* not in map
*/
@@ -62,6 +74,7 @@ struct interface_map_entry {
*/
};
+/** WebIDL interface map */
struct interface_map {
int entryc; /**< count of interfaces */
struct interface_map_entry *entries;