From 0c5f196017056b257c4c5a28338f90ada379310a Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Wed, 29 Jul 2015 16:22:36 +0100 Subject: Generate constant values on the class prototype --- src/duk-libdom.c | 51 +++++++++++++++++++++++++++++ src/interface-map.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/interface-map.h | 13 ++++++++ 3 files changed, 156 insertions(+) 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 @@ -663,6 +663,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 */ @@ -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; -- cgit v1.2.3