Gitweb links:
...log
http://git.netsurf-browser.org/nsgenbind.git/shortlog/56eee21ccb63cb7f040...
...commit
http://git.netsurf-browser.org/nsgenbind.git/commit/56eee21ccb63cb7f040c5...
...tree
http://git.netsurf-browser.org/nsgenbind.git/tree/56eee21ccb63cb7f040c5ce...
The branch, master has been updated
via 56eee21ccb63cb7f040c5ce07bc226fbd229330d (commit)
via e8d19a2821bfd15bcbe8d17f6564439c1673cbf7 (commit)
via 40cd6a199d8a5f92f71c5638f4da021a779e7a5c (commit)
from ee69169f841542c6d5d8a8c7d4b011e294d73bd8 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commitdiff
http://git.netsurf-browser.org/nsgenbind.git/commit/?id=56eee21ccb63cb7f0...
commit 56eee21ccb63cb7f040c5ce07bc226fbd229330d
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
add dictionary support and generation
The dictionary implementation is presetnt but incomplete.
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 046f741..3e20d13 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -293,7 +293,7 @@ static int output_tool_preface(FILE* outf)
* - if the previous character in the input name was uppercase and the current
* one is lowercase insert an underscore before the *previous* character.
*/
-static char *gen_class_name(struct ir_interface_entry *interfacee)
+static char *gen_class_name(struct ir_entry *interfacee)
{
const char *inc;
char *outc;
@@ -301,7 +301,8 @@ static char *gen_class_name(struct ir_interface_entry *interfacee)
int wasupper;
/* enpty strings are a bad idea */
- if ((interfacee->name == NULL) || (interfacee->name[0] == 0)) {
+ if ((interfacee->name == NULL) ||
+ (interfacee->name[0] == 0)) {
return NULL;
}
@@ -434,7 +435,7 @@ static int close_header(struct ir *ir,
* generate the interface constructor
*/
static int
-output_interface_constructor(FILE* outf, struct ir_interface_entry *interfacee)
+output_interface_constructor(FILE* outf, struct ir_entry *interfacee)
{
int init_argc;
@@ -470,7 +471,7 @@ output_interface_constructor(FILE* outf, struct ir_interface_entry
*interfacee)
* generate the interface destructor
*/
static int
-output_interface_destructor(FILE* outf, struct ir_interface_entry *interfacee)
+output_interface_destructor(FILE* outf, struct ir_entry *interfacee)
{
/* destructor definition */
fprintf(outf,
@@ -498,8 +499,8 @@ output_interface_destructor(FILE* outf, struct ir_interface_entry
*interfacee)
*/
static int
output_interface_inherit_init(FILE* outf,
- struct ir_interface_entry *interfacee,
- struct ir_interface_entry *inherite)
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *init_node;
struct genbind_node *inh_init_node;
@@ -593,7 +594,7 @@ output_interface_inherit_init(FILE* outf,
static int
output_interface_init_declaration(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct genbind_node *init_node)
{
struct genbind_node *param_node;
@@ -627,8 +628,8 @@ output_interface_init_declaration(FILE* outf,
static int
output_interface_init(FILE* outf,
- struct ir_interface_entry *interfacee,
- struct ir_interface_entry *inherite)
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *init_node;
int res;
@@ -666,8 +667,8 @@ output_interface_init(FILE* outf,
static int
output_interface_fini(FILE* outf,
- struct ir_interface_entry *interfacee,
- struct ir_interface_entry *inherite)
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *fini_node;
@@ -708,7 +709,7 @@ output_interface_fini(FILE* outf,
*/
static int
output_prototype_method(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
@@ -730,15 +731,16 @@ output_prototype_method(FILE* outf,
* generate prototype method definitions
*/
static int
-output_prototype_methods(FILE *outf, struct ir_interface_entry *interfacee)
+output_prototype_methods(FILE *outf, struct ir_entry *entry)
{
int opc;
int res = 0;
- for (opc = 0; opc < interfacee->operationc; opc++) {
- res = output_prototype_method(outf,
- interfacee,
- interfacee->operationv + opc);
+ for (opc = 0; opc < entry->u.interface.operationc; opc++) {
+ res = output_prototype_method(
+ outf,
+ entry,
+ entry->u.interface.operationv + opc);
if (res != 0) {
break;
}
@@ -750,8 +752,8 @@ output_prototype_methods(FILE *outf, struct ir_interface_entry
*interfacee)
static int
output_prototype_attribute(FILE *outf,
- struct ir_interface_entry *interfacee,
- struct ir_attribute_entry *attributee)
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *attributee)
{
if (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
return output_populate_ro_property(outf,
@@ -767,14 +769,16 @@ output_prototype_attribute(FILE *outf,
* generate prototype attribute definitions
*/
static int
-output_prototype_attributes(FILE *outf, struct ir_interface_entry *interfacee)
+output_prototype_attributes(FILE *outf, struct ir_entry *entry)
{
int attrc;
int res = 0;
- for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- res = output_prototype_attribute(outf,interfacee,
- interfacee->attributev + attrc);
+ for (attrc = 0; attrc < entry->u.interface.attributec; attrc++) {
+ res = output_prototype_attribute(
+ outf,
+ entry,
+ entry->u.interface.attributev + attrc);
if (res != 0) {
break;
}
@@ -810,14 +814,15 @@ output_prototype_constant(FILE *outf,
* generate prototype constant definitions
*/
static int
-output_prototype_constants(FILE *outf, struct ir_interface_entry *interfacee)
+output_prototype_constants(FILE *outf, struct ir_entry *entry)
{
int attrc;
int res = 0;
- for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- res = output_prototype_constant(outf,
- interfacee->constantv + attrc);
+ for (attrc = 0; attrc < entry->u.interface.constantc; attrc++) {
+ res = output_prototype_constant(
+ outf,
+ entry->u.interface.constantv + attrc);
if (res != 0) {
break;
}
@@ -826,14 +831,46 @@ output_prototype_constants(FILE *outf, struct ir_interface_entry
*interfacee)
return res;
}
+static int
+output_global_create_prototype(FILE* outf,
+ struct ir *ir,
+ struct ir_entry *interfacee)
+{
+ int idx;
+
+ fprintf(outf, "\t/* Create interface objects */\n");
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *entry;
+
+ entry = ir->entries + idx;
+
+ if (entry->type == IR_ENTRY_TYPE_INTERFACE) {
+
+ if (entry->u.interface.noobject) {
+ continue;
+ }
+
+ if (entry == interfacee) {
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ } else {
+ output_get_prototype(outf, entry->name);
+ }
+
+ fprintf(outf,
+ "\tdukky_inject_not_ctr(ctx, 0,
\"%s\");\n",
+ entry->name);
+ }
+ }
+ return 0;
+}
/**
* generate the interface prototype creator
*/
static int
output_interface_prototype(FILE* outf,
- struct ir_interface_entry *interfacee,
- struct ir_interface_entry *inherite,
- struct ir *ir)
+ struct ir *ir,
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *proto_node;
@@ -872,21 +909,8 @@ output_interface_prototype(FILE* outf,
/* if this is the global object, output all interfaces which do not
* prevent us from doing so
*/
- if (interfacee->primary_global) {
- fprintf(outf, "\t/* Create interface objects */\n");
- for (int idx = 0; idx < ir->interfacec; idx++) {
- struct ir_interface_entry *interfacep;
-
- interfacep = ir->interfaces + idx;
- if (interfacep->noobject) continue;
- if (interfacep == interfacee)
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- else
- output_get_prototype(outf, interfacep->name);
- fprintf(outf,
- "\tdukky_inject_not_ctr(ctx, 0,
\"%s\");\n",
- interfacep->name);
- }
+ if (interfacee->u.interface.primary_global) {
+ output_global_create_prototype(outf, ir, interfacee);
}
/* generate setting of destructor */
@@ -910,7 +934,7 @@ output_interface_prototype(FILE* outf,
*/
static int
output_interface_elipsis_operation(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -953,7 +977,7 @@ output_interface_elipsis_operation(FILE* outf,
*/
static int
output_interface_overloaded_operation(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -992,7 +1016,7 @@ output_interface_overloaded_operation(FILE* outf,
*/
static int
output_interface_special_operation(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
/* special method definition */
@@ -1077,7 +1101,7 @@ output_operation_optional_defaults(FILE* outf,
static int
output_operation_argument_type_check(
FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_operation_entry *operatione,
struct ir_operation_overload_entry *overloade,
int argidx)
@@ -1168,7 +1192,7 @@ output_operation_argument_type_check(
*/
static int
output_interface_operation(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -1287,15 +1311,16 @@ output_interface_operation(FILE* outf,
* generate class methods for each interface operation
*/
static int
-output_interface_operations(FILE* outf, struct ir_interface_entry *interfacee)
+output_interface_operations(FILE* outf, struct ir_entry *ife)
{
int opc;
int res = 0;
- for (opc = 0; opc < interfacee->operationc; opc++) {
- res = output_interface_operation(outf,
- interfacee,
- interfacee->operationv + opc);
+ for (opc = 0; opc < ife->u.interface.operationc; opc++) {
+ res = output_interface_operation(
+ outf,
+ ife,
+ ife->u.interface.operationv + opc);
if (res != 0) {
break;
}
@@ -1309,7 +1334,7 @@ output_interface_operations(FILE* outf, struct ir_interface_entry
*interfacee)
*/
static int
output_interface_attribute(FILE* outf,
- struct ir_interface_entry *interfacee,
+ struct ir_entry *interfacee,
struct ir_attribute_entry *atributee)
{
int cdatac;
@@ -1369,15 +1394,15 @@ output_interface_attribute(FILE* outf,
* generate class property getters and setters for each interface attribute
*/
static int
-output_interface_attributes(FILE* outf,
- struct ir_interface_entry *interfacee)
+output_interface_attributes(FILE* outf, struct ir_entry *ife)
{
int attrc;
- for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- output_interface_attribute(outf,
- interfacee,
- interfacee->attributev + attrc);
+ for (attrc = 0; attrc < ife->u.interface.attributec; attrc++) {
+ output_interface_attribute(
+ outf,
+ ife,
+ ife->u.interface.attributev + attrc);
}
return 0;
@@ -1407,29 +1432,110 @@ static int output_tool_prologue(FILE* outf)
}
/**
- * generate a source file to implement an interface using duk and libdom.
+ * generate a source file to implement a dictionary using duk and libdom.
*/
-static int output_interface(struct ir *ir,
- struct ir_interface_entry *interfacee)
+static int output_dictionary(struct ir *ir, struct ir_entry *dictionarye)
{
FILE *ifacef;
- int ifacenamelen;
- struct ir_interface_entry *inherite;
+ struct ir_entry *inherite;
int res = 0;
- /* do not generate class for interfaces marked no output */
- if (interfacee->noobject) {
- return 0;
+ /* open output file */
+ ifacef = genb_fopen_tmp(dictionarye->filename);
+ if (ifacef == NULL) {
+ return -1;
+ }
+
+ /* find parent interface entry */
+ inherite = ir_inherit_entry(ir, dictionarye);
+
+ /* tool preface */
+ output_tool_preface(ifacef);
+
+ /* binding preface */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
+
+ /* class preface */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_PREFACE);
+
+ /* tool prologue */
+ output_tool_prologue(ifacef);
+
+ /* binding prologue */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_PROLOGUE);
+
+ /* class prologue */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_PROLOGUE);
+
+ fprintf(ifacef, "\n");
+
+ /* initialisor */
+ res = output_interface_init(ifacef, dictionarye, inherite);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* finaliser */
+ res = output_interface_fini(ifacef, dictionarye, inherite);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* constructor */
+ res = output_interface_constructor(ifacef, dictionarye);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* destructor */
+ res = output_interface_destructor(ifacef, dictionarye);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* prototype */
+ res = output_interface_prototype(ifacef, ir, dictionarye, inherite);
+ if (res != 0) {
+ goto op_error;
}
- /* compute class name */
- interfacee->class_name = gen_class_name(interfacee);
- /* generate source filename */
- ifacenamelen = strlen(interfacee->class_name) + 4;
- interfacee->filename = malloc(ifacenamelen);
- snprintf(interfacee->filename, ifacenamelen,
- "%s.c", interfacee->class_name);
+ fprintf(ifacef, "\n");
+
+ /* class epilogue */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_EPILOGUE);
+
+ /* binding epilogue */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_EPILOGUE);
+
+ /* class postface */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_POSTFACE);
+
+ /* binding postface */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
+
+op_error:
+ genb_fclose_tmp(ifacef, dictionarye->filename);
+
+ return res;
+}
+
+/**
+ * generate a source file to implement an interface using duk and libdom.
+ */
+static int output_interface(struct ir *ir, struct ir_entry *interfacee)
+{
+ FILE *ifacef;
+ struct ir_entry *inherite;
+ int res = 0;
/* open output file */
ifacef = genb_fopen_tmp(interfacee->filename);
@@ -1486,7 +1592,7 @@ static int output_interface(struct ir *ir,
output_interface_attributes(ifacef, interfacee);
/* prototype */
- output_interface_prototype(ifacef, interfacee, inherite, ir);
+ output_interface_prototype(ifacef, ir, interfacee, inherite);
fprintf(ifacef, "\n");
@@ -1524,25 +1630,39 @@ output_private_header(struct ir *ir)
/* open header */
privf = open_header(ir, "private");
- for (idx = 0; idx < ir->interfacec; idx++) {
- struct ir_interface_entry *interfacee;
- struct ir_interface_entry *inherite;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
+ struct ir_entry *inherite;
struct genbind_node *priv_node;
- interfacee = ir->interfaces + idx;
+ interfacee = ir->entries + idx;
/* do not generate private structs for interfaces marked no
* output
*/
- if (interfacee->noobject) {
+ if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) &&
+ (interfacee->u.interface.noobject)) {
continue;
}
- /* find parent interface entry */
- inherite = ir_inherit_entry(ir,
- interfacee);
+ switch (interfacee->type) {
+ case IR_ENTRY_TYPE_INTERFACE:
+ fprintf(privf,
+ "/* Private data for %s interface */\n",
+ interfacee->name);
+ break;
+
+ case IR_ENTRY_TYPE_DICTIONARY:
+ fprintf(privf,
+ "/* Private data for %s dictionary */\n",
+ interfacee->name);
+ break;
+ }
fprintf(privf, "typedef struct {\n");
+
+ /* find parent entry and include in private */
+ inherite = ir_inherit_entry(ir, interfacee);
if (inherite != NULL) {
fprintf(privf, "\t%s_private_t parent;\n",
inherite->class_name);
@@ -1602,16 +1722,17 @@ output_prototype_header(struct ir *ir)
/* open header */
protof = open_header(ir, "prototype");
- for (idx = 0; idx < ir->interfacec; idx++) {
- struct ir_interface_entry *interfacee;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
struct genbind_node *init_node;
- interfacee = ir->interfaces + idx;
+ interfacee = ir->entries + idx;
/* do not generate prototype declarations for interfaces marked
* no output
*/
- if (interfacee->noobject) {
+ if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) &&
+ (interfacee->u.interface.noobject)) {
continue;
}
@@ -1664,13 +1785,14 @@ output_makefile(struct ir *ir)
fprintf(makef, "# duk libdom makefile fragment\n\n");
fprintf(makef, "NSGENBIND_SOURCES:=binding.c ");
- for (idx = 0; idx < ir->interfacec; idx++) {
- struct ir_interface_entry *interfacee;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
- interfacee = ir->interfaces + idx;
+ interfacee = ir->entries + idx;
/* no source for interfaces marked no output */
- if (interfacee->noobject) {
+ if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) &&
+ (interfacee->u.interface.noobject)) {
continue;
}
@@ -1752,7 +1874,7 @@ output_binding_src(struct ir *ir)
{
int idx;
FILE *bindf;
- struct ir_interface_entry *pglobale = NULL;
+ struct ir_entry *pglobale = NULL;
char *proto_name;
/* open output file */
@@ -1893,23 +2015,24 @@ output_binding_src(struct ir *ir)
fprintf(bindf, "{\n");
- for (idx = 0; idx < ir->interfacec; idx++) {
- struct ir_interface_entry *interfacee;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
- interfacee = ir->interfaces + idx;
+ interfacee = ir->entries + idx;
/* do not generate prototype calls for interfaces marked
* no output
*/
- if (interfacee->noobject) {
- continue;
- }
+ if (interfacee->type == IR_ENTRY_TYPE_INTERFACE) {
+ if (interfacee->u.interface.noobject) {
+ continue;
+ }
- if (interfacee->primary_global) {
- pglobale = interfacee;
- continue;
+ if (interfacee->u.interface.primary_global) {
+ pglobale = interfacee;
+ continue;
+ }
}
-
proto_name = get_prototype_name(interfacee->name);
fprintf(bindf,
@@ -1951,20 +2074,76 @@ output_binding_src(struct ir *ir)
return 0;
}
+static int output_interfaces_dictionaries(struct ir *ir)
+{
+ int res;
+ int idx;
+
+ /* generate interfaces */
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *irentry;
+
+ irentry = ir->entries + idx;
+
+ switch (irentry->type) {
+ case IR_ENTRY_TYPE_INTERFACE:
+ /* do not generate class for interfaces marked no
+ * output
+ */
+ if (!irentry->u.interface.noobject) {
+ res = output_interface(ir, irentry);
+ if (res != 0) {
+ return res;
+ }
+ }
+ break;
+
+ case IR_ENTRY_TYPE_DICTIONARY:
+ res = output_dictionary(ir, irentry);
+ if (res != 0) {
+ return res;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+}
+
int duk_libdom_output(struct ir *ir)
{
int idx;
int res = 0;
- /* generate interfaces */
- for (idx = 0; idx < ir->interfacec; idx++) {
- res = output_interface(ir,
- ir->interfaces + idx);
- if (res != 0) {
- goto output_err;
+ /* process ir entries for output */
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *irentry;
+
+ irentry = ir->entries + idx;
+
+ /* compute class name */
+ irentry->class_name = gen_class_name(irentry);
+
+ if (irentry->class_name != NULL) {
+ int ifacenamelen;
+
+ /* generate source filename */
+ ifacenamelen = strlen(irentry->class_name) + 4;
+ irentry->filename = malloc(ifacenamelen);
+ snprintf(irentry->filename,
+ ifacenamelen,
+ "%s.c",
+ irentry->class_name);
}
}
+ res = output_interfaces_dictionaries(ir);
+ if (res != 0) {
+ goto output_err;
+ }
+
/* generate private header */
res = output_private_header(ir);
if (res != 0) {
diff --git a/src/ir.c b/src/ir.c
index ab2add7..3a2a1c8 100644
--- a/src/ir.c
+++ b/src/ir.c
@@ -49,7 +49,7 @@ enumerate_interface_type(struct webidl_node *interface_node,
* binding also maintain refcounts
*/
static void
-compute_inherit_refcount(struct ir_interface_entry *entries, int entryc)
+compute_inherit_refcount(struct ir_entry *entries, int entryc)
{
int idx;
int inf;
@@ -81,14 +81,14 @@ compute_inherit_refcount(struct ir_interface_entry *entries, int
entryc)
* reduce refcount on inherit index if !=-1
* remove entry from source map
*/
-static struct ir_interface_entry *
-interface_topoligical_sort(struct ir_interface_entry *srcinf, int infc)
+static struct ir_entry *
+entry_topoligical_sort(struct ir_entry *srcinf, int infc)
{
- struct ir_interface_entry *dstinf;
+ struct ir_entry *dstinf;
int idx;
int inf;
- dstinf = calloc(infc, sizeof(struct ir_interface_entry));
+ dstinf = calloc(infc, sizeof(struct ir_entry));
if (dstinf == NULL) {
return NULL;
}
@@ -110,15 +110,9 @@ interface_topoligical_sort(struct ir_interface_entry *srcinf, int
infc)
dstinf[idx].name = srcinf[inf].name;
dstinf[idx].node = srcinf[inf].node;
dstinf[idx].inherit_name = srcinf[inf].inherit_name;
- dstinf[idx].noobject = srcinf[inf].noobject;
- dstinf[idx].primary_global = srcinf[inf].primary_global;
- dstinf[idx].operationc = srcinf[inf].operationc;
- 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;
+ dstinf[idx].type = srcinf[inf].type;
+ dstinf[idx].u = srcinf[inf].u;
/* reduce refcount on inherit index if !=-1 */
if (srcinf[inf].inherit_idx != -1) {
@@ -553,50 +547,69 @@ constant_map_new(struct webidl_node *interface,
return 0;
}
-int ir_new(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct ir **map_out)
+static int
+entry_map_new(struct genbind_node *genbind,
+ struct webidl_node *interface,
+ int *interfacec_out,
+ struct ir_entry **interfacev_out)
{
int interfacec;
- struct ir_interface_entry *entries;
- struct ir_interface_entry *sorted_entries;
- struct ir_interface_entry *ecur;
+ int dictionaryc;
+ int entryc;
+ struct ir_entry *entries;
+ struct ir_entry *sorted_entries;
+ struct ir_entry *cure;
struct webidl_node *node;
- struct ir *map;
-
- interfacec = webidl_node_enumerate_type(webidl,
- WEBIDL_NODE_TYPE_INTERFACE);
+ interfacec = webidl_node_enumerate_type(interface,
+ WEBIDL_NODE_TYPE_INTERFACE);
+ dictionaryc = webidl_node_enumerate_type(interface,
+ WEBIDL_NODE_TYPE_DICTIONARY);
if (options->verbose) {
printf("Mapping %d interfaces\n", interfacec);
+ printf("Mapping %d dictionaries\n", dictionaryc);
}
- entries = calloc(interfacec, sizeof(struct ir_interface_entry));
+ entryc = interfacec + dictionaryc;
+
+ entries = calloc(entryc, sizeof(struct ir_entry));
if (entries == NULL) {
return -1;
}
/* for each interface populate an entry in the map */
- ecur = entries;
- node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
+ cure = entries;
+ node = webidl_node_find_type(interface,
+ NULL,
+ WEBIDL_NODE_TYPE_INTERFACE);
while (node != NULL) {
/* fill map entry */
- ecur->node = node;
+ cure->node = node;
/* name of interface */
- ecur->name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
/* name of the inherited interface (if any) */
- ecur->inherit_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(node),
+ cure->inherit_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_INHERITANCE));
+
+ /* matching class from binding */
+ cure->class = genbind_node_find_type_ident(
+ genbind,
NULL,
- WEBIDL_NODE_TYPE_INHERITANCE));
+ GENBIND_NODE_TYPE_CLASS,
+ cure->name);
+
+ /* identify this is an interface entry */
+ cure->type = IR_ENTRY_TYPE_INTERFACE;
/* is the interface marked as not generating an object */
if (webidl_node_find_type_ident(
@@ -607,7 +620,7 @@ int ir_new(struct genbind_node *genbind,
* cannot form part of an inheritance chain if it is
* not generating an output class
*/
- ecur->noobject = true;
+ cure->u.interface.noobject = true;
}
/* is the interface marked as the primary global */
@@ -619,189 +632,262 @@ int ir_new(struct genbind_node *genbind,
* class or all hell will break loose having two
* primary globals.
*/
- ecur->primary_global = true;
+ cure->u.interface.primary_global = true;
}
- /* matching class from binding */
- ecur->class = genbind_node_find_type_ident(genbind,
- NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
-
/* enumerate and map the interface operations */
operation_map_new(node,
- ecur->class,
- &ecur->operationc,
- &ecur->operationv);
+ cure->class,
+ &cure->u.interface.operationc,
+ &cure->u.interface.operationv);
/* enumerate and map the interface attributes */
attribute_map_new(node,
- ecur->class,
- &ecur->attributec,
- &ecur->attributev);
+ cure->class,
+ &cure->u.interface.attributec,
+ &cure->u.interface.attributev);
/* enumerate and map the interface constants */
constant_map_new(node,
- &ecur->constantc,
- &ecur->constantv);
+ &cure->u.interface.constantc,
+ &cure->u.interface.constantv);
/* move to next interface */
- node = webidl_node_find_type(webidl, node,
+ node = webidl_node_find_type(interface,
+ node,
WEBIDL_NODE_TYPE_INTERFACE);
- ecur++;
+ cure++;
+ }
+
+ /* for each dictionary populate an entry in the map */
+ node = webidl_node_find_type(interface,
+ NULL,
+ WEBIDL_NODE_TYPE_DICTIONARY);
+ while (node != NULL) {
+
+ /* fill map entry */
+ cure->node = node;
+
+ /* name of interface */
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ /* name of the inherited interface (if any) */
+ cure->inherit_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_INHERITANCE));
+
+ /* matching class from binding */
+ cure->class = genbind_node_find_type_ident(
+ genbind,
+ NULL,
+ GENBIND_NODE_TYPE_CLASS,
+ cure->name);
+
+ /* identify this is an interface entry */
+ cure->type = IR_ENTRY_TYPE_DICTIONARY;
+
+
+
+
+ /* move to next interface */
+ node = webidl_node_find_type(interface,
+ node,
+ WEBIDL_NODE_TYPE_DICTIONARY);
+ cure++;
}
/* compute inheritance and refcounts on map */
- compute_inherit_refcount(entries, interfacec);
+ compute_inherit_refcount(entries, entryc);
- /* sort interfaces to ensure correct ordering */
- sorted_entries = interface_topoligical_sort(entries, interfacec);
+ /* sort entries to ensure correct ordering */
+ sorted_entries = entry_topoligical_sort(entries, entryc);
free(entries);
if (sorted_entries == NULL) {
return -1;
}
/* compute inheritance and refcounts on sorted map */
- compute_inherit_refcount(sorted_entries, interfacec);
+ compute_inherit_refcount(sorted_entries, entryc);
+
+ *interfacec_out = entryc;
+ *interfacev_out = sorted_entries;
+
+ return 0;
+}
+
+
+int ir_new(struct genbind_node *genbind,
+ struct webidl_node *webidl,
+ struct ir **map_out)
+{
+ struct ir *map;
+ int ret;
map = malloc(sizeof(struct ir));
- map->interfacec = interfacec;
- map->interfaces = sorted_entries;
+ if (map == NULL) {
+ return -1;
+ }
+
map->webidl = webidl;
map->binding_node = genbind_node_find_type(genbind, NULL,
GENBIND_NODE_TYPE_BINDING);
+ /* interfaces */
+ ret = entry_map_new(genbind,
+ webidl,
+ &map->entryc,
+ &map->entries);
+ if (ret != 0) {
+ free(map);
+ return ret;
+ }
+
*map_out = map;
return 0;
}
-int ir_dump(struct ir *index)
+static int ir_dump_interface(FILE *dumpf, struct ir_entry *ecur)
{
- FILE *dumpf;
- int eidx;
- struct ir_interface_entry *ecur;
+ if (ecur->u.interface.operationc > 0) {
+ int opc;
- /* only dump AST to file if required */
- if (!options->debug) {
- return 0;
- }
+ fprintf(dumpf, "\t%d operations\n",
+ ecur->u.interface.operationc);
- dumpf = genb_fopen("interface-map", "w");
- if (dumpf == NULL) {
- return 2;
- }
+ for (opc = 0; opc < ecur->u.interface.operationc; opc++) {
+ int ovlc;
+ struct ir_operation_entry *ope;
- ecur = index->interfaces;
- for (eidx = 0; eidx < index->interfacec; eidx++) {
- fprintf(dumpf, "%d %s\n", eidx, ecur->name);
- if (ecur->inherit_name != NULL) {
- fprintf(dumpf, "\tinherit:%s\n",
ecur->inherit_name);
- }
- if (ecur->class != NULL) {
- fprintf(dumpf, "\tclass:%p\n", ecur->class);
- }
+ ope = ecur->u.interface.operationv + opc;
- if (ecur->operationc > 0) {
- int opc;
-
- fprintf(dumpf, "\t%d operations\n",
- ecur->operationc);
-
- for (opc = 0; opc < ecur->operationc; opc++) {
- int ovlc;
- struct ir_operation_entry *ope;
-
- ope = ecur->operationv + opc;
+ fprintf(dumpf,
+ "\t\t%s\n",
+ ope->name);
+ fprintf(dumpf,
+ "\t\t\tmethod:%p\n",
+ ope->method);
+ for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
+ int argc;
+ struct ir_operation_overload_entry *ovle;
+ ovle = ope->overloadv + ovlc;
fprintf(dumpf,
- "\t\t%s\n",
- ope->name);
+ "\t\t\toverload:%d\n", ovlc);
+
fprintf(dumpf,
- "\t\t\tmethod:%p\n",
- ope->method);
- for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
- int argc;
- struct ir_operation_overload_entry *ovle;
- ovle = ope->overloadv + ovlc;
+ "\t\t\t\treturn type:%p\n",
+ ovle->type);
- fprintf(dumpf,
- "\t\t\toverload:%d\n", ovlc);
+ fprintf(dumpf,
+ "\t\t\t\targuments:%d\n",
+ ovle->argumentc);
- fprintf(dumpf,
- "\t\t\t\treturn type:%p\n",
- ovle->type);
+ fprintf(dumpf,
+ "\t\t\t\toptionals:%d\n",
+ ovle->optionalc);
- fprintf(dumpf,
- "\t\t\t\targuments:%d\n",
- ovle->argumentc);
+ fprintf(dumpf,
+ "\t\t\t\telipsis:%d\n",
+ ovle->elipsisc);
- fprintf(dumpf,
- "\t\t\t\toptionals:%d\n",
- ovle->optionalc);
+ for (argc = 0; argc < ovle->argumentc; argc++) {
+ struct ir_operation_argument_entry *arge;
+ arge = ovle->argumentv + argc;
fprintf(dumpf,
- "\t\t\t\telipsis:%d\n",
- ovle->elipsisc);
-
- for (argc = 0; argc < ovle->argumentc;
argc++) {
- struct ir_operation_argument_entry
*arge;
- arge = ovle->argumentv + argc;
+ "\t\t\t\t\t%s\n",
+ arge->name);
+ if (arge->optionalc != 0) {
fprintf(dumpf,
- "\t\t\t\t\t%s\n",
- arge->name);
-
- if (arge->optionalc != 0) {
- fprintf(dumpf,
-
"\t\t\t\t\t\toptional:%d\n",
- arge->optionalc);
- }
-
- if (arge->elipsisc != 0) {
- fprintf(dumpf,
-
"\t\t\t\t\t\telipsis:%d\n",
- arge->elipsisc);
- }
+
"\t\t\t\t\t\toptional:%d\n",
+ arge->optionalc);
+ }
+ if (arge->elipsisc != 0) {
+ fprintf(dumpf,
+
"\t\t\t\t\t\telipsis:%d\n",
+ arge->elipsisc);
}
+
}
}
}
+ }
- if (ecur->attributec > 0) {
- int attrc = ecur->attributec;
- struct ir_attribute_entry *attre;
-
- fprintf(dumpf, "\t%d attributes\n", attrc);
-
- attre = ecur->attributev;
- while (attre != NULL) {
- fprintf(dumpf, "\t\t%s %p",
- attre->name,
- attre->getter);
- if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
- fprintf(dumpf, " %p\n",
attre->setter);
- } else {
- fprintf(dumpf, "\n");
- }
- attre++;
- attrc--;
- if (attrc == 0) {
- break;
- }
+ if (ecur->u.interface.attributec > 0) {
+ int attrc = ecur->u.interface.attributec;
+ struct ir_attribute_entry *attre;
+
+ fprintf(dumpf, "\t%d attributes\n", attrc);
+
+ attre = ecur->u.interface.attributev;
+ while (attre != NULL) {
+ fprintf(dumpf, "\t\t%s %p",
+ attre->name,
+ attre->getter);
+ if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
+ fprintf(dumpf, " %p\n", attre->setter);
+ } else {
+ fprintf(dumpf, "\n");
+ }
+ attre++;
+ attrc--;
+ if (attrc == 0) {
+ break;
}
}
- if (ecur->constantc > 0) {
- int idx;
+ }
+ if (ecur->u.interface.constantc > 0) {
+ int idx;
- fprintf(dumpf, "\t%d constants\n",
- ecur->constantc);
+ fprintf(dumpf, "\t%d constants\n",
+ ecur->u.interface.constantc);
- for (idx = 0; idx < ecur->constantc; idx++) {
- struct ir_constant_entry *cone;
- cone = ecur->constantv + idx;
- fprintf(dumpf, "\t\t%s\n",
- cone->name);
- }
+ for (idx = 0; idx < ecur->u.interface.constantc; idx++) {
+ struct ir_constant_entry *cone;
+ cone = ecur->u.interface.constantv + idx;
+ fprintf(dumpf, "\t\t%s\n", cone->name);
+ }
+ }
+ return 0;
+}
+
+int ir_dump(struct ir *ir)
+{
+ FILE *dumpf;
+ int eidx;
+ struct ir_entry *ecur;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("ir-map", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ ecur = ir->entries;
+ for (eidx = 0; eidx < ir->entryc; eidx++) {
+ fprintf(dumpf, "%d %s\n", eidx, ecur->name);
+ if (ecur->inherit_name != NULL) {
+ fprintf(dumpf, "\tinherit:%s\n",
ecur->inherit_name);
+ }
+ if (ecur->class != NULL) {
+ fprintf(dumpf, "\tclass:%p\n", ecur->class);
+ }
+
+ if (ecur->type == IR_ENTRY_TYPE_INTERFACE) {
+ ir_dump_interface(dumpf, ecur);
}
ecur++;
}
@@ -815,14 +901,14 @@ int ir_dumpdot(struct ir *index)
{
FILE *dumpf;
int eidx;
- struct ir_interface_entry *ecur;
+ struct ir_entry *ecur;
/* only dump AST to file if required */
if (!options->debug) {
return 0;
}
- dumpf = genb_fopen("interface.dot", "w");
+ dumpf = genb_fopen("ir.dot", "w");
if (dumpf == NULL) {
return 2;
}
@@ -831,25 +917,27 @@ int ir_dumpdot(struct ir *index)
fprintf(dumpf, "node [shape=box]\n");
- ecur = index->interfaces;
- for (eidx = 0; eidx < index->interfacec; eidx++) {
+ ecur = index->entries;
+ for (eidx = 0; eidx < index->entryc; eidx++) {
fprintf(dumpf, "%04d [label=\"%s\"", eidx,
ecur->name);
- if (ecur->noobject == true) {
+ if ((ecur == IR_ENTRY_TYPE_INTERFACE) &&
+ (ecur->u.interface.noobject == true)) {
/* noobject interfaces in red */
fprintf(dumpf, "fontcolor=\"red\"");
} else if (ecur->class != NULL) {
/* interfaces bound to a class are shown in blue */
fprintf(dumpf, "fontcolor=\"blue\"");
}
+
fprintf(dumpf, "];\n");
ecur++;
}
- ecur = index->interfaces;
- for (eidx = 0; eidx < index->interfacec; eidx++) {
- if (index->interfaces[eidx].inherit_idx != -1) {
+ ecur = index->entries;
+ for (eidx = 0; eidx < index->entryc; eidx++) {
+ if (index->entries[eidx].inherit_idx != -1) {
fprintf(dumpf, "%04d -> %04d;\n",
- eidx, index->interfaces[eidx].inherit_idx);
+ eidx, index->entries[eidx].inherit_idx);
}
}
@@ -860,15 +948,15 @@ int ir_dumpdot(struct ir *index)
return 0;
}
-struct ir_interface_entry *
+struct ir_entry *
ir_inherit_entry(struct ir *map,
- struct ir_interface_entry *entry)
+ struct ir_entry *entry)
{
- struct ir_interface_entry *res = NULL;
+ struct ir_entry *res = NULL;
if ((entry != NULL) &&
(entry->inherit_idx != -1)) {
- res = &map->interfaces[entry->inherit_idx];
+ res = &map->entries[entry->inherit_idx];
}
return res;
}
diff --git a/src/ir.h b/src/ir.h
index 4d0365e..cf431f6 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -60,17 +60,9 @@ struct ir_constant_entry {
struct webidl_node *node; /**< AST constant node */
};
+
/** map entry for an interface */
struct ir_interface_entry {
- const char *name; /** interface name */
- struct webidl_node *node; /**< AST interface node */
- const char *inherit_name; /**< Name of interface inhertited from */
- int inherit_idx; /**< index into map of inherited interface or -1 for
- * not in map
- */
- int refcount; /**< number of interfacess in map that refer to this
- * interface
- */
bool noobject; /**< flag indicating if no interface object should eb
* generated. This allows for interfaces which do not
* generate code. For implements (mixin) interfaces
@@ -87,12 +79,39 @@ struct ir_interface_entry {
int constantc; /**< number of constants on interface */
struct ir_constant_entry *constantv;
+};
+/** map entry for a dictionary */
+struct ir_dictionary_entry {
+};
+
+enum ir_entry_type {
+ IR_ENTRY_TYPE_INTERFACE,
+ IR_ENTRY_TYPE_DICTIONARY,
+};
+/** top level entry info common to interfaces and dictionaries */
+struct ir_entry {
+ const char *name; /** dictionary name */
+ struct webidl_node *node; /**< AST dictionary node */
+ const char *inherit_name; /**< Name of interface inhertited from */
struct genbind_node *class; /**< class from binding (if any) */
+ enum ir_entry_type type;
+ union {
+ struct ir_dictionary_entry dictionary;
+ struct ir_interface_entry interface;
+ } u;
+
+ int inherit_idx; /**< index into map of inherited interface or -1 for
+ * not in map
+ */
+ int refcount; /**< number of interfacess in map that refer to this
+ * interface
+ */
+
/* The variables are created and used by the output generation but
- * rtaher than have another allocation and pointer the data they are
+ * rather than have another allocation and pointer the data they are
* just inline here.
*/
@@ -108,20 +127,10 @@ struct ir_interface_entry {
*/
};
-/** map entry for a dictionary */
-struct ir_dictionary_entry {
- const char *name; /** dictionary name */
- struct webidl_node *node; /**< AST dictionary node */
- const char *inherit_name; /**< Name of interface inhertited from */
-};
-
/** intermediate representation of WebIDL and binding data */
struct ir {
- int interfacec; /**< count of interfaces */
- struct ir_interface_entry *interfaces; /**< interface entries */
-
- int dictionaryc; /**< count of dictionaries */
- struct ir_dictionary_entry *dictionaries; /**< dictionary entries */
+ int entryc; /**< count of entries */
+ struct ir_entry *entries; /**< interface entries */
/** The AST node of the binding information */
struct genbind_node *binding_node;
@@ -146,6 +155,6 @@ int ir_dumpdot(struct ir *map);
*
* \return inherit entry or NULL if there is not one
*/
-struct ir_interface_entry *ir_inherit_entry(struct ir *map, struct ir_interface_entry
*entry);
+struct ir_entry *ir_inherit_entry(struct ir *map, struct ir_entry *entry);
#endif
commitdiff
http://git.netsurf-browser.org/nsgenbind.git/commit/?id=e8d19a2821bfd15bc...
commit e8d19a2821bfd15bcbe8d17f6564439c1673cbf7
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
rename interface map to be intermediate representation
The interface map is now completely inapropriately named and is in
fact now an intermediate representation of the webidl and bindings
kept in a sorted order.
diff --git a/src/Makefile b/src/Makefile
index 8b034fe..9905baf 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,8 +1,8 @@
CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/ -g -DYYENABLE_NLS=0
# Sources in this directory
-DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.c \
- interface-map.c duk-libdom.c
+DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.c ir.c \
+ duk-libdom.c
# jsapi-libdom.c jsapi-libdom-function.c jsapi-libdom-property.c jsapi-libdom-init.c
jsapi-libdom-new.c jsapi-libdom-infmap.c jsapi-libdom-jsclass.c
SOURCES := $(SOURCES) $(BUILDDIR)/nsgenbind-parser.c $(BUILDDIR)/nsgenbind-lexer.c
$(BUILDDIR)/webidl-parser.c $(BUILDDIR)/webidl-lexer.c
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index aad7bb6..046f741 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -19,7 +19,7 @@
#include "utils.h"
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
-#include "interface-map.h"
+#include "ir.h"
#include "duk-libdom.h"
/** prefix for all generated functions */
@@ -293,7 +293,7 @@ static int output_tool_preface(FILE* outf)
* - if the previous character in the input name was uppercase and the current
* one is lowercase insert an underscore before the *previous* character.
*/
-static char *gen_class_name(struct interface_map_entry *interfacee)
+static char *gen_class_name(struct ir_interface_entry *interfacee)
{
const char *inc;
char *outc;
@@ -373,7 +373,7 @@ output_cdata(FILE* outf,
return res;
}
-static FILE *open_header(struct interface_map *interface_map, const char *name)
+static FILE *open_header(struct ir *ir, const char *name)
{
FILE *hdrf;
char *fname;
@@ -392,7 +392,7 @@ static FILE *open_header(struct interface_map *interface_map, const
char *name)
/* binding preface */
output_cdata(hdrf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PREFACE);
/* tool preface */
@@ -405,7 +405,7 @@ static FILE *open_header(struct interface_map *interface_map, const
char *name)
return hdrf;
}
-static int close_header(struct interface_map *interface_map,
+static int close_header(struct ir *ir,
FILE *hdrf,
const char *name)
{
@@ -420,7 +420,7 @@ static int close_header(struct interface_map *interface_map,
/* binding postface */
output_cdata(hdrf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_POSTFACE);
genb_fclose_tmp(hdrf, fname);
@@ -434,7 +434,7 @@ static int close_header(struct interface_map *interface_map,
* generate the interface constructor
*/
static int
-output_interface_constructor(FILE* outf, struct interface_map_entry *interfacee)
+output_interface_constructor(FILE* outf, struct ir_interface_entry *interfacee)
{
int init_argc;
@@ -470,7 +470,7 @@ output_interface_constructor(FILE* outf, struct interface_map_entry
*interfacee)
* generate the interface destructor
*/
static int
-output_interface_destructor(FILE* outf, struct interface_map_entry *interfacee)
+output_interface_destructor(FILE* outf, struct ir_interface_entry *interfacee)
{
/* destructor definition */
fprintf(outf,
@@ -498,8 +498,8 @@ output_interface_destructor(FILE* outf, struct interface_map_entry
*interfacee)
*/
static int
output_interface_inherit_init(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+ struct ir_interface_entry *interfacee,
+ struct ir_interface_entry *inherite)
{
struct genbind_node *init_node;
struct genbind_node *inh_init_node;
@@ -593,7 +593,7 @@ output_interface_inherit_init(FILE* outf,
static int
output_interface_init_declaration(FILE* outf,
- struct interface_map_entry *interfacee,
+ struct ir_interface_entry *interfacee,
struct genbind_node *init_node)
{
struct genbind_node *param_node;
@@ -627,8 +627,8 @@ output_interface_init_declaration(FILE* outf,
static int
output_interface_init(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+ struct ir_interface_entry *interfacee,
+ struct ir_interface_entry *inherite)
{
struct genbind_node *init_node;
int res;
@@ -666,8 +666,8 @@ output_interface_init(FILE* outf,
static int
output_interface_fini(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+ struct ir_interface_entry *interfacee,
+ struct ir_interface_entry *inherite)
{
struct genbind_node *fini_node;
@@ -708,8 +708,8 @@ output_interface_fini(FILE* outf,
*/
static int
output_prototype_method(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_interface_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
if (operatione->name != NULL) {
@@ -730,7 +730,7 @@ output_prototype_method(FILE* outf,
* generate prototype method definitions
*/
static int
-output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
+output_prototype_methods(FILE *outf, struct ir_interface_entry *interfacee)
{
int opc;
int res = 0;
@@ -750,8 +750,8 @@ output_prototype_methods(FILE *outf, struct interface_map_entry
*interfacee)
static int
output_prototype_attribute(FILE *outf,
- struct interface_map_entry *interfacee,
- struct interface_map_attribute_entry *attributee)
+ struct ir_interface_entry *interfacee,
+ struct ir_attribute_entry *attributee)
{
if (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
return output_populate_ro_property(outf,
@@ -767,7 +767,7 @@ output_prototype_attribute(FILE *outf,
* generate prototype attribute definitions
*/
static int
-output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
+output_prototype_attributes(FILE *outf, struct ir_interface_entry *interfacee)
{
int attrc;
int res = 0;
@@ -791,7 +791,7 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry
*interfacee)
*/
static int
output_prototype_constant(FILE *outf,
- struct interface_map_constant_entry *constante)
+ struct ir_constant_entry *constante)
{
int *value;
@@ -810,7 +810,7 @@ output_prototype_constant(FILE *outf,
* generate prototype constant definitions
*/
static int
-output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
+output_prototype_constants(FILE *outf, struct ir_interface_entry *interfacee)
{
int attrc;
int res = 0;
@@ -831,9 +831,9 @@ output_prototype_constants(FILE *outf, struct interface_map_entry
*interfacee)
*/
static int
output_interface_prototype(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite,
- struct interface_map *interface_map)
+ struct ir_interface_entry *interfacee,
+ struct ir_interface_entry *inherite,
+ struct ir *ir)
{
struct genbind_node *proto_node;
@@ -874,10 +874,10 @@ output_interface_prototype(FILE* outf,
*/
if (interfacee->primary_global) {
fprintf(outf, "\t/* Create interface objects */\n");
- for (int idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacep;
+ for (int idx = 0; idx < ir->interfacec; idx++) {
+ struct ir_interface_entry *interfacep;
- interfacep = interface_map->entries + idx;
+ interfacep = ir->interfaces + idx;
if (interfacep->noobject) continue;
if (interfacep == interfacee)
fprintf(outf, "\tduk_dup(ctx, 0);\n");
@@ -910,8 +910,8 @@ output_interface_prototype(FILE* outf,
*/
static int
output_interface_elipsis_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_interface_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -953,8 +953,8 @@ output_interface_elipsis_operation(FILE* outf,
*/
static int
output_interface_overloaded_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_interface_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -992,8 +992,8 @@ output_interface_overloaded_operation(FILE* outf,
*/
static int
output_interface_special_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_interface_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
/* special method definition */
fprintf(outf, "/* Special method definition - UNIMPLEMENTED */\n\n");
@@ -1011,12 +1011,12 @@ output_interface_special_operation(FILE* outf,
*/
static int
output_operation_optional_defaults(FILE* outf,
- struct interface_map_operation_argument_entry *argumentv,
+ struct ir_operation_argument_entry *argumentv,
int argumentc)
{
int argc;
for (argc = 0; argc < argumentc; argc++) {
- struct interface_map_operation_argument_entry *cure;
+ struct ir_operation_argument_entry *cure;
struct webidl_node *lit_node; /* literal node */
enum webidl_node_type lit_type;
int *lit_int;
@@ -1077,12 +1077,12 @@ output_operation_optional_defaults(FILE* outf,
static int
output_operation_argument_type_check(
FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione,
- struct interface_map_operation_overload_entry *overloade,
+ struct ir_interface_entry *interfacee,
+ struct ir_operation_entry *operatione,
+ struct ir_operation_overload_entry *overloade,
int argidx)
{
- struct interface_map_operation_argument_entry *argumente;
+ struct ir_operation_argument_entry *argumente;
struct webidl_node *type_node;
enum webidl_type *argument_type;
@@ -1168,11 +1168,11 @@ output_operation_argument_type_check(
*/
static int
output_interface_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_interface_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
- struct interface_map_operation_overload_entry *overloade;
+ struct ir_operation_overload_entry *overloade;
int fixedargc; /* number of non optional arguments */
int argidx; /* loop counter for arguments */
int optargc; /* loop counter for optional arguments */
@@ -1287,7 +1287,7 @@ output_interface_operation(FILE* outf,
* generate class methods for each interface operation
*/
static int
-output_interface_operations(FILE* outf, struct interface_map_entry *interfacee)
+output_interface_operations(FILE* outf, struct ir_interface_entry *interfacee)
{
int opc;
int res = 0;
@@ -1309,8 +1309,8 @@ output_interface_operations(FILE* outf, struct interface_map_entry
*interfacee)
*/
static int
output_interface_attribute(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_attribute_entry *atributee)
+ struct ir_interface_entry *interfacee,
+ struct ir_attribute_entry *atributee)
{
int cdatac;
@@ -1370,7 +1370,7 @@ output_interface_attribute(FILE* outf,
*/
static int
output_interface_attributes(FILE* outf,
- struct interface_map_entry *interfacee)
+ struct ir_interface_entry *interfacee)
{
int attrc;
@@ -1409,12 +1409,12 @@ static int output_tool_prologue(FILE* outf)
/**
* generate a source file to implement an interface using duk and libdom.
*/
-static int output_interface(struct interface_map *interface_map,
- struct interface_map_entry *interfacee)
+static int output_interface(struct ir *ir,
+ struct ir_interface_entry *interfacee)
{
FILE *ifacef;
int ifacenamelen;
- struct interface_map_entry *inherite;
+ struct ir_interface_entry *inherite;
int res = 0;
/* do not generate class for interfaces marked no output */
@@ -1438,14 +1438,14 @@ static int output_interface(struct interface_map *interface_map,
}
/* find parent interface entry */
- inherite = interface_map_inherit_entry(interface_map, interfacee);
+ inherite = ir_inherit_entry(ir, interfacee);
/* tool preface */
output_tool_preface(ifacef);
/* binding preface */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PREFACE);
/* class preface */
@@ -1456,7 +1456,7 @@ static int output_interface(struct interface_map *interface_map,
/* binding prologue */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PROLOGUE);
/* class prologue */
@@ -1486,7 +1486,7 @@ static int output_interface(struct interface_map *interface_map,
output_interface_attributes(ifacef, interfacee);
/* prototype */
- output_interface_prototype(ifacef, interfacee, inherite, interface_map);
+ output_interface_prototype(ifacef, interfacee, inherite, ir);
fprintf(ifacef, "\n");
@@ -1495,7 +1495,7 @@ static int output_interface(struct interface_map *interface_map,
/* binding epilogue */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_EPILOGUE);
/* class postface */
@@ -1503,7 +1503,7 @@ static int output_interface(struct interface_map *interface_map,
/* binding postface */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_POSTFACE);
op_error:
@@ -1516,20 +1516,20 @@ op_error:
* generate private header
*/
static int
-output_private_header(struct interface_map *interface_map)
+output_private_header(struct ir *ir)
{
int idx;
FILE *privf;
/* open header */
- privf = open_header(interface_map, "private");
+ privf = open_header(ir, "private");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
- struct interface_map_entry *inherite;
+ for (idx = 0; idx < ir->interfacec; idx++) {
+ struct ir_interface_entry *interfacee;
+ struct ir_interface_entry *inherite;
struct genbind_node *priv_node;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->interfaces + idx;
/* do not generate private structs for interfaces marked no
* output
@@ -1539,7 +1539,7 @@ output_private_header(struct interface_map *interface_map)
}
/* find parent interface entry */
- inherite = interface_map_inherit_entry(interface_map,
+ inherite = ir_inherit_entry(ir,
interfacee);
fprintf(privf, "typedef struct {\n");
@@ -1585,7 +1585,7 @@ output_private_header(struct interface_map *interface_map)
}
- close_header(interface_map, privf, "private");
+ close_header(ir, privf, "private");
return 0;
}
@@ -1594,19 +1594,19 @@ output_private_header(struct interface_map *interface_map)
* generate prototype header
*/
static int
-output_prototype_header(struct interface_map *interface_map)
+output_prototype_header(struct ir *ir)
{
int idx;
FILE *protof;
/* open header */
- protof = open_header(interface_map, "prototype");
+ protof = open_header(ir, "prototype");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
+ for (idx = 0; idx < ir->interfacec; idx++) {
+ struct ir_interface_entry *interfacee;
struct genbind_node *init_node;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->interfaces + idx;
/* do not generate prototype declarations for interfaces marked
* no output
@@ -1641,7 +1641,7 @@ output_prototype_header(struct interface_map *interface_map)
fprintf(protof, ";\n\n");
}
- close_header(interface_map, protof, "prototype");
+ close_header(ir, protof, "prototype");
return 0;
}
@@ -1650,7 +1650,7 @@ output_prototype_header(struct interface_map *interface_map)
* generate makefile fragment
*/
static int
-output_makefile(struct interface_map *interface_map)
+output_makefile(struct ir *ir)
{
int idx;
FILE *makef;
@@ -1664,10 +1664,10 @@ output_makefile(struct interface_map *interface_map)
fprintf(makef, "# duk libdom makefile fragment\n\n");
fprintf(makef, "NSGENBIND_SOURCES:=binding.c ");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
+ for (idx = 0; idx < ir->interfacec; idx++) {
+ struct ir_interface_entry *interfacee;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->interfaces + idx;
/* no source for interfaces marked no output */
if (interfacee->noobject) {
@@ -1695,12 +1695,12 @@ output_makefile(struct interface_map *interface_map)
* the primary global (if any) generated last.
*/
static int
-output_binding_header(struct interface_map *interface_map)
+output_binding_header(struct ir *ir)
{
FILE *bindf;
/* open header */
- bindf = open_header(interface_map, "binding");
+ bindf = open_header(ir, "binding");
fprintf(bindf,
"#define _MAGIC(S) (\"%s\" S)\n"
@@ -1735,7 +1735,7 @@ output_binding_header(struct interface_map *interface_map)
fprintf(bindf,
"duk_ret_t %s_create_prototypes(duk_context *ctx);\n", DLPFX);
- close_header(interface_map, bindf, "binding");
+ close_header(ir, bindf, "binding");
return 0;
}
@@ -1748,11 +1748,11 @@ output_binding_header(struct interface_map *interface_map)
* implementations.
*/
static int
-output_binding_src(struct interface_map *interface_map)
+output_binding_src(struct ir *ir)
{
int idx;
FILE *bindf;
- struct interface_map_entry *pglobale = NULL;
+ struct ir_interface_entry *pglobale = NULL;
char *proto_name;
/* open output file */
@@ -1766,14 +1766,14 @@ output_binding_src(struct interface_map *interface_map)
/* binding preface */
output_cdata(bindf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PREFACE);
output_tool_prologue(bindf);
/* binding prologue */
output_cdata(bindf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PROLOGUE);
@@ -1893,10 +1893,10 @@ output_binding_src(struct interface_map *interface_map)
fprintf(bindf, "{\n");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
+ for (idx = 0; idx < ir->interfacec; idx++) {
+ struct ir_interface_entry *interfacee;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->interfaces + idx;
/* do not generate prototype calls for interfaces marked
* no output
@@ -1943,7 +1943,7 @@ output_binding_src(struct interface_map *interface_map)
/* binding postface */
output_cdata(bindf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_POSTFACE);
genb_fclose_tmp(bindf, "binding.c");
@@ -1951,46 +1951,46 @@ output_binding_src(struct interface_map *interface_map)
return 0;
}
-int duk_libdom_output(struct interface_map *interface_map)
+int duk_libdom_output(struct ir *ir)
{
int idx;
int res = 0;
/* generate interfaces */
- for (idx = 0; idx < interface_map->entryc; idx++) {
- res = output_interface(interface_map,
- interface_map->entries + idx);
+ for (idx = 0; idx < ir->interfacec; idx++) {
+ res = output_interface(ir,
+ ir->interfaces + idx);
if (res != 0) {
goto output_err;
}
}
/* generate private header */
- res = output_private_header(interface_map);
+ res = output_private_header(ir);
if (res != 0) {
goto output_err;
}
/* generate prototype header */
- res = output_prototype_header(interface_map);
+ res = output_prototype_header(ir);
if (res != 0) {
goto output_err;
}
/* generate binding header */
- res = output_binding_header(interface_map);
+ res = output_binding_header(ir);
if (res != 0) {
goto output_err;
}
/* generate binding source */
- res = output_binding_src(interface_map);
+ res = output_binding_src(ir);
if (res != 0) {
goto output_err;
}
/* generate makefile fragment */
- res = output_makefile(interface_map);
+ res = output_makefile(ir);
output_err:
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index e1dd2c4..2ecd482 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -9,6 +9,6 @@
#ifndef nsgenbind_duk_libdom_h
#define nsgenbind_duk_libdom_h
-int duk_libdom_output(struct interface_map *interface_map);
+int duk_libdom_output(struct ir *ir);
#endif
diff --git a/src/interface-map.c b/src/interface-map.c
deleted file mode 100644
index 822892f..0000000
--- a/src/interface-map.c
+++ /dev/null
@@ -1,874 +0,0 @@
-/* interface mapping
- *
- * This file is part of nsgenbind.
- * Published under the MIT License,
- *
http://www.opensource.org/licenses/mit-license.php
- * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
- */
-
-#include <stdbool.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-#include "options.h"
-#include "utils.h"
-#include "nsgenbind-ast.h"
-#include "webidl-ast.h"
-#include "interface-map.h"
-
-/** count the number of nodes of a given type on an interface */
-static int
-enumerate_interface_type(struct webidl_node *interface_node,
- enum webidl_node_type node_type)
-{
- int count = 0;
- struct webidl_node *members_node;
-
- members_node = webidl_node_find_type(
- webidl_node_getnode(interface_node),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
- while (members_node != NULL) {
- count += webidl_node_enumerate_type(
- webidl_node_getnode(members_node),
- node_type);
-
- members_node = webidl_node_find_type(
- webidl_node_getnode(interface_node),
- members_node,
- WEBIDL_NODE_TYPE_LIST);
- }
-
- return count;
-}
-
-/* find index of inherited node if it is one of those listed in the
- * binding also maintain refcounts
- */
-static void
-compute_inherit_refcount(struct interface_map_entry *entries, int entryc)
-{
- int idx;
- int inf;
-
- for (idx = 0; idx < entryc; idx++ ) {
- entries[idx].inherit_idx = -1;
- for (inf = 0; inf < entryc; inf++ ) {
- /* cannot inherit from self and name must match */
- if ((inf != idx) &&
- (entries[idx].inherit_name != NULL ) &&
- (strcmp(entries[idx].inherit_name,
- entries[inf].name) == 0)) {
- entries[idx].inherit_idx = inf;
- entries[inf].refcount++;
- break;
- }
- }
- }
-}
-
-/** Topoligical sort based on the refcount
- *
- * do not need to consider loops as constructed graph is a acyclic
- *
- * alloc a second copy of the map
- * repeat until all entries copied:
- * walk source mapping until first entry with zero refcount
- * put the entry at the end of the output map
- * reduce refcount on inherit index if !=-1
- * remove entry from source map
- */
-static struct interface_map_entry *
-interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
-{
- struct interface_map_entry *dstinf;
- int idx;
- int inf;
-
- dstinf = calloc(infc, sizeof(struct interface_map_entry));
- if (dstinf == NULL) {
- return NULL;
- }
-
- for (idx = infc - 1; idx >= 0; idx--) {
- /* walk source map until first valid entry with zero refcount */
- inf = 0;
- while ((inf < infc) &&
- ((srcinf[inf].name == NULL) ||
- (srcinf[inf].refcount > 0))) {
- inf++;
- }
- if (inf == infc) {
- free(dstinf);
- return NULL;
- }
-
- /* copy entry to the end of the output map */
- dstinf[idx].name = srcinf[inf].name;
- dstinf[idx].node = srcinf[inf].node;
- dstinf[idx].inherit_name = srcinf[inf].inherit_name;
- dstinf[idx].noobject = srcinf[inf].noobject;
- dstinf[idx].primary_global = srcinf[inf].primary_global;
- dstinf[idx].operationc = srcinf[inf].operationc;
- 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 */
- if (srcinf[inf].inherit_idx != -1) {
- srcinf[srcinf[inf].inherit_idx].refcount--;
- }
-
- /* remove entry from source map */
- srcinf[inf].name = NULL;
- }
-
- return dstinf;
-}
-
-static struct interface_map_operation_entry *
-find_operation_name(struct interface_map_operation_entry *operationv,
- int operationc,
- const char *name)
-{
- struct interface_map_operation_entry *cure;
- int opc;
-
- for (opc = 0; opc < operationc; opc++) {
- cure = operationv + opc;
-
- if (cure->name == name) {
- /* check pointers for equivalence */
- return cure;
- } else {
- if ((cure->name != NULL) &&
- (name != NULL) &&
- (strcmp(cure->name, name) == 0)) {
- return cure;
- }
- }
- }
-
- return NULL;
-}
-
-static int
-argument_map_new(struct webidl_node *arg_list_node,
- int *argumentc_out,
- struct interface_map_operation_argument_entry **argumentv_out)
-{
- int argumentc;
- struct webidl_node *argument;
- struct interface_map_operation_argument_entry *argumentv;
- struct interface_map_operation_argument_entry *cure;
-
- argumentc = webidl_node_enumerate_type(
- webidl_node_getnode(arg_list_node),
- WEBIDL_NODE_TYPE_ARGUMENT);
- if (argumentc == 0) {
- *argumentc_out = 0;
- *argumentv_out = NULL;
- return 0;
- }
-
- argumentv = calloc(argumentc, sizeof(*argumentv));
- cure = argumentv;
-
- /* iterate each argument node within the list */
- argument = webidl_node_find_type(webidl_node_getnode(arg_list_node),
- NULL,
- WEBIDL_NODE_TYPE_ARGUMENT);
-
- while (argument != NULL) {
-
- cure->name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(argument),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
-
- cure->node = argument;
-
-
- cure->optionalc = webidl_node_enumerate_type(
- webidl_node_getnode(argument),
- WEBIDL_NODE_TYPE_OPTIONAL);
-
- cure->elipsisc = webidl_node_enumerate_type(
- webidl_node_getnode(argument),
- WEBIDL_NODE_TYPE_ELLIPSIS);
-
- cure++;
-
- argument = webidl_node_find_type(
- webidl_node_getnode(arg_list_node),
- argument,
- WEBIDL_NODE_TYPE_ARGUMENT);
- }
-
- *argumentc_out = argumentc;
- *argumentv_out = argumentv;
-
- return 0;
-}
-
-/**
- * create a new overloaded parameter set on an operation
- *
- * each operation can be overloaded with multiple function signatures. By
- * adding them to the operation as overloads duplicate operation enrtries is
- * avoided.
- */
-static int
-overload_map_new(struct webidl_node *op_node,
- int *overloadc_out,
- struct interface_map_operation_overload_entry **overloadv_out)
-{
- int overloadc = *overloadc_out;
- struct interface_map_operation_overload_entry *overloadv;
- struct interface_map_operation_overload_entry *cure;
- struct webidl_node *arg_list_node;
- int argc;
-
- /* update allocation */
- overloadc++;
- overloadv = realloc(*overloadv_out, overloadc * sizeof(*overloadv));
- if (overloadv == NULL) {
- return -1;
- }
-
- /* get added entry */
- cure = overloadv + (overloadc - 1);
-
- /* clear entry */
- cure = memset(cure, 0, sizeof(*cure));
-
- /* return type */
- cure->type = webidl_node_find_type(webidl_node_getnode(op_node),
- NULL,
- WEBIDL_NODE_TYPE_TYPE);
-
- arg_list_node = webidl_node_find_type(webidl_node_getnode(op_node),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
- if (arg_list_node != NULL) {
- argument_map_new(arg_list_node,
- &cure->argumentc,
- &cure->argumentv);
- }
-
- for (argc = 0; argc < cure->argumentc; argc++) {
- struct interface_map_operation_argument_entry *arge;
- arge = cure->argumentv + argc;
- cure->optionalc += arge->optionalc;
- cure->elipsisc += arge->elipsisc;
- }
-
- /* return entry list */
- *overloadc_out = overloadc;
- *overloadv_out = overloadv;
-
- return 0;
-}
-
-static int
-operation_map_new(struct webidl_node *interface,
- struct genbind_node *class,
- int *operationc_out,
- struct interface_map_operation_entry **operationv_out)
-{
- struct webidl_node *list_node;
- struct webidl_node *op_node; /* attribute node */
- struct interface_map_operation_entry *cure; /* current entry */
- struct interface_map_operation_entry *operationv;
- int operationc;
-
- /* enumerate operationss including overloaded members */
- operationc = enumerate_interface_type(interface,
- WEBIDL_NODE_TYPE_OPERATION);
-
- if (operationc < 1) {
- /* no operations so empty map */
- *operationc_out = 0;
- *operationv_out = NULL;
- return 0;
- }
-
- operationv = calloc(operationc,
- sizeof(struct interface_map_operation_entry));
- if (operationv == NULL) {
- return -1;
- };
- cure = operationv;
-
- /* 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 operations on list */
- op_node = webidl_node_find_type(
- webidl_node_getnode(list_node),
- NULL,
- WEBIDL_NODE_TYPE_OPERATION);
-
- while (op_node != NULL) {
- const char *operation_name;
- struct interface_map_operation_entry *finde;
-
- /* get operation name */
- operation_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(op_node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
- /* if this operation is already an entry in the list
- * augment that entry else create a new one
- */
- finde = find_operation_name(operationv,
- operationc,
- operation_name);
- if (finde == NULL) {
- /* operation does not already exist in list */
-
- cure->name = operation_name;
-
- cure->node = op_node;
-
- cure->method = genbind_node_find_method_ident(
- class,
- NULL,
- GENBIND_METHOD_TYPE_METHOD,
- cure->name);
-
- overload_map_new(op_node,
- &cure->overloadc,
- &cure->overloadv);
-
- cure++; /* advance to next entry */
- } else {
- overload_map_new(op_node,
- &finde->overloadc,
- &finde->overloadv);
- /* Overloaded entry does not advance the
- * current entry but does reduce list
- * length. Do not bother shortening allocation.
- */
- operationc--;
- }
-
- /* move to next operation */
- op_node = webidl_node_find_type(
- webidl_node_getnode(list_node),
- op_node,
- WEBIDL_NODE_TYPE_OPERATION);
- }
-
- list_node = webidl_node_find_type(
- webidl_node_getnode(interface),
- list_node,
- WEBIDL_NODE_TYPE_LIST);
- }
-
- *operationc_out = operationc;
- *operationv_out = operationv; /* resulting operations map */
-
- return 0;
-}
-
-static int
-attribute_map_new(struct webidl_node *interface,
- struct genbind_node *class,
- int *attributec_out,
- struct interface_map_attribute_entry **attributev_out)
-{
- struct webidl_node *list_node;
- struct webidl_node *at_node; /* attribute node */
- struct interface_map_attribute_entry *cure; /* current entry */
- struct interface_map_attribute_entry *attributev;
- int attributec;
-
- /* enumerate attributes */
- attributec = enumerate_interface_type(interface,
- WEBIDL_NODE_TYPE_ATTRIBUTE);
- *attributec_out = attributec;
-
- if (attributec < 1) {
- *attributev_out = NULL; /* no attributes so empty map */
- return 0;
- }
-
- attributev = calloc(attributec,
- sizeof(struct interface_map_attribute_entry));
- if (attributev == NULL) {
- return -1;
- };
- cure = attributev;
-
- /* 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 attributes on list */
- at_node = webidl_node_find_type(
- webidl_node_getnode(list_node),
- NULL,
- WEBIDL_NODE_TYPE_ATTRIBUTE);
-
- while (at_node != NULL) {
- enum webidl_type_modifier *modifier;
-
- cure->node = at_node;
-
- cure->name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(at_node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
-
- cure->getter = genbind_node_find_method_ident(
- class,
- NULL,
- GENBIND_METHOD_TYPE_GETTER,
- cure->name);
-
- /* check fo readonly attributes */
- modifier = (enum webidl_type_modifier *)webidl_node_getint(
- webidl_node_find_type(
- webidl_node_getnode(at_node),
- NULL,
- WEBIDL_NODE_TYPE_MODIFIER));
- if ((modifier != NULL) &&
- (*modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
- cure->modifier = WEBIDL_TYPE_MODIFIER_READONLY;
- } else {
- cure->modifier = WEBIDL_TYPE_MODIFIER_NONE;
- cure->setter = genbind_node_find_method_ident(
- class,
- NULL,
- GENBIND_METHOD_TYPE_SETTER,
- cure->name);
- }
-
- cure++;
-
- /* move to next attribute */
- at_node = webidl_node_find_type(
- webidl_node_getnode(list_node),
- at_node,
- WEBIDL_NODE_TYPE_ATTRIBUTE);
- }
-
- list_node = webidl_node_find_type(
- webidl_node_getnode(interface),
- list_node,
- WEBIDL_NODE_TYPE_LIST);
- }
-
- *attributev_out = attributev; /* resulting attributes map */
-
- 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 **map_out)
-{
- int interfacec;
- struct interface_map_entry *entries;
- struct interface_map_entry *sorted_entries;
- struct interface_map_entry *ecur;
- struct webidl_node *node;
- struct interface_map *map;
-
- interfacec = webidl_node_enumerate_type(webidl,
- WEBIDL_NODE_TYPE_INTERFACE);
-
- if (options->verbose) {
- printf("Mapping %d interfaces\n", interfacec);
- }
-
- entries = calloc(interfacec, sizeof(struct interface_map_entry));
- if (entries == NULL) {
- return -1;
- }
-
- /* for each interface populate an entry in the map */
- ecur = entries;
- node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
- while (node != NULL) {
-
- /* fill map entry */
- ecur->node = node;
-
- /* name of interface */
- ecur->name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
-
- /* name of the inherited interface (if any) */
- ecur->inherit_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(node),
- NULL,
- WEBIDL_NODE_TYPE_INHERITANCE));
-
- /* is the interface marked as not generating an object */
- if (webidl_node_find_type_ident(
- webidl_node_getnode(node),
- WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE,
- "NoInterfaceObject") != NULL) {
- /** \todo we should ensure inherit is unset as this
- * cannot form part of an inheritance chain if it is
- * not generating an output class
- */
- ecur->noobject = true;
- }
-
- /* is the interface marked as the primary global */
- if (webidl_node_find_type_ident(
- webidl_node_getnode(node),
- WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE,
- "PrimaryGlobal") != NULL) {
- /** \todo we should ensure nothing inherits *from* this
- * class or all hell will break loose having two
- * primary globals.
- */
- ecur->primary_global = true;
- }
-
- /* matching class from binding */
- ecur->class = genbind_node_find_type_ident(genbind,
- NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
-
- /* enumerate and map the interface operations */
- operation_map_new(node,
- ecur->class,
- &ecur->operationc,
- &ecur->operationv);
-
- /* enumerate and map the interface attributes */
- attribute_map_new(node,
- ecur->class,
- &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);
- ecur++;
- }
-
- /* compute inheritance and refcounts on map */
- compute_inherit_refcount(entries, interfacec);
-
- /* sort interfaces to ensure correct ordering */
- sorted_entries = interface_topoligical_sort(entries, interfacec);
- free(entries);
- if (sorted_entries == NULL) {
- return -1;
- }
-
- /* compute inheritance and refcounts on sorted map */
- compute_inherit_refcount(sorted_entries, interfacec);
-
- map = malloc(sizeof(struct interface_map));
- map->entryc = interfacec;
- map->entries = sorted_entries;
- map->webidl = webidl;
- map->binding_node = genbind_node_find_type(genbind, NULL,
- GENBIND_NODE_TYPE_BINDING);
-
- *map_out = map;
-
- return 0;
-}
-
-int interface_map_dump(struct interface_map *index)
-{
- FILE *dumpf;
- int eidx;
- struct interface_map_entry *ecur;
-
- /* only dump AST to file if required */
- if (!options->debug) {
- return 0;
- }
-
- dumpf = genb_fopen("interface-map", "w");
- if (dumpf == NULL) {
- return 2;
- }
-
- ecur = index->entries;
- for (eidx = 0; eidx < index->entryc; eidx++) {
- fprintf(dumpf, "%d %s\n", eidx, ecur->name);
- if (ecur->inherit_name != NULL) {
- fprintf(dumpf, "\tinherit:%s\n",
ecur->inherit_name);
- }
- if (ecur->class != NULL) {
- fprintf(dumpf, "\tclass:%p\n", ecur->class);
- }
-
- if (ecur->operationc > 0) {
- int opc;
-
- fprintf(dumpf, "\t%d operations\n",
- ecur->operationc);
-
- for (opc = 0; opc < ecur->operationc; opc++) {
- int ovlc;
- struct interface_map_operation_entry *ope;
-
- ope = ecur->operationv + opc;
-
- fprintf(dumpf,
- "\t\t%s\n",
- ope->name);
- fprintf(dumpf,
- "\t\t\tmethod:%p\n",
- ope->method);
- for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
- int argc;
- struct interface_map_operation_overload_entry
*ovle;
- ovle = ope->overloadv + ovlc;
-
- fprintf(dumpf,
- "\t\t\toverload:%d\n", ovlc);
-
- fprintf(dumpf,
- "\t\t\t\treturn type:%p\n",
- ovle->type);
-
- fprintf(dumpf,
- "\t\t\t\targuments:%d\n",
- ovle->argumentc);
-
- fprintf(dumpf,
- "\t\t\t\toptionals:%d\n",
- ovle->optionalc);
-
- fprintf(dumpf,
- "\t\t\t\telipsis:%d\n",
- ovle->elipsisc);
-
- for (argc = 0; argc < ovle->argumentc;
argc++) {
- struct
interface_map_operation_argument_entry *arge;
- arge = ovle->argumentv + argc;
-
- fprintf(dumpf,
- "\t\t\t\t\t%s\n",
- arge->name);
-
- if (arge->optionalc != 0) {
- fprintf(dumpf,
-
"\t\t\t\t\t\toptional:%d\n",
- arge->optionalc);
- }
-
- if (arge->elipsisc != 0) {
- fprintf(dumpf,
-
"\t\t\t\t\t\telipsis:%d\n",
- arge->elipsisc);
- }
-
- }
- }
- }
- }
-
- if (ecur->attributec > 0) {
- int attrc = ecur->attributec;
- struct interface_map_attribute_entry *attre;
-
- fprintf(dumpf, "\t%d attributes\n", attrc);
-
- attre = ecur->attributev;
- while (attre != NULL) {
- fprintf(dumpf, "\t\t%s %p",
- attre->name,
- attre->getter);
- if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
- fprintf(dumpf, " %p\n",
attre->setter);
- } else {
- fprintf(dumpf, "\n");
- }
- attre++;
- attrc--;
- if (attrc == 0) {
- break;
- }
- }
- }
- if (ecur->constantc > 0) {
- int idx;
-
- fprintf(dumpf, "\t%d constants\n",
- ecur->constantc);
-
- for (idx = 0; idx < ecur->constantc; idx++) {
- struct interface_map_constant_entry *cone;
- cone = ecur->constantv + idx;
- fprintf(dumpf, "\t\t%s\n",
- cone->name);
- }
- }
- ecur++;
- }
-
- fclose(dumpf);
-
- return 0;
-}
-
-int interface_map_dumpdot(struct interface_map *index)
-{
- FILE *dumpf;
- int eidx;
- struct interface_map_entry *ecur;
-
- /* only dump AST to file if required */
- if (!options->debug) {
- return 0;
- }
-
- dumpf = genb_fopen("interface.dot", "w");
- if (dumpf == NULL) {
- return 2;
- }
-
- fprintf(dumpf, "digraph interfaces {\n");
-
- fprintf(dumpf, "node [shape=box]\n");
-
- ecur = index->entries;
- for (eidx = 0; eidx < index->entryc; eidx++) {
- fprintf(dumpf, "%04d [label=\"%s\"", eidx,
ecur->name);
- if (ecur->noobject == true) {
- /* noobject interfaces in red */
- fprintf(dumpf, "fontcolor=\"red\"");
- } else if (ecur->class != NULL) {
- /* interfaces bound to a class are shown in blue */
- fprintf(dumpf, "fontcolor=\"blue\"");
- }
- fprintf(dumpf, "];\n");
- ecur++;
- }
-
- ecur = index->entries;
- for (eidx = 0; eidx < index->entryc; eidx++) {
- if (index->entries[eidx].inherit_idx != -1) {
- fprintf(dumpf, "%04d -> %04d;\n",
- eidx, index->entries[eidx].inherit_idx);
- }
- }
-
- fprintf(dumpf, "}\n");
-
- fclose(dumpf);
-
- return 0;
-}
-
-struct interface_map_entry *
-interface_map_inherit_entry(struct interface_map *map,
- struct interface_map_entry *entry)
-{
- struct interface_map_entry *res = NULL;
-
- if ((entry != NULL) &&
- (entry->inherit_idx != -1)) {
- res = &map->entries[entry->inherit_idx];
- }
- return res;
-}
diff --git a/src/interface-map.h b/src/interface-map.h
deleted file mode 100644
index 079ed96..0000000
--- a/src/interface-map.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Interface mapping
- *
- * This file is part of nsgenbind.
- * Licensed under the MIT License,
- *
http://www.opensource.org/licenses/mit-license.php
- * Copyright 2012 Vincent Sanders <vince(a)netsurf-browser.org>
- */
-
-#ifndef nsgenbind_interface_map_h
-#define nsgenbind_interface_map_h
-
-struct genbind_node;
-struct webidl_node;
-
-/**
- * map entry for each argument of an overload on an operation
- */
-struct interface_map_operation_argument_entry {
- const char *name;
-
- int optionalc; /**< 1 if the argument is optional */
- int elipsisc; /**< 1 if the argument is an elipsis */
-
- struct webidl_node *node;
-};
-
-/** map entry for each overload of an operation */
-struct interface_map_operation_overload_entry {
- struct webidl_node *type; /**< The return type of this overload */
-
- int optionalc; /**< Number of parameters that are optional */
- int elipsisc; /**< Number of elipsis parameters */
-
- int argumentc; /**< the number of parameters */
- struct interface_map_operation_argument_entry *argumentv;
-};
-
-/** 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 */
-
- int overloadc; /**< Number of overloads of this operation */
- struct interface_map_operation_overload_entry *overloadv;
-};
-
-/** map entry for attributes on an interface */
-struct interface_map_attribute_entry {
- const char *name; /** attribute name */
- struct webidl_node *node; /**< AST attribute node */
- enum webidl_type_modifier modifier;
- struct genbind_node *getter; /**< getter from binding */
- struct genbind_node *setter; /**< getter from binding */
-};
-
-/** 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 */
- const char *inherit_name; /**< Name of interface inhertited from */
- int inherit_idx; /**< index into map of inherited interface or -1 for
- * not in map
- */
- int refcount; /**< number of interfacess in map that refer to this
- * interface
- */
- bool noobject; /**< flag indicating if no interface object should eb
- * generated. This allows for interfaces which do not
- * generate code. For implements (mixin) interfaces
- */
- bool primary_global; /**< flag indicating the interface is the primary
- * global javascript object.
- */
-
- int operationc; /**< number of operations on interface */
- struct interface_map_operation_entry *operationv;
-
- 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;
-
-
- struct genbind_node *class; /**< class from binding (if any) */
-
- /* The variables are created and used by the output generation but
- * rtaher than have another allocation and pointer the data they are
- * just inline here.
- */
-
- char *filename; /**< filename used for output */
-
- char *class_name; /**< the interface name converted to output
- * appropriate value. e.g. generators targetting c
- * might lowercase the name or add underscores
- * instead of caps
- */
- int class_init_argc; /**< The number of parameters on the class
- * initializer.
- */
-};
-
-/** WebIDL interface map */
-struct interface_map {
- int entryc; /**< count of interfaces */
- struct interface_map_entry *entries; /**< interface entries */
-
- /** The AST node of the binding information */
- struct genbind_node *binding_node;
-
- /** Root AST node of the webIDL */
- struct webidl_node *webidl;
-};
-
-/**
- * Create a new interface map
- */
-int interface_map_new(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct interface_map **map_out);
-
-int interface_map_dump(struct interface_map *map);
-
-int interface_map_dumpdot(struct interface_map *map);
-
-/**
- * interface map parent entry
- *
- * \return inherit entry or NULL if there is not one
- */
-struct interface_map_entry *interface_map_inherit_entry(struct interface_map *map, struct
interface_map_entry *entry);
-
-#endif
diff --git a/src/ir.c b/src/ir.c
new file mode 100644
index 0000000..ab2add7
--- /dev/null
+++ b/src/ir.c
@@ -0,0 +1,874 @@
+/* intermediate representation of WebIDL and binding data
+ *
+ * This file is part of nsgenbind.
+ * Published under the MIT License,
+ *
http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2015 Vincent Sanders <vince(a)netsurf-browser.org>
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include "options.h"
+#include "utils.h"
+#include "nsgenbind-ast.h"
+#include "webidl-ast.h"
+#include "ir.h"
+
+/** count the number of nodes of a given type on an interface */
+static int
+enumerate_interface_type(struct webidl_node *interface_node,
+ enum webidl_node_type node_type)
+{
+ int count = 0;
+ struct webidl_node *members_node;
+
+ members_node = webidl_node_find_type(
+ webidl_node_getnode(interface_node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+ while (members_node != NULL) {
+ count += webidl_node_enumerate_type(
+ webidl_node_getnode(members_node),
+ node_type);
+
+ members_node = webidl_node_find_type(
+ webidl_node_getnode(interface_node),
+ members_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ return count;
+}
+
+/* find index of inherited node if it is one of those listed in the
+ * binding also maintain refcounts
+ */
+static void
+compute_inherit_refcount(struct ir_interface_entry *entries, int entryc)
+{
+ int idx;
+ int inf;
+
+ for (idx = 0; idx < entryc; idx++ ) {
+ entries[idx].inherit_idx = -1;
+ for (inf = 0; inf < entryc; inf++ ) {
+ /* cannot inherit from self and name must match */
+ if ((inf != idx) &&
+ (entries[idx].inherit_name != NULL ) &&
+ (strcmp(entries[idx].inherit_name,
+ entries[inf].name) == 0)) {
+ entries[idx].inherit_idx = inf;
+ entries[inf].refcount++;
+ break;
+ }
+ }
+ }
+}
+
+/** Topoligical sort based on the refcount
+ *
+ * do not need to consider loops as constructed graph is a acyclic
+ *
+ * alloc a second copy of the map
+ * repeat until all entries copied:
+ * walk source mapping until first entry with zero refcount
+ * put the entry at the end of the output map
+ * reduce refcount on inherit index if !=-1
+ * remove entry from source map
+ */
+static struct ir_interface_entry *
+interface_topoligical_sort(struct ir_interface_entry *srcinf, int infc)
+{
+ struct ir_interface_entry *dstinf;
+ int idx;
+ int inf;
+
+ dstinf = calloc(infc, sizeof(struct ir_interface_entry));
+ if (dstinf == NULL) {
+ return NULL;
+ }
+
+ for (idx = infc - 1; idx >= 0; idx--) {
+ /* walk source map until first valid entry with zero refcount */
+ inf = 0;
+ while ((inf < infc) &&
+ ((srcinf[inf].name == NULL) ||
+ (srcinf[inf].refcount > 0))) {
+ inf++;
+ }
+ if (inf == infc) {
+ free(dstinf);
+ return NULL;
+ }
+
+ /* copy entry to the end of the output map */
+ dstinf[idx].name = srcinf[inf].name;
+ dstinf[idx].node = srcinf[inf].node;
+ dstinf[idx].inherit_name = srcinf[inf].inherit_name;
+ dstinf[idx].noobject = srcinf[inf].noobject;
+ dstinf[idx].primary_global = srcinf[inf].primary_global;
+ dstinf[idx].operationc = srcinf[inf].operationc;
+ 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 */
+ if (srcinf[inf].inherit_idx != -1) {
+ srcinf[srcinf[inf].inherit_idx].refcount--;
+ }
+
+ /* remove entry from source map */
+ srcinf[inf].name = NULL;
+ }
+
+ return dstinf;
+}
+
+static struct ir_operation_entry *
+find_operation_name(struct ir_operation_entry *operationv,
+ int operationc,
+ const char *name)
+{
+ struct ir_operation_entry *cure;
+ int opc;
+
+ for (opc = 0; opc < operationc; opc++) {
+ cure = operationv + opc;
+
+ if (cure->name == name) {
+ /* check pointers for equivalence */
+ return cure;
+ } else {
+ if ((cure->name != NULL) &&
+ (name != NULL) &&
+ (strcmp(cure->name, name) == 0)) {
+ return cure;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+static int
+argument_map_new(struct webidl_node *arg_list_node,
+ int *argumentc_out,
+ struct ir_operation_argument_entry **argumentv_out)
+{
+ int argumentc;
+ struct webidl_node *argument;
+ struct ir_operation_argument_entry *argumentv;
+ struct ir_operation_argument_entry *cure;
+
+ argumentc = webidl_node_enumerate_type(
+ webidl_node_getnode(arg_list_node),
+ WEBIDL_NODE_TYPE_ARGUMENT);
+ if (argumentc == 0) {
+ *argumentc_out = 0;
+ *argumentv_out = NULL;
+ return 0;
+ }
+
+ argumentv = calloc(argumentc, sizeof(*argumentv));
+ cure = argumentv;
+
+ /* iterate each argument node within the list */
+ argument = webidl_node_find_type(webidl_node_getnode(arg_list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_ARGUMENT);
+
+ while (argument != NULL) {
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(argument),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure->node = argument;
+
+
+ cure->optionalc = webidl_node_enumerate_type(
+ webidl_node_getnode(argument),
+ WEBIDL_NODE_TYPE_OPTIONAL);
+
+ cure->elipsisc = webidl_node_enumerate_type(
+ webidl_node_getnode(argument),
+ WEBIDL_NODE_TYPE_ELLIPSIS);
+
+ cure++;
+
+ argument = webidl_node_find_type(
+ webidl_node_getnode(arg_list_node),
+ argument,
+ WEBIDL_NODE_TYPE_ARGUMENT);
+ }
+
+ *argumentc_out = argumentc;
+ *argumentv_out = argumentv;
+
+ return 0;
+}
+
+/**
+ * create a new overloaded parameter set on an operation
+ *
+ * each operation can be overloaded with multiple function signatures. By
+ * adding them to the operation as overloads duplicate operation enrtries is
+ * avoided.
+ */
+static int
+overload_map_new(struct webidl_node *op_node,
+ int *overloadc_out,
+ struct ir_operation_overload_entry **overloadv_out)
+{
+ int overloadc = *overloadc_out;
+ struct ir_operation_overload_entry *overloadv;
+ struct ir_operation_overload_entry *cure;
+ struct webidl_node *arg_list_node;
+ int argc;
+
+ /* update allocation */
+ overloadc++;
+ overloadv = realloc(*overloadv_out, overloadc * sizeof(*overloadv));
+ if (overloadv == NULL) {
+ return -1;
+ }
+
+ /* get added entry */
+ cure = overloadv + (overloadc - 1);
+
+ /* clear entry */
+ cure = memset(cure, 0, sizeof(*cure));
+
+ /* return type */
+ cure->type = webidl_node_find_type(webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_TYPE);
+
+ arg_list_node = webidl_node_find_type(webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+ if (arg_list_node != NULL) {
+ argument_map_new(arg_list_node,
+ &cure->argumentc,
+ &cure->argumentv);
+ }
+
+ for (argc = 0; argc < cure->argumentc; argc++) {
+ struct ir_operation_argument_entry *arge;
+ arge = cure->argumentv + argc;
+ cure->optionalc += arge->optionalc;
+ cure->elipsisc += arge->elipsisc;
+ }
+
+ /* return entry list */
+ *overloadc_out = overloadc;
+ *overloadv_out = overloadv;
+
+ return 0;
+}
+
+static int
+operation_map_new(struct webidl_node *interface,
+ struct genbind_node *class,
+ int *operationc_out,
+ struct ir_operation_entry **operationv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *op_node; /* attribute node */
+ struct ir_operation_entry *cure; /* current entry */
+ struct ir_operation_entry *operationv;
+ int operationc;
+
+ /* enumerate operationss including overloaded members */
+ operationc = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ if (operationc < 1) {
+ /* no operations so empty map */
+ *operationc_out = 0;
+ *operationv_out = NULL;
+ return 0;
+ }
+
+ operationv = calloc(operationc,
+ sizeof(struct ir_operation_entry));
+ if (operationv == NULL) {
+ return -1;
+ };
+ cure = operationv;
+
+ /* 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 operations on list */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_OPERATION);
+
+ while (op_node != NULL) {
+ const char *operation_name;
+ struct ir_operation_entry *finde;
+
+ /* get operation name */
+ operation_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(op_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+ /* if this operation is already an entry in the list
+ * augment that entry else create a new one
+ */
+ finde = find_operation_name(operationv,
+ operationc,
+ operation_name);
+ if (finde == NULL) {
+ /* operation does not already exist in list */
+
+ cure->name = operation_name;
+
+ cure->node = op_node;
+
+ cure->method = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_METHOD,
+ cure->name);
+
+ overload_map_new(op_node,
+ &cure->overloadc,
+ &cure->overloadv);
+
+ cure++; /* advance to next entry */
+ } else {
+ overload_map_new(op_node,
+ &finde->overloadc,
+ &finde->overloadv);
+ /* Overloaded entry does not advance the
+ * current entry but does reduce list
+ * length. Do not bother shortening allocation.
+ */
+ operationc--;
+ }
+
+ /* move to next operation */
+ op_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ op_node,
+ WEBIDL_NODE_TYPE_OPERATION);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *operationc_out = operationc;
+ *operationv_out = operationv; /* resulting operations map */
+
+ return 0;
+}
+
+static int
+attribute_map_new(struct webidl_node *interface,
+ struct genbind_node *class,
+ int *attributec_out,
+ struct ir_attribute_entry **attributev_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *at_node; /* attribute node */
+ struct ir_attribute_entry *cure; /* current entry */
+ struct ir_attribute_entry *attributev;
+ int attributec;
+
+ /* enumerate attributes */
+ attributec = enumerate_interface_type(interface,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+ *attributec_out = attributec;
+
+ if (attributec < 1) {
+ *attributev_out = NULL; /* no attributes so empty map */
+ return 0;
+ }
+
+ attributev = calloc(attributec,
+ sizeof(struct ir_attribute_entry));
+ if (attributev == NULL) {
+ return -1;
+ };
+ cure = attributev;
+
+ /* 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 attributes on list */
+ at_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ NULL,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+
+ while (at_node != NULL) {
+ enum webidl_type_modifier *modifier;
+
+ cure->node = at_node;
+
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(at_node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ cure->getter = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_GETTER,
+ cure->name);
+
+ /* check fo readonly attributes */
+ modifier = (enum webidl_type_modifier *)webidl_node_getint(
+ webidl_node_find_type(
+ webidl_node_getnode(at_node),
+ NULL,
+ WEBIDL_NODE_TYPE_MODIFIER));
+ if ((modifier != NULL) &&
+ (*modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
+ cure->modifier = WEBIDL_TYPE_MODIFIER_READONLY;
+ } else {
+ cure->modifier = WEBIDL_TYPE_MODIFIER_NONE;
+ cure->setter = genbind_node_find_method_ident(
+ class,
+ NULL,
+ GENBIND_METHOD_TYPE_SETTER,
+ cure->name);
+ }
+
+ cure++;
+
+ /* move to next attribute */
+ at_node = webidl_node_find_type(
+ webidl_node_getnode(list_node),
+ at_node,
+ WEBIDL_NODE_TYPE_ATTRIBUTE);
+ }
+
+ list_node = webidl_node_find_type(
+ webidl_node_getnode(interface),
+ list_node,
+ WEBIDL_NODE_TYPE_LIST);
+ }
+
+ *attributev_out = attributev; /* resulting attributes map */
+
+ return 0;
+}
+
+static int
+constant_map_new(struct webidl_node *interface,
+ int *constantc_out,
+ struct ir_constant_entry **constantv_out)
+{
+ struct webidl_node *list_node;
+ struct webidl_node *constant_node; /* constant node */
+ struct ir_constant_entry *cure; /* current entry */
+ struct ir_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 ir_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 ir_new(struct genbind_node *genbind,
+ struct webidl_node *webidl,
+ struct ir **map_out)
+{
+ int interfacec;
+ struct ir_interface_entry *entries;
+ struct ir_interface_entry *sorted_entries;
+ struct ir_interface_entry *ecur;
+ struct webidl_node *node;
+ struct ir *map;
+
+ interfacec = webidl_node_enumerate_type(webidl,
+ WEBIDL_NODE_TYPE_INTERFACE);
+
+ if (options->verbose) {
+ printf("Mapping %d interfaces\n", interfacec);
+ }
+
+ entries = calloc(interfacec, sizeof(struct ir_interface_entry));
+ if (entries == NULL) {
+ return -1;
+ }
+
+ /* for each interface populate an entry in the map */
+ ecur = entries;
+ node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
+ while (node != NULL) {
+
+ /* fill map entry */
+ ecur->node = node;
+
+ /* name of interface */
+ ecur->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ /* name of the inherited interface (if any) */
+ ecur->inherit_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_INHERITANCE));
+
+ /* is the interface marked as not generating an object */
+ if (webidl_node_find_type_ident(
+ webidl_node_getnode(node),
+ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE,
+ "NoInterfaceObject") != NULL) {
+ /** \todo we should ensure inherit is unset as this
+ * cannot form part of an inheritance chain if it is
+ * not generating an output class
+ */
+ ecur->noobject = true;
+ }
+
+ /* is the interface marked as the primary global */
+ if (webidl_node_find_type_ident(
+ webidl_node_getnode(node),
+ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE,
+ "PrimaryGlobal") != NULL) {
+ /** \todo we should ensure nothing inherits *from* this
+ * class or all hell will break loose having two
+ * primary globals.
+ */
+ ecur->primary_global = true;
+ }
+
+ /* matching class from binding */
+ ecur->class = genbind_node_find_type_ident(genbind,
+ NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
+
+ /* enumerate and map the interface operations */
+ operation_map_new(node,
+ ecur->class,
+ &ecur->operationc,
+ &ecur->operationv);
+
+ /* enumerate and map the interface attributes */
+ attribute_map_new(node,
+ ecur->class,
+ &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);
+ ecur++;
+ }
+
+ /* compute inheritance and refcounts on map */
+ compute_inherit_refcount(entries, interfacec);
+
+ /* sort interfaces to ensure correct ordering */
+ sorted_entries = interface_topoligical_sort(entries, interfacec);
+ free(entries);
+ if (sorted_entries == NULL) {
+ return -1;
+ }
+
+ /* compute inheritance and refcounts on sorted map */
+ compute_inherit_refcount(sorted_entries, interfacec);
+
+ map = malloc(sizeof(struct ir));
+ map->interfacec = interfacec;
+ map->interfaces = sorted_entries;
+ map->webidl = webidl;
+ map->binding_node = genbind_node_find_type(genbind, NULL,
+ GENBIND_NODE_TYPE_BINDING);
+
+ *map_out = map;
+
+ return 0;
+}
+
+int ir_dump(struct ir *index)
+{
+ FILE *dumpf;
+ int eidx;
+ struct ir_interface_entry *ecur;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("interface-map", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ ecur = index->interfaces;
+ for (eidx = 0; eidx < index->interfacec; eidx++) {
+ fprintf(dumpf, "%d %s\n", eidx, ecur->name);
+ if (ecur->inherit_name != NULL) {
+ fprintf(dumpf, "\tinherit:%s\n",
ecur->inherit_name);
+ }
+ if (ecur->class != NULL) {
+ fprintf(dumpf, "\tclass:%p\n", ecur->class);
+ }
+
+ if (ecur->operationc > 0) {
+ int opc;
+
+ fprintf(dumpf, "\t%d operations\n",
+ ecur->operationc);
+
+ for (opc = 0; opc < ecur->operationc; opc++) {
+ int ovlc;
+ struct ir_operation_entry *ope;
+
+ ope = ecur->operationv + opc;
+
+ fprintf(dumpf,
+ "\t\t%s\n",
+ ope->name);
+ fprintf(dumpf,
+ "\t\t\tmethod:%p\n",
+ ope->method);
+ for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
+ int argc;
+ struct ir_operation_overload_entry *ovle;
+ ovle = ope->overloadv + ovlc;
+
+ fprintf(dumpf,
+ "\t\t\toverload:%d\n", ovlc);
+
+ fprintf(dumpf,
+ "\t\t\t\treturn type:%p\n",
+ ovle->type);
+
+ fprintf(dumpf,
+ "\t\t\t\targuments:%d\n",
+ ovle->argumentc);
+
+ fprintf(dumpf,
+ "\t\t\t\toptionals:%d\n",
+ ovle->optionalc);
+
+ fprintf(dumpf,
+ "\t\t\t\telipsis:%d\n",
+ ovle->elipsisc);
+
+ for (argc = 0; argc < ovle->argumentc;
argc++) {
+ struct ir_operation_argument_entry
*arge;
+ arge = ovle->argumentv + argc;
+
+ fprintf(dumpf,
+ "\t\t\t\t\t%s\n",
+ arge->name);
+
+ if (arge->optionalc != 0) {
+ fprintf(dumpf,
+
"\t\t\t\t\t\toptional:%d\n",
+ arge->optionalc);
+ }
+
+ if (arge->elipsisc != 0) {
+ fprintf(dumpf,
+
"\t\t\t\t\t\telipsis:%d\n",
+ arge->elipsisc);
+ }
+
+ }
+ }
+ }
+ }
+
+ if (ecur->attributec > 0) {
+ int attrc = ecur->attributec;
+ struct ir_attribute_entry *attre;
+
+ fprintf(dumpf, "\t%d attributes\n", attrc);
+
+ attre = ecur->attributev;
+ while (attre != NULL) {
+ fprintf(dumpf, "\t\t%s %p",
+ attre->name,
+ attre->getter);
+ if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
+ fprintf(dumpf, " %p\n",
attre->setter);
+ } else {
+ fprintf(dumpf, "\n");
+ }
+ attre++;
+ attrc--;
+ if (attrc == 0) {
+ break;
+ }
+ }
+ }
+ if (ecur->constantc > 0) {
+ int idx;
+
+ fprintf(dumpf, "\t%d constants\n",
+ ecur->constantc);
+
+ for (idx = 0; idx < ecur->constantc; idx++) {
+ struct ir_constant_entry *cone;
+ cone = ecur->constantv + idx;
+ fprintf(dumpf, "\t\t%s\n",
+ cone->name);
+ }
+ }
+ ecur++;
+ }
+
+ fclose(dumpf);
+
+ return 0;
+}
+
+int ir_dumpdot(struct ir *index)
+{
+ FILE *dumpf;
+ int eidx;
+ struct ir_interface_entry *ecur;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("interface.dot", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ fprintf(dumpf, "digraph interfaces {\n");
+
+ fprintf(dumpf, "node [shape=box]\n");
+
+ ecur = index->interfaces;
+ for (eidx = 0; eidx < index->interfacec; eidx++) {
+ fprintf(dumpf, "%04d [label=\"%s\"", eidx,
ecur->name);
+ if (ecur->noobject == true) {
+ /* noobject interfaces in red */
+ fprintf(dumpf, "fontcolor=\"red\"");
+ } else if (ecur->class != NULL) {
+ /* interfaces bound to a class are shown in blue */
+ fprintf(dumpf, "fontcolor=\"blue\"");
+ }
+ fprintf(dumpf, "];\n");
+ ecur++;
+ }
+
+ ecur = index->interfaces;
+ for (eidx = 0; eidx < index->interfacec; eidx++) {
+ if (index->interfaces[eidx].inherit_idx != -1) {
+ fprintf(dumpf, "%04d -> %04d;\n",
+ eidx, index->interfaces[eidx].inherit_idx);
+ }
+ }
+
+ fprintf(dumpf, "}\n");
+
+ fclose(dumpf);
+
+ return 0;
+}
+
+struct ir_interface_entry *
+ir_inherit_entry(struct ir *map,
+ struct ir_interface_entry *entry)
+{
+ struct ir_interface_entry *res = NULL;
+
+ if ((entry != NULL) &&
+ (entry->inherit_idx != -1)) {
+ res = &map->interfaces[entry->inherit_idx];
+ }
+ return res;
+}
diff --git a/src/ir.h b/src/ir.h
new file mode 100644
index 0000000..4d0365e
--- /dev/null
+++ b/src/ir.h
@@ -0,0 +1,151 @@
+/* intermediate representation of WebIDL and binding data
+ *
+ * This file is part of nsgenbind.
+ * Licensed under the MIT License,
+ *
http://www.opensource.org/licenses/mit-license.php
+ * Copyright 2012 Vincent Sanders <vince(a)netsurf-browser.org>
+ */
+
+#ifndef nsgenbind_ir_h
+#define nsgenbind_ir_h
+
+struct genbind_node;
+struct webidl_node;
+
+/**
+ * map entry for each argument of an overload on an operation
+ */
+struct ir_operation_argument_entry {
+ const char *name;
+
+ int optionalc; /**< 1 if the argument is optional */
+ int elipsisc; /**< 1 if the argument is an elipsis */
+
+ struct webidl_node *node;
+};
+
+/** map entry for each overload of an operation */
+struct ir_operation_overload_entry {
+ struct webidl_node *type; /**< The return type of this overload */
+
+ int optionalc; /**< Number of parameters that are optional */
+ int elipsisc; /**< Number of elipsis parameters */
+
+ int argumentc; /**< the number of parameters */
+ struct ir_operation_argument_entry *argumentv;
+};
+
+/** map entry for operations on an interface */
+struct ir_operation_entry {
+ const char *name; /** operation name */
+ struct webidl_node *node; /**< AST operation node */
+ struct genbind_node *method; /**< method from binding */
+
+ int overloadc; /**< Number of overloads of this operation */
+ struct ir_operation_overload_entry *overloadv;
+};
+
+/** map entry for attributes on an interface */
+struct ir_attribute_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST attribute node */
+ enum webidl_type_modifier modifier;
+ struct genbind_node *getter; /**< getter from binding */
+ struct genbind_node *setter; /**< getter from binding */
+};
+
+/** map entry for constants on an interface */
+struct ir_constant_entry {
+ const char *name; /** attribute name */
+ struct webidl_node *node; /**< AST constant node */
+};
+
+/** map entry for an interface */
+struct ir_interface_entry {
+ const char *name; /** interface name */
+ struct webidl_node *node; /**< AST interface node */
+ const char *inherit_name; /**< Name of interface inhertited from */
+ int inherit_idx; /**< index into map of inherited interface or -1 for
+ * not in map
+ */
+ int refcount; /**< number of interfacess in map that refer to this
+ * interface
+ */
+ bool noobject; /**< flag indicating if no interface object should eb
+ * generated. This allows for interfaces which do not
+ * generate code. For implements (mixin) interfaces
+ */
+ bool primary_global; /**< flag indicating the interface is the primary
+ * global javascript object.
+ */
+
+ int operationc; /**< number of operations on interface */
+ struct ir_operation_entry *operationv;
+
+ int attributec; /**< number of attributes on interface */
+ struct ir_attribute_entry *attributev;
+
+ int constantc; /**< number of constants on interface */
+ struct ir_constant_entry *constantv;
+
+
+ struct genbind_node *class; /**< class from binding (if any) */
+
+ /* The variables are created and used by the output generation but
+ * rtaher than have another allocation and pointer the data they are
+ * just inline here.
+ */
+
+ char *filename; /**< filename used for output */
+
+ char *class_name; /**< the interface name converted to output
+ * appropriate value. e.g. generators targetting c
+ * might lowercase the name or add underscores
+ * instead of caps
+ */
+ int class_init_argc; /**< The number of parameters on the class
+ * initializer.
+ */
+};
+
+/** map entry for a dictionary */
+struct ir_dictionary_entry {
+ const char *name; /** dictionary name */
+ struct webidl_node *node; /**< AST dictionary node */
+ const char *inherit_name; /**< Name of interface inhertited from */
+};
+
+/** intermediate representation of WebIDL and binding data */
+struct ir {
+ int interfacec; /**< count of interfaces */
+ struct ir_interface_entry *interfaces; /**< interface entries */
+
+ int dictionaryc; /**< count of dictionaries */
+ struct ir_dictionary_entry *dictionaries; /**< dictionary entries */
+
+ /** The AST node of the binding information */
+ struct genbind_node *binding_node;
+
+ /** Root AST node of the webIDL */
+ struct webidl_node *webidl;
+};
+
+/**
+ * Create a new interface map
+ */
+int ir_new(struct genbind_node *genbind,
+ struct webidl_node *webidl,
+ struct ir **map_out);
+
+int ir_dump(struct ir *map);
+
+int ir_dumpdot(struct ir *map);
+
+/**
+ * interface map parent entry
+ *
+ * \return inherit entry or NULL if there is not one
+ */
+struct ir_interface_entry *ir_inherit_entry(struct ir *map, struct ir_interface_entry
*entry);
+
+#endif
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index 9558b95..135c5c0 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -17,7 +17,7 @@
#include "options.h"
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
-#include "interface-map.h"
+#include "ir.h"
#include "jsapi-libdom.h"
#include "duk-libdom.h"
@@ -192,7 +192,7 @@ int main(int argc, char **argv)
int res;
struct genbind_node *genbind_root = NULL;
struct webidl_node *webidl_root = NULL;
- struct interface_map *interface_map = NULL;
+ struct ir *ir = NULL;
enum bindingtype_e bindingtype;
options = process_cmdline(argc, argv);
@@ -225,20 +225,20 @@ int main(int argc, char **argv)
/* debug dump of web idl AST */
webidl_dump_ast(webidl_root);
- /* generate map of WebIDL interfaces sorted by inheritance */
- res = interface_map_new(genbind_root, webidl_root, &interface_map);
+ /* generate intermediate representation */
+ res = ir_new(genbind_root, webidl_root, &ir);
if (res != 0) {
return 5;
}
- /* dump the interface mapping */
- interface_map_dump(interface_map);
- interface_map_dumpdot(interface_map);
+ /* dump the intermediate representation */
+ ir_dump(ir);
+ ir_dumpdot(ir);
/* generate binding */
switch (bindingtype) {
case BINDINGTYPE_DUK_LIBDOM:
- res = duk_libdom_output(interface_map);
+ res = duk_libdom_output(ir);
break;
default:
commitdiff
http://git.netsurf-browser.org/nsgenbind.git/commit/?id=40cd6a199d8a5f92f...
commit 40cd6a199d8a5f92f71c5638f4da021a779e7a5c
Author: Vincent Sanders <vince(a)kyllikki.org>
Commit: Vincent Sanders <vince(a)kyllikki.org>
Add WebIDL parsing of dictionaries
This adds correct parsing of dictionaries into the AST. These entries
in the AST are not yet used but do not affect generation of
interfaces.
diff --git a/src/interface-map.c b/src/interface-map.c
index a5a672a..822892f 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -596,7 +596,7 @@ int interface_map_new(struct genbind_node *genbind,
webidl_node_find_type(
webidl_node_getnode(node),
NULL,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
+ WEBIDL_NODE_TYPE_INHERITANCE));
/* is the interface marked as not generating an object */
if (webidl_node_find_type_ident(
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 87e3485..dc78e1f 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -96,6 +96,7 @@ webidl_node_add(struct webidl_node *node, struct webidl_node *list)
switch (node->type) {
case WEBIDL_NODE_TYPE_ROOT:
case WEBIDL_NODE_TYPE_INTERFACE:
+ case WEBIDL_NODE_TYPE_DICTIONARY:
case WEBIDL_NODE_TYPE_LIST:
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
@@ -265,7 +266,7 @@ char *webidl_node_gettext(struct webidl_node *node)
switch(node->type) {
case WEBIDL_NODE_TYPE_IDENT:
- case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
+ case WEBIDL_NODE_TYPE_INHERITANCE:
case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
case WEBIDL_NODE_TYPE_LITERAL_STRING:
return node->r.text;
@@ -311,6 +312,7 @@ struct webidl_node *webidl_node_getnode(struct webidl_node *node)
switch (node->type) {
case WEBIDL_NODE_TYPE_ROOT:
case WEBIDL_NODE_TYPE_INTERFACE:
+ case WEBIDL_NODE_TYPE_DICTIONARY:
case WEBIDL_NODE_TYPE_LIST:
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
@@ -338,7 +340,7 @@ static const char *webidl_node_type_to_str(enum webidl_node_type
type)
case WEBIDL_NODE_TYPE_IDENT:
return "Ident";
- case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
+ case WEBIDL_NODE_TYPE_INHERITANCE:
return "Inherit";
case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
@@ -347,6 +349,9 @@ static const char *webidl_node_type_to_str(enum webidl_node_type
type)
case WEBIDL_NODE_TYPE_INTERFACE:
return "Interface";
+ case WEBIDL_NODE_TYPE_DICTIONARY:
+ return "Dictionary";
+
case WEBIDL_NODE_TYPE_LIST:
return "List";
@@ -600,7 +605,7 @@ static int implements_copy_nodes(struct webidl_node *src_node,
while (src != NULL) {
if (src->type == WEBIDL_NODE_TYPE_LIST) {
- /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE */
+ /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INHERITANCE */
dst = webidl_node_new(src->type, dst, src->r.text);
}
src = src->l;
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 109159f..0872965 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -19,14 +19,16 @@ enum webidl_node_type {
WEBIDL_NODE_TYPE_LIST,
/* non structural node types */
- WEBIDL_NODE_TYPE_INTERFACE,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
+ WEBIDL_NODE_TYPE_INTERFACE, /**< node is an interface*/
WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS,
WEBIDL_NODE_TYPE_ATTRIBUTE,
WEBIDL_NODE_TYPE_OPERATION,
WEBIDL_NODE_TYPE_CONST,
+ WEBIDL_NODE_TYPE_DICTIONARY, /**< node is a dictionary */
+
+ WEBIDL_NODE_TYPE_INHERITANCE, /**< node has inheritance */
WEBIDL_NODE_TYPE_SPECIAL,
WEBIDL_NODE_TYPE_ARGUMENT,
WEBIDL_NODE_TYPE_OPTIONAL,
diff --git a/src/webidl-lexer.l b/src/webidl-lexer.l
index 8c68fdf..4788610 100644
--- a/src/webidl-lexer.l
+++ b/src/webidl-lexer.l
@@ -213,6 +213,8 @@ iterable return TOK_ITERABLE;
legacyiterable return TOK_LEGACYITERABLE;
+required return TOK_REQUIRED;
+
{identifier} {
/* A leading "_" is used to escape an identifier from
* looking like a reserved word terminal. */
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 42fed63..406962f 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -66,7 +66,6 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char
*str)
%token TOK_BOOLEAN
%token TOK_BYTE
%token TOK_CALLBACK
-%token TOK_LEGACYCALLER
%token TOK_CONST
%token TOK_CREATOR
%token TOK_DATE
@@ -87,6 +86,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char
*str)
%token TOK_INHERIT
%token TOK_INTERFACE
%token TOK_ITERABLE
+%token TOK_LEGACYCALLER
%token TOK_LEGACYITERABLE
%token TOK_LONG
%token TOK_MODULE
@@ -102,6 +102,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%token TOK_PROMISE
%token TOK_RAISES
%token TOK_READONLY
+%token TOK_REQUIRED
%token TOK_SETRAISES
%token TOK_SETTER
%token TOK_SEQUENCE
@@ -134,6 +135,8 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <node> Dictionary
%type <node> PartialDictionary
+%type <node> DictionaryMembers
+%type <node> DictionaryMember
%type <node> Exception
%type <node> Enum
@@ -151,6 +154,8 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <node> Attribute
%type <node> AttributeRest
+%type <text> AttributeName
+%type <text> AttributeNameKeyword
%type <node> AttributeOrOperation
%type <node> StringifierAttributeOrOperation
%type <node> Const
@@ -201,6 +206,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <isit> ReadOnly
%type <isit> OptionalLong
%type <isit> Inherit
+ //%type <isit> Required
%type <node> ExtendedAttributeList
%type <node> ExtendedAttributes
@@ -210,6 +216,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <text> Other
%type <text> OtherOrComma
+
%%
/* [1] default rule to add built AST to passed in one, altered from
@@ -274,34 +281,40 @@ CallbackRestOrInterface:
Interface:
TOK_INTERFACE TOK_IDENTIFIER Inheritance '{' InterfaceMembers '}'
';'
{
- /* extend interface with additional members */
- struct webidl_node *interface_node;
- struct webidl_node *members = NULL;
+ /* extend interface with additional members */
+ struct webidl_node *interface_node;
+ struct webidl_node *members = NULL;
- if ($3 != NULL) {
- members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
members, $3);
- }
+ if ($3 != NULL) {
+ members = webidl_node_new(WEBIDL_NODE_TYPE_INHERITANCE,
+ members,
+ $3);
+ }
- members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
- interface_node = webidl_node_find_type_ident(*webidl_ast,
+ interface_node = webidl_node_find_type_ident(*webidl_ast,
WEBIDL_NODE_TYPE_INTERFACE,
- $2);
+ $2);
- if (interface_node == NULL) {
- /* no existing interface - create one with ident */
- members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2);
+ if (interface_node == NULL) {
+ /* no existing interface - create one with ident */
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, members);
- } else {
- /* update the existing interface */
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE,
+ NULL,
+ members);
+ } else {
+ /* update the existing interface */
- /* link member node into interfaces_node */
- webidl_node_add(interface_node, members);
+ /* link member node into interfaces_node */
+ webidl_node_add(interface_node, members);
- $$ = NULL; /* updating so no need to add a new node */
- }
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;
@@ -353,64 +366,65 @@ PartialInterface:
/* [9] slightly altered from original grammar to be left recursive */
InterfaceMembers:
- /* empty */
{
- $$ = NULL;
+ $$ = NULL; /* empty */
}
|
InterfaceMembers ExtendedAttributeList InterfaceMember
- /* This needs to deal with members with the same identifier which
- * indicate polymorphism. this is handled in the AST by adding the
- * argument lists for each polymorphism to the same
- * WEBIDL_NODE_TYPE_OPERATION
- *
- * @todo need to consider qualifer/stringifier compatibility
- */
- {
- struct webidl_node *member_node;
- struct webidl_node *ident_node;
- struct webidl_node *list_node;
-
- ident_node = webidl_node_find_type(webidl_node_getnode($3),
- NULL,
- WEBIDL_NODE_TYPE_IDENT);
-
- list_node = webidl_node_find_type(webidl_node_getnode($3),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
-
- if (ident_node == NULL) {
- /* something with no ident - possibly constructors? */
- /* @todo understand this better */
-
- $$ = webidl_node_prepend($1, $3);
-
- } else if (list_node == NULL) {
- /* member with no argument list, usually an attribute, cannot
- * be polymorphic
+ {
+ /* This needs to deal with members with the same
+ * identifier which indicate polymorphism. this is
+ * handled in the AST by adding the argument lists for
+ * each polymorphism to the same
+ * WEBIDL_NODE_TYPE_OPERATION
+ *
+ * @todo need to consider qualifer/stringifier compatibility
*/
+ struct webidl_node *member_node;
+ struct webidl_node *ident_node;
+ struct webidl_node *list_node;
- /* add extended attributes to parameter list */
- webidl_node_add($3, $2);
+ ident_node = webidl_node_find_type(webidl_node_getnode($3),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT);
- $$ = webidl_node_prepend($1, $3);
+ list_node = webidl_node_find_type(webidl_node_getnode($3),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ if (ident_node == NULL) {
+ /* something with no ident - possibly constructors? */
+ /* @todo understand this better */
+
+ $$ = webidl_node_prepend($1, $3);
+
+ } else if (list_node == NULL) {
+ /* member with no argument list, usually an
+ * attribute, cannot be polymorphic
+ */
+
+ /* add extended attributes to parameter list */
+ webidl_node_add($3, $2);
+
+ $$ = webidl_node_prepend($1, $3);
- } else {
- /* add extended attributes to parameter list */
- webidl_node_add(list_node, $2);
-
- /* has an arguemnt list so can be polymorphic */
- member_node = webidl_node_find_type_ident($1,
- webidl_node_gettype($3),
- webidl_node_gettext(ident_node));
- if (member_node == NULL) {
- /* not a member with that ident already present */
- $$ = webidl_node_prepend($1, $3);
} else {
- webidl_node_add(member_node, list_node);
- $$ = $1; /* updated existing node do not add new one */
+ /* add extended attributes to parameter list */
+ webidl_node_add(list_node, $2);
+
+ /* has an arguemnt list so can be polymorphic */
+ member_node = webidl_node_find_type_ident(
+ $1,
+ webidl_node_gettype($3),
+ webidl_node_gettext(ident_node));
+ if (member_node == NULL) {
+ /* not a member with that ident already present */
+ $$ = webidl_node_prepend($1, $3);
+ } else {
+ webidl_node_add(member_node, list_node);
+ $$ = $1; /* updated existing node do not add new one */
+ }
}
- }
}
;
@@ -433,28 +447,134 @@ InterfaceMember:
Dictionary:
TOK_DICTIONARY TOK_IDENTIFIER Inheritance '{' DictionaryMembers
'}' ';'
{
- $$ = NULL;
+ /* extend dictionary with additional members */
+ struct webidl_node *dictionary_node;
+ struct webidl_node *members = NULL;
+
+ if ($3 != NULL) {
+ members = webidl_node_new(WEBIDL_NODE_TYPE_INHERITANCE,
+ members,
+ $3);
+ }
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
+
+ dictionary_node = webidl_node_find_type_ident(
+ *webidl_ast,
+ WEBIDL_NODE_TYPE_DICTIONARY,
+ $2);
+
+ if (dictionary_node == NULL) {
+ /* no existing interface - create one with ident */
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_DICTIONARY,
+ NULL,
+ members);
+ } else {
+ /* update the existing interface */
+
+ /* link member node into interfaces_node */
+ webidl_node_add(dictionary_node, members);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;
- /* [12] */
+ /* SE[12] */
DictionaryMembers:
- /* empty */
+ {
+ $$ = NULL; /* empty */
+ }
|
ExtendedAttributeList DictionaryMember DictionaryMembers
+ {
+ /** \todo handle ExtendedAttributeList */
+ $$ = webidl_node_append($3, $2);
+ }
;
- /* [13] */
+ /* SE[13]
+ * Second edition introduces Required except required type may not
+ * have default so why not express this in grammar here and remove
+ * rule 14?
+ */
DictionaryMember:
+ TOK_REQUIRED Type TOK_IDENTIFIER ';'
+ {
+ struct webidl_node *member;
+ /* add name */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $3);
+ /* add type node */
+ member = webidl_node_prepend(member, $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, member);
+ }
+ |
Type TOK_IDENTIFIER Default ';'
+ {
+ struct webidl_node *member;
+ /* add name */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $2);
+ /* add default */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_OPTIONAL, member, $3);
+ /* add type node */
+ member = webidl_node_prepend(member, $1);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, member);
+ }
;
+/* SE[14] */
+//Required:
+// {
+// $$ = false; /* empty */
+// }
+// |
+// TOK_REQUIRED
+// {
+// $$ = true;
+// }
+// ;
+
/* [14] */
PartialDictionary:
TOK_DICTIONARY TOK_IDENTIFIER '{' DictionaryMembers '}'
';'
{
- $$ = NULL;
+ /* extend dictionary with additional members */
+ struct webidl_node *members;
+ struct webidl_node *dictionary_node;
+
+ dictionary_node = webidl_node_find_type_ident(
+ *webidl_ast,
+ WEBIDL_NODE_TYPE_DICTIONARY,
+ $2);
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, $4);
+
+ if (dictionary_node == NULL) {
+ /* doesnt already exist so create it */
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_DICTIONARY,
+ NULL,
+ members);
+ } else {
+ /* update the existing dictionary */
+
+ /* link member node into dictionary node */
+ webidl_node_add(dictionary_node, members);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
+ ;
/* [15] */
Default:
@@ -778,12 +898,25 @@ StaticMemberRest:
/* SE[42] */
AttributeRest:
- TOK_ATTRIBUTE Type TOK_IDENTIFIER ';'
+ TOK_ATTRIBUTE Type AttributeName ';'
{
$$ = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, $2, $3);
}
;
+/* SE[43] */
+AttributeName:
+ AttributeNameKeyword
+ |
+ TOK_IDENTIFIER
+ ;
+
+/* SE[44] */
+AttributeNameKeyword:
+ TOK_REQUIRED
+ {
+ $$ = strdup("required");
+ }
/* [33]
* SE[45]
@@ -1333,7 +1466,9 @@ Other:
}
;
- /* [55] */
+ /* [55]
+ * SE[71] extended with new keywords
+ */
ArgumentNameKeyword:
TOK_ATTRIBUTE
{
@@ -1395,16 +1530,31 @@ ArgumentNameKeyword:
$$ = strdup("interface");
}
|
+ TOK_ITERABLE
+ {
+ $$ = strdup("iterable");
+ }
+ |
TOK_LEGACYCALLER
{
$$ = strdup("legacycaller");
}
|
+ TOK_LEGACYITERABLE
+ {
+ $$ = strdup("legacyiterable");
+ }
+ |
TOK_PARTIAL
{
$$ = strdup("partial");
}
|
+ TOK_REQUIRED
+ {
+ $$ = strdup("required");
+ }
+ |
TOK_SETTER
{
$$ = strdup("setter");
-----------------------------------------------------------------------
Summary of changes:
src/Makefile | 4 +-
src/duk-libdom.c | 487 ++++++++++++++++++++++++++++-------------
src/duk-libdom.h | 2 +-
src/{interface-map.c => ir.c} | 476 ++++++++++++++++++++++++----------------
src/{interface-map.h => ir.h} | 85 ++++---
src/nsgenbind.c | 16 +-
src/webidl-ast.c | 11 +-
src/webidl-ast.h | 6 +-
src/webidl-lexer.l | 2 +
src/webidl-parser.y | 300 ++++++++++++++++++-------
10 files changed, 917 insertions(+), 472 deletions(-)
rename src/{interface-map.c => ir.c} (67%)
rename src/{interface-map.h => ir.h} (70%)
diff --git a/src/Makefile b/src/Makefile
index 8b034fe..9905baf 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,8 +1,8 @@
CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/ -g -DYYENABLE_NLS=0
# Sources in this directory
-DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.c \
- interface-map.c duk-libdom.c
+DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.c ir.c \
+ duk-libdom.c
# jsapi-libdom.c jsapi-libdom-function.c jsapi-libdom-property.c jsapi-libdom-init.c
jsapi-libdom-new.c jsapi-libdom-infmap.c jsapi-libdom-jsclass.c
SOURCES := $(SOURCES) $(BUILDDIR)/nsgenbind-parser.c $(BUILDDIR)/nsgenbind-lexer.c
$(BUILDDIR)/webidl-parser.c $(BUILDDIR)/webidl-lexer.c
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index aad7bb6..3e20d13 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -19,7 +19,7 @@
#include "utils.h"
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
-#include "interface-map.h"
+#include "ir.h"
#include "duk-libdom.h"
/** prefix for all generated functions */
@@ -293,7 +293,7 @@ static int output_tool_preface(FILE* outf)
* - if the previous character in the input name was uppercase and the current
* one is lowercase insert an underscore before the *previous* character.
*/
-static char *gen_class_name(struct interface_map_entry *interfacee)
+static char *gen_class_name(struct ir_entry *interfacee)
{
const char *inc;
char *outc;
@@ -301,7 +301,8 @@ static char *gen_class_name(struct interface_map_entry *interfacee)
int wasupper;
/* enpty strings are a bad idea */
- if ((interfacee->name == NULL) || (interfacee->name[0] == 0)) {
+ if ((interfacee->name == NULL) ||
+ (interfacee->name[0] == 0)) {
return NULL;
}
@@ -373,7 +374,7 @@ output_cdata(FILE* outf,
return res;
}
-static FILE *open_header(struct interface_map *interface_map, const char *name)
+static FILE *open_header(struct ir *ir, const char *name)
{
FILE *hdrf;
char *fname;
@@ -392,7 +393,7 @@ static FILE *open_header(struct interface_map *interface_map, const
char *name)
/* binding preface */
output_cdata(hdrf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PREFACE);
/* tool preface */
@@ -405,7 +406,7 @@ static FILE *open_header(struct interface_map *interface_map, const
char *name)
return hdrf;
}
-static int close_header(struct interface_map *interface_map,
+static int close_header(struct ir *ir,
FILE *hdrf,
const char *name)
{
@@ -420,7 +421,7 @@ static int close_header(struct interface_map *interface_map,
/* binding postface */
output_cdata(hdrf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_POSTFACE);
genb_fclose_tmp(hdrf, fname);
@@ -434,7 +435,7 @@ static int close_header(struct interface_map *interface_map,
* generate the interface constructor
*/
static int
-output_interface_constructor(FILE* outf, struct interface_map_entry *interfacee)
+output_interface_constructor(FILE* outf, struct ir_entry *interfacee)
{
int init_argc;
@@ -470,7 +471,7 @@ output_interface_constructor(FILE* outf, struct interface_map_entry
*interfacee)
* generate the interface destructor
*/
static int
-output_interface_destructor(FILE* outf, struct interface_map_entry *interfacee)
+output_interface_destructor(FILE* outf, struct ir_entry *interfacee)
{
/* destructor definition */
fprintf(outf,
@@ -498,8 +499,8 @@ output_interface_destructor(FILE* outf, struct interface_map_entry
*interfacee)
*/
static int
output_interface_inherit_init(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *init_node;
struct genbind_node *inh_init_node;
@@ -593,7 +594,7 @@ output_interface_inherit_init(FILE* outf,
static int
output_interface_init_declaration(FILE* outf,
- struct interface_map_entry *interfacee,
+ struct ir_entry *interfacee,
struct genbind_node *init_node)
{
struct genbind_node *param_node;
@@ -627,8 +628,8 @@ output_interface_init_declaration(FILE* outf,
static int
output_interface_init(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *init_node;
int res;
@@ -666,8 +667,8 @@ output_interface_init(FILE* outf,
static int
output_interface_fini(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite)
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *fini_node;
@@ -708,8 +709,8 @@ output_interface_fini(FILE* outf,
*/
static int
output_prototype_method(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
if (operatione->name != NULL) {
@@ -730,15 +731,16 @@ output_prototype_method(FILE* outf,
* generate prototype method definitions
*/
static int
-output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
+output_prototype_methods(FILE *outf, struct ir_entry *entry)
{
int opc;
int res = 0;
- for (opc = 0; opc < interfacee->operationc; opc++) {
- res = output_prototype_method(outf,
- interfacee,
- interfacee->operationv + opc);
+ for (opc = 0; opc < entry->u.interface.operationc; opc++) {
+ res = output_prototype_method(
+ outf,
+ entry,
+ entry->u.interface.operationv + opc);
if (res != 0) {
break;
}
@@ -750,8 +752,8 @@ output_prototype_methods(FILE *outf, struct interface_map_entry
*interfacee)
static int
output_prototype_attribute(FILE *outf,
- struct interface_map_entry *interfacee,
- struct interface_map_attribute_entry *attributee)
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *attributee)
{
if (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY) {
return output_populate_ro_property(outf,
@@ -767,14 +769,16 @@ output_prototype_attribute(FILE *outf,
* generate prototype attribute definitions
*/
static int
-output_prototype_attributes(FILE *outf, struct interface_map_entry *interfacee)
+output_prototype_attributes(FILE *outf, struct ir_entry *entry)
{
int attrc;
int res = 0;
- for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- res = output_prototype_attribute(outf,interfacee,
- interfacee->attributev + attrc);
+ for (attrc = 0; attrc < entry->u.interface.attributec; attrc++) {
+ res = output_prototype_attribute(
+ outf,
+ entry,
+ entry->u.interface.attributev + attrc);
if (res != 0) {
break;
}
@@ -791,7 +795,7 @@ output_prototype_attributes(FILE *outf, struct interface_map_entry
*interfacee)
*/
static int
output_prototype_constant(FILE *outf,
- struct interface_map_constant_entry *constante)
+ struct ir_constant_entry *constante)
{
int *value;
@@ -810,14 +814,15 @@ output_prototype_constant(FILE *outf,
* generate prototype constant definitions
*/
static int
-output_prototype_constants(FILE *outf, struct interface_map_entry *interfacee)
+output_prototype_constants(FILE *outf, struct ir_entry *entry)
{
int attrc;
int res = 0;
- for (attrc = 0; attrc < interfacee->constantc; attrc++) {
- res = output_prototype_constant(outf,
- interfacee->constantv + attrc);
+ for (attrc = 0; attrc < entry->u.interface.constantc; attrc++) {
+ res = output_prototype_constant(
+ outf,
+ entry->u.interface.constantv + attrc);
if (res != 0) {
break;
}
@@ -826,14 +831,46 @@ output_prototype_constants(FILE *outf, struct interface_map_entry
*interfacee)
return res;
}
+static int
+output_global_create_prototype(FILE* outf,
+ struct ir *ir,
+ struct ir_entry *interfacee)
+{
+ int idx;
+
+ fprintf(outf, "\t/* Create interface objects */\n");
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *entry;
+
+ entry = ir->entries + idx;
+
+ if (entry->type == IR_ENTRY_TYPE_INTERFACE) {
+
+ if (entry->u.interface.noobject) {
+ continue;
+ }
+
+ if (entry == interfacee) {
+ fprintf(outf, "\tduk_dup(ctx, 0);\n");
+ } else {
+ output_get_prototype(outf, entry->name);
+ }
+
+ fprintf(outf,
+ "\tdukky_inject_not_ctr(ctx, 0,
\"%s\");\n",
+ entry->name);
+ }
+ }
+ return 0;
+}
/**
* generate the interface prototype creator
*/
static int
output_interface_prototype(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_entry *inherite,
- struct interface_map *interface_map)
+ struct ir *ir,
+ struct ir_entry *interfacee,
+ struct ir_entry *inherite)
{
struct genbind_node *proto_node;
@@ -872,21 +909,8 @@ output_interface_prototype(FILE* outf,
/* if this is the global object, output all interfaces which do not
* prevent us from doing so
*/
- if (interfacee->primary_global) {
- fprintf(outf, "\t/* Create interface objects */\n");
- for (int idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacep;
-
- interfacep = interface_map->entries + idx;
- if (interfacep->noobject) continue;
- if (interfacep == interfacee)
- fprintf(outf, "\tduk_dup(ctx, 0);\n");
- else
- output_get_prototype(outf, interfacep->name);
- fprintf(outf,
- "\tdukky_inject_not_ctr(ctx, 0,
\"%s\");\n",
- interfacep->name);
- }
+ if (interfacee->u.interface.primary_global) {
+ output_global_create_prototype(outf, ir, interfacee);
}
/* generate setting of destructor */
@@ -910,8 +934,8 @@ output_interface_prototype(FILE* outf,
*/
static int
output_interface_elipsis_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -953,8 +977,8 @@ output_interface_elipsis_operation(FILE* outf,
*/
static int
output_interface_overloaded_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
@@ -992,8 +1016,8 @@ output_interface_overloaded_operation(FILE* outf,
*/
static int
output_interface_special_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
/* special method definition */
fprintf(outf, "/* Special method definition - UNIMPLEMENTED */\n\n");
@@ -1011,12 +1035,12 @@ output_interface_special_operation(FILE* outf,
*/
static int
output_operation_optional_defaults(FILE* outf,
- struct interface_map_operation_argument_entry *argumentv,
+ struct ir_operation_argument_entry *argumentv,
int argumentc)
{
int argc;
for (argc = 0; argc < argumentc; argc++) {
- struct interface_map_operation_argument_entry *cure;
+ struct ir_operation_argument_entry *cure;
struct webidl_node *lit_node; /* literal node */
enum webidl_node_type lit_type;
int *lit_int;
@@ -1077,12 +1101,12 @@ output_operation_optional_defaults(FILE* outf,
static int
output_operation_argument_type_check(
FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione,
- struct interface_map_operation_overload_entry *overloade,
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione,
+ struct ir_operation_overload_entry *overloade,
int argidx)
{
- struct interface_map_operation_argument_entry *argumente;
+ struct ir_operation_argument_entry *argumente;
struct webidl_node *type_node;
enum webidl_type *argument_type;
@@ -1168,11 +1192,11 @@ output_operation_argument_type_check(
*/
static int
output_interface_operation(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_operation_entry *operatione)
+ struct ir_entry *interfacee,
+ struct ir_operation_entry *operatione)
{
int cdatac; /* cdata blocks output */
- struct interface_map_operation_overload_entry *overloade;
+ struct ir_operation_overload_entry *overloade;
int fixedargc; /* number of non optional arguments */
int argidx; /* loop counter for arguments */
int optargc; /* loop counter for optional arguments */
@@ -1287,15 +1311,16 @@ output_interface_operation(FILE* outf,
* generate class methods for each interface operation
*/
static int
-output_interface_operations(FILE* outf, struct interface_map_entry *interfacee)
+output_interface_operations(FILE* outf, struct ir_entry *ife)
{
int opc;
int res = 0;
- for (opc = 0; opc < interfacee->operationc; opc++) {
- res = output_interface_operation(outf,
- interfacee,
- interfacee->operationv + opc);
+ for (opc = 0; opc < ife->u.interface.operationc; opc++) {
+ res = output_interface_operation(
+ outf,
+ ife,
+ ife->u.interface.operationv + opc);
if (res != 0) {
break;
}
@@ -1309,8 +1334,8 @@ output_interface_operations(FILE* outf, struct interface_map_entry
*interfacee)
*/
static int
output_interface_attribute(FILE* outf,
- struct interface_map_entry *interfacee,
- struct interface_map_attribute_entry *atributee)
+ struct ir_entry *interfacee,
+ struct ir_attribute_entry *atributee)
{
int cdatac;
@@ -1369,15 +1394,15 @@ output_interface_attribute(FILE* outf,
* generate class property getters and setters for each interface attribute
*/
static int
-output_interface_attributes(FILE* outf,
- struct interface_map_entry *interfacee)
+output_interface_attributes(FILE* outf, struct ir_entry *ife)
{
int attrc;
- for (attrc = 0; attrc < interfacee->attributec; attrc++) {
- output_interface_attribute(outf,
- interfacee,
- interfacee->attributev + attrc);
+ for (attrc = 0; attrc < ife->u.interface.attributec; attrc++) {
+ output_interface_attribute(
+ outf,
+ ife,
+ ife->u.interface.attributev + attrc);
}
return 0;
@@ -1407,29 +1432,110 @@ static int output_tool_prologue(FILE* outf)
}
/**
- * generate a source file to implement an interface using duk and libdom.
+ * generate a source file to implement a dictionary using duk and libdom.
*/
-static int output_interface(struct interface_map *interface_map,
- struct interface_map_entry *interfacee)
+static int output_dictionary(struct ir *ir, struct ir_entry *dictionarye)
{
FILE *ifacef;
- int ifacenamelen;
- struct interface_map_entry *inherite;
+ struct ir_entry *inherite;
int res = 0;
- /* do not generate class for interfaces marked no output */
- if (interfacee->noobject) {
- return 0;
+ /* open output file */
+ ifacef = genb_fopen_tmp(dictionarye->filename);
+ if (ifacef == NULL) {
+ return -1;
+ }
+
+ /* find parent interface entry */
+ inherite = ir_inherit_entry(ir, dictionarye);
+
+ /* tool preface */
+ output_tool_preface(ifacef);
+
+ /* binding preface */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_PREFACE);
+
+ /* class preface */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_PREFACE);
+
+ /* tool prologue */
+ output_tool_prologue(ifacef);
+
+ /* binding prologue */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_PROLOGUE);
+
+ /* class prologue */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_PROLOGUE);
+
+ fprintf(ifacef, "\n");
+
+ /* initialisor */
+ res = output_interface_init(ifacef, dictionarye, inherite);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* finaliser */
+ res = output_interface_fini(ifacef, dictionarye, inherite);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* constructor */
+ res = output_interface_constructor(ifacef, dictionarye);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* destructor */
+ res = output_interface_destructor(ifacef, dictionarye);
+ if (res != 0) {
+ goto op_error;
+ }
+
+ /* prototype */
+ res = output_interface_prototype(ifacef, ir, dictionarye, inherite);
+ if (res != 0) {
+ goto op_error;
}
- /* compute class name */
- interfacee->class_name = gen_class_name(interfacee);
- /* generate source filename */
- ifacenamelen = strlen(interfacee->class_name) + 4;
- interfacee->filename = malloc(ifacenamelen);
- snprintf(interfacee->filename, ifacenamelen,
- "%s.c", interfacee->class_name);
+ fprintf(ifacef, "\n");
+
+ /* class epilogue */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_EPILOGUE);
+
+ /* binding epilogue */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_EPILOGUE);
+
+ /* class postface */
+ output_cdata(ifacef, dictionarye->class, GENBIND_NODE_TYPE_POSTFACE);
+
+ /* binding postface */
+ output_cdata(ifacef,
+ ir->binding_node,
+ GENBIND_NODE_TYPE_POSTFACE);
+
+op_error:
+ genb_fclose_tmp(ifacef, dictionarye->filename);
+
+ return res;
+}
+
+/**
+ * generate a source file to implement an interface using duk and libdom.
+ */
+static int output_interface(struct ir *ir, struct ir_entry *interfacee)
+{
+ FILE *ifacef;
+ struct ir_entry *inherite;
+ int res = 0;
/* open output file */
ifacef = genb_fopen_tmp(interfacee->filename);
@@ -1438,14 +1544,14 @@ static int output_interface(struct interface_map *interface_map,
}
/* find parent interface entry */
- inherite = interface_map_inherit_entry(interface_map, interfacee);
+ inherite = ir_inherit_entry(ir, interfacee);
/* tool preface */
output_tool_preface(ifacef);
/* binding preface */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PREFACE);
/* class preface */
@@ -1456,7 +1562,7 @@ static int output_interface(struct interface_map *interface_map,
/* binding prologue */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PROLOGUE);
/* class prologue */
@@ -1486,7 +1592,7 @@ static int output_interface(struct interface_map *interface_map,
output_interface_attributes(ifacef, interfacee);
/* prototype */
- output_interface_prototype(ifacef, interfacee, inherite, interface_map);
+ output_interface_prototype(ifacef, ir, interfacee, inherite);
fprintf(ifacef, "\n");
@@ -1495,7 +1601,7 @@ static int output_interface(struct interface_map *interface_map,
/* binding epilogue */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_EPILOGUE);
/* class postface */
@@ -1503,7 +1609,7 @@ static int output_interface(struct interface_map *interface_map,
/* binding postface */
output_cdata(ifacef,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_POSTFACE);
op_error:
@@ -1516,33 +1622,47 @@ op_error:
* generate private header
*/
static int
-output_private_header(struct interface_map *interface_map)
+output_private_header(struct ir *ir)
{
int idx;
FILE *privf;
/* open header */
- privf = open_header(interface_map, "private");
+ privf = open_header(ir, "private");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
- struct interface_map_entry *inherite;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
+ struct ir_entry *inherite;
struct genbind_node *priv_node;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->entries + idx;
/* do not generate private structs for interfaces marked no
* output
*/
- if (interfacee->noobject) {
+ if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) &&
+ (interfacee->u.interface.noobject)) {
continue;
}
- /* find parent interface entry */
- inherite = interface_map_inherit_entry(interface_map,
- interfacee);
+ switch (interfacee->type) {
+ case IR_ENTRY_TYPE_INTERFACE:
+ fprintf(privf,
+ "/* Private data for %s interface */\n",
+ interfacee->name);
+ break;
+
+ case IR_ENTRY_TYPE_DICTIONARY:
+ fprintf(privf,
+ "/* Private data for %s dictionary */\n",
+ interfacee->name);
+ break;
+ }
fprintf(privf, "typedef struct {\n");
+
+ /* find parent entry and include in private */
+ inherite = ir_inherit_entry(ir, interfacee);
if (inherite != NULL) {
fprintf(privf, "\t%s_private_t parent;\n",
inherite->class_name);
@@ -1585,7 +1705,7 @@ output_private_header(struct interface_map *interface_map)
}
- close_header(interface_map, privf, "private");
+ close_header(ir, privf, "private");
return 0;
}
@@ -1594,24 +1714,25 @@ output_private_header(struct interface_map *interface_map)
* generate prototype header
*/
static int
-output_prototype_header(struct interface_map *interface_map)
+output_prototype_header(struct ir *ir)
{
int idx;
FILE *protof;
/* open header */
- protof = open_header(interface_map, "prototype");
+ protof = open_header(ir, "prototype");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
struct genbind_node *init_node;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->entries + idx;
/* do not generate prototype declarations for interfaces marked
* no output
*/
- if (interfacee->noobject) {
+ if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) &&
+ (interfacee->u.interface.noobject)) {
continue;
}
@@ -1641,7 +1762,7 @@ output_prototype_header(struct interface_map *interface_map)
fprintf(protof, ";\n\n");
}
- close_header(interface_map, protof, "prototype");
+ close_header(ir, protof, "prototype");
return 0;
}
@@ -1650,7 +1771,7 @@ output_prototype_header(struct interface_map *interface_map)
* generate makefile fragment
*/
static int
-output_makefile(struct interface_map *interface_map)
+output_makefile(struct ir *ir)
{
int idx;
FILE *makef;
@@ -1664,13 +1785,14 @@ output_makefile(struct interface_map *interface_map)
fprintf(makef, "# duk libdom makefile fragment\n\n");
fprintf(makef, "NSGENBIND_SOURCES:=binding.c ");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->entries + idx;
/* no source for interfaces marked no output */
- if (interfacee->noobject) {
+ if ((interfacee->type == IR_ENTRY_TYPE_INTERFACE) &&
+ (interfacee->u.interface.noobject)) {
continue;
}
@@ -1695,12 +1817,12 @@ output_makefile(struct interface_map *interface_map)
* the primary global (if any) generated last.
*/
static int
-output_binding_header(struct interface_map *interface_map)
+output_binding_header(struct ir *ir)
{
FILE *bindf;
/* open header */
- bindf = open_header(interface_map, "binding");
+ bindf = open_header(ir, "binding");
fprintf(bindf,
"#define _MAGIC(S) (\"%s\" S)\n"
@@ -1735,7 +1857,7 @@ output_binding_header(struct interface_map *interface_map)
fprintf(bindf,
"duk_ret_t %s_create_prototypes(duk_context *ctx);\n", DLPFX);
- close_header(interface_map, bindf, "binding");
+ close_header(ir, bindf, "binding");
return 0;
}
@@ -1748,11 +1870,11 @@ output_binding_header(struct interface_map *interface_map)
* implementations.
*/
static int
-output_binding_src(struct interface_map *interface_map)
+output_binding_src(struct ir *ir)
{
int idx;
FILE *bindf;
- struct interface_map_entry *pglobale = NULL;
+ struct ir_entry *pglobale = NULL;
char *proto_name;
/* open output file */
@@ -1766,14 +1888,14 @@ output_binding_src(struct interface_map *interface_map)
/* binding preface */
output_cdata(bindf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PREFACE);
output_tool_prologue(bindf);
/* binding prologue */
output_cdata(bindf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_PROLOGUE);
@@ -1893,23 +2015,24 @@ output_binding_src(struct interface_map *interface_map)
fprintf(bindf, "{\n");
- for (idx = 0; idx < interface_map->entryc; idx++) {
- struct interface_map_entry *interfacee;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *interfacee;
- interfacee = interface_map->entries + idx;
+ interfacee = ir->entries + idx;
/* do not generate prototype calls for interfaces marked
* no output
*/
- if (interfacee->noobject) {
- continue;
- }
+ if (interfacee->type == IR_ENTRY_TYPE_INTERFACE) {
+ if (interfacee->u.interface.noobject) {
+ continue;
+ }
- if (interfacee->primary_global) {
- pglobale = interfacee;
- continue;
+ if (interfacee->u.interface.primary_global) {
+ pglobale = interfacee;
+ continue;
+ }
}
-
proto_name = get_prototype_name(interfacee->name);
fprintf(bindf,
@@ -1943,7 +2066,7 @@ output_binding_src(struct interface_map *interface_map)
/* binding postface */
output_cdata(bindf,
- interface_map->binding_node,
+ ir->binding_node,
GENBIND_NODE_TYPE_POSTFACE);
genb_fclose_tmp(bindf, "binding.c");
@@ -1951,46 +2074,102 @@ output_binding_src(struct interface_map *interface_map)
return 0;
}
-int duk_libdom_output(struct interface_map *interface_map)
+static int output_interfaces_dictionaries(struct ir *ir)
{
+ int res;
int idx;
- int res = 0;
/* generate interfaces */
- for (idx = 0; idx < interface_map->entryc; idx++) {
- res = output_interface(interface_map,
- interface_map->entries + idx);
- if (res != 0) {
- goto output_err;
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *irentry;
+
+ irentry = ir->entries + idx;
+
+ switch (irentry->type) {
+ case IR_ENTRY_TYPE_INTERFACE:
+ /* do not generate class for interfaces marked no
+ * output
+ */
+ if (!irentry->u.interface.noobject) {
+ res = output_interface(ir, irentry);
+ if (res != 0) {
+ return res;
+ }
+ }
+ break;
+
+ case IR_ENTRY_TYPE_DICTIONARY:
+ res = output_dictionary(ir, irentry);
+ if (res != 0) {
+ return res;
+ }
+
+ default:
+ break;
}
}
+ return 0;
+}
+
+int duk_libdom_output(struct ir *ir)
+{
+ int idx;
+ int res = 0;
+
+ /* process ir entries for output */
+ for (idx = 0; idx < ir->entryc; idx++) {
+ struct ir_entry *irentry;
+
+ irentry = ir->entries + idx;
+
+ /* compute class name */
+ irentry->class_name = gen_class_name(irentry);
+
+ if (irentry->class_name != NULL) {
+ int ifacenamelen;
+
+ /* generate source filename */
+ ifacenamelen = strlen(irentry->class_name) + 4;
+ irentry->filename = malloc(ifacenamelen);
+ snprintf(irentry->filename,
+ ifacenamelen,
+ "%s.c",
+ irentry->class_name);
+ }
+ }
+
+ res = output_interfaces_dictionaries(ir);
+ if (res != 0) {
+ goto output_err;
+ }
+
/* generate private header */
- res = output_private_header(interface_map);
+ res = output_private_header(ir);
if (res != 0) {
goto output_err;
}
/* generate prototype header */
- res = output_prototype_header(interface_map);
+ res = output_prototype_header(ir);
if (res != 0) {
goto output_err;
}
/* generate binding header */
- res = output_binding_header(interface_map);
+ res = output_binding_header(ir);
if (res != 0) {
goto output_err;
}
/* generate binding source */
- res = output_binding_src(interface_map);
+ res = output_binding_src(ir);
if (res != 0) {
goto output_err;
}
/* generate makefile fragment */
- res = output_makefile(interface_map);
+ res = output_makefile(ir);
output_err:
diff --git a/src/duk-libdom.h b/src/duk-libdom.h
index e1dd2c4..2ecd482 100644
--- a/src/duk-libdom.h
+++ b/src/duk-libdom.h
@@ -9,6 +9,6 @@
#ifndef nsgenbind_duk_libdom_h
#define nsgenbind_duk_libdom_h
-int duk_libdom_output(struct interface_map *interface_map);
+int duk_libdom_output(struct ir *ir);
#endif
diff --git a/src/interface-map.c b/src/ir.c
similarity index 67%
rename from src/interface-map.c
rename to src/ir.c
index a5a672a..3a2a1c8 100644
--- a/src/interface-map.c
+++ b/src/ir.c
@@ -1,4 +1,4 @@
-/* interface mapping
+/* intermediate representation of WebIDL and binding data
*
* This file is part of nsgenbind.
* Published under the MIT License,
@@ -17,7 +17,7 @@
#include "utils.h"
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
-#include "interface-map.h"
+#include "ir.h"
/** count the number of nodes of a given type on an interface */
static int
@@ -49,7 +49,7 @@ enumerate_interface_type(struct webidl_node *interface_node,
* binding also maintain refcounts
*/
static void
-compute_inherit_refcount(struct interface_map_entry *entries, int entryc)
+compute_inherit_refcount(struct ir_entry *entries, int entryc)
{
int idx;
int inf;
@@ -81,14 +81,14 @@ compute_inherit_refcount(struct interface_map_entry *entries, int
entryc)
* reduce refcount on inherit index if !=-1
* remove entry from source map
*/
-static struct interface_map_entry *
-interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
+static struct ir_entry *
+entry_topoligical_sort(struct ir_entry *srcinf, int infc)
{
- struct interface_map_entry *dstinf;
+ struct ir_entry *dstinf;
int idx;
int inf;
- dstinf = calloc(infc, sizeof(struct interface_map_entry));
+ dstinf = calloc(infc, sizeof(struct ir_entry));
if (dstinf == NULL) {
return NULL;
}
@@ -110,15 +110,9 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int
infc)
dstinf[idx].name = srcinf[inf].name;
dstinf[idx].node = srcinf[inf].node;
dstinf[idx].inherit_name = srcinf[inf].inherit_name;
- dstinf[idx].noobject = srcinf[inf].noobject;
- dstinf[idx].primary_global = srcinf[inf].primary_global;
- dstinf[idx].operationc = srcinf[inf].operationc;
- 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;
+ dstinf[idx].type = srcinf[inf].type;
+ dstinf[idx].u = srcinf[inf].u;
/* reduce refcount on inherit index if !=-1 */
if (srcinf[inf].inherit_idx != -1) {
@@ -132,12 +126,12 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int
infc)
return dstinf;
}
-static struct interface_map_operation_entry *
-find_operation_name(struct interface_map_operation_entry *operationv,
+static struct ir_operation_entry *
+find_operation_name(struct ir_operation_entry *operationv,
int operationc,
const char *name)
{
- struct interface_map_operation_entry *cure;
+ struct ir_operation_entry *cure;
int opc;
for (opc = 0; opc < operationc; opc++) {
@@ -161,12 +155,12 @@ find_operation_name(struct interface_map_operation_entry
*operationv,
static int
argument_map_new(struct webidl_node *arg_list_node,
int *argumentc_out,
- struct interface_map_operation_argument_entry **argumentv_out)
+ struct ir_operation_argument_entry **argumentv_out)
{
int argumentc;
struct webidl_node *argument;
- struct interface_map_operation_argument_entry *argumentv;
- struct interface_map_operation_argument_entry *cure;
+ struct ir_operation_argument_entry *argumentv;
+ struct ir_operation_argument_entry *cure;
argumentc = webidl_node_enumerate_type(
webidl_node_getnode(arg_list_node),
@@ -228,11 +222,11 @@ argument_map_new(struct webidl_node *arg_list_node,
static int
overload_map_new(struct webidl_node *op_node,
int *overloadc_out,
- struct interface_map_operation_overload_entry **overloadv_out)
+ struct ir_operation_overload_entry **overloadv_out)
{
int overloadc = *overloadc_out;
- struct interface_map_operation_overload_entry *overloadv;
- struct interface_map_operation_overload_entry *cure;
+ struct ir_operation_overload_entry *overloadv;
+ struct ir_operation_overload_entry *cure;
struct webidl_node *arg_list_node;
int argc;
@@ -264,7 +258,7 @@ overload_map_new(struct webidl_node *op_node,
}
for (argc = 0; argc < cure->argumentc; argc++) {
- struct interface_map_operation_argument_entry *arge;
+ struct ir_operation_argument_entry *arge;
arge = cure->argumentv + argc;
cure->optionalc += arge->optionalc;
cure->elipsisc += arge->elipsisc;
@@ -281,12 +275,12 @@ static int
operation_map_new(struct webidl_node *interface,
struct genbind_node *class,
int *operationc_out,
- struct interface_map_operation_entry **operationv_out)
+ struct ir_operation_entry **operationv_out)
{
struct webidl_node *list_node;
struct webidl_node *op_node; /* attribute node */
- struct interface_map_operation_entry *cure; /* current entry */
- struct interface_map_operation_entry *operationv;
+ struct ir_operation_entry *cure; /* current entry */
+ struct ir_operation_entry *operationv;
int operationc;
/* enumerate operationss including overloaded members */
@@ -301,7 +295,7 @@ operation_map_new(struct webidl_node *interface,
}
operationv = calloc(operationc,
- sizeof(struct interface_map_operation_entry));
+ sizeof(struct ir_operation_entry));
if (operationv == NULL) {
return -1;
};
@@ -322,7 +316,7 @@ operation_map_new(struct webidl_node *interface,
while (op_node != NULL) {
const char *operation_name;
- struct interface_map_operation_entry *finde;
+ struct ir_operation_entry *finde;
/* get operation name */
operation_name = webidl_node_gettext(
@@ -388,12 +382,12 @@ static int
attribute_map_new(struct webidl_node *interface,
struct genbind_node *class,
int *attributec_out,
- struct interface_map_attribute_entry **attributev_out)
+ struct ir_attribute_entry **attributev_out)
{
struct webidl_node *list_node;
struct webidl_node *at_node; /* attribute node */
- struct interface_map_attribute_entry *cure; /* current entry */
- struct interface_map_attribute_entry *attributev;
+ struct ir_attribute_entry *cure; /* current entry */
+ struct ir_attribute_entry *attributev;
int attributec;
/* enumerate attributes */
@@ -407,7 +401,7 @@ attribute_map_new(struct webidl_node *interface,
}
attributev = calloc(attributec,
- sizeof(struct interface_map_attribute_entry));
+ sizeof(struct ir_attribute_entry));
if (attributev == NULL) {
return -1;
};
@@ -484,12 +478,12 @@ attribute_map_new(struct webidl_node *interface,
static int
constant_map_new(struct webidl_node *interface,
int *constantc_out,
- struct interface_map_constant_entry **constantv_out)
+ struct ir_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;
+ struct ir_constant_entry *cure; /* current entry */
+ struct ir_constant_entry *constantv;
int constantc;
/* enumerate constants */
@@ -505,7 +499,7 @@ constant_map_new(struct webidl_node *interface,
*constantc_out = constantc;
constantv = calloc(constantc,
- sizeof(struct interface_map_constant_entry));
+ sizeof(struct ir_constant_entry));
if (constantv == NULL) {
return -1;
};
@@ -553,50 +547,69 @@ constant_map_new(struct webidl_node *interface,
return 0;
}
-int interface_map_new(struct genbind_node *genbind,
- struct webidl_node *webidl,
- struct interface_map **map_out)
+static int
+entry_map_new(struct genbind_node *genbind,
+ struct webidl_node *interface,
+ int *interfacec_out,
+ struct ir_entry **interfacev_out)
{
int interfacec;
- struct interface_map_entry *entries;
- struct interface_map_entry *sorted_entries;
- struct interface_map_entry *ecur;
+ int dictionaryc;
+ int entryc;
+ struct ir_entry *entries;
+ struct ir_entry *sorted_entries;
+ struct ir_entry *cure;
struct webidl_node *node;
- struct interface_map *map;
-
- interfacec = webidl_node_enumerate_type(webidl,
- WEBIDL_NODE_TYPE_INTERFACE);
+ interfacec = webidl_node_enumerate_type(interface,
+ WEBIDL_NODE_TYPE_INTERFACE);
+ dictionaryc = webidl_node_enumerate_type(interface,
+ WEBIDL_NODE_TYPE_DICTIONARY);
if (options->verbose) {
printf("Mapping %d interfaces\n", interfacec);
+ printf("Mapping %d dictionaries\n", dictionaryc);
}
- entries = calloc(interfacec, sizeof(struct interface_map_entry));
+ entryc = interfacec + dictionaryc;
+
+ entries = calloc(entryc, sizeof(struct ir_entry));
if (entries == NULL) {
return -1;
}
/* for each interface populate an entry in the map */
- ecur = entries;
- node = webidl_node_find_type(webidl, NULL, WEBIDL_NODE_TYPE_INTERFACE);
+ cure = entries;
+ node = webidl_node_find_type(interface,
+ NULL,
+ WEBIDL_NODE_TYPE_INTERFACE);
while (node != NULL) {
/* fill map entry */
- ecur->node = node;
+ cure->node = node;
/* name of interface */
- ecur->name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
/* name of the inherited interface (if any) */
- ecur->inherit_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(node),
+ cure->inherit_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_INHERITANCE));
+
+ /* matching class from binding */
+ cure->class = genbind_node_find_type_ident(
+ genbind,
NULL,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE));
+ GENBIND_NODE_TYPE_CLASS,
+ cure->name);
+
+ /* identify this is an interface entry */
+ cure->type = IR_ENTRY_TYPE_INTERFACE;
/* is the interface marked as not generating an object */
if (webidl_node_find_type_ident(
@@ -607,7 +620,7 @@ int interface_map_new(struct genbind_node *genbind,
* cannot form part of an inheritance chain if it is
* not generating an output class
*/
- ecur->noobject = true;
+ cure->u.interface.noobject = true;
}
/* is the interface marked as the primary global */
@@ -619,189 +632,262 @@ int interface_map_new(struct genbind_node *genbind,
* class or all hell will break loose having two
* primary globals.
*/
- ecur->primary_global = true;
+ cure->u.interface.primary_global = true;
}
- /* matching class from binding */
- ecur->class = genbind_node_find_type_ident(genbind,
- NULL, GENBIND_NODE_TYPE_CLASS, ecur->name);
-
/* enumerate and map the interface operations */
operation_map_new(node,
- ecur->class,
- &ecur->operationc,
- &ecur->operationv);
+ cure->class,
+ &cure->u.interface.operationc,
+ &cure->u.interface.operationv);
/* enumerate and map the interface attributes */
attribute_map_new(node,
- ecur->class,
- &ecur->attributec,
- &ecur->attributev);
+ cure->class,
+ &cure->u.interface.attributec,
+ &cure->u.interface.attributev);
/* enumerate and map the interface constants */
constant_map_new(node,
- &ecur->constantc,
- &ecur->constantv);
+ &cure->u.interface.constantc,
+ &cure->u.interface.constantv);
/* move to next interface */
- node = webidl_node_find_type(webidl, node,
+ node = webidl_node_find_type(interface,
+ node,
WEBIDL_NODE_TYPE_INTERFACE);
- ecur++;
+ cure++;
+ }
+
+ /* for each dictionary populate an entry in the map */
+ node = webidl_node_find_type(interface,
+ NULL,
+ WEBIDL_NODE_TYPE_DICTIONARY);
+ while (node != NULL) {
+
+ /* fill map entry */
+ cure->node = node;
+
+ /* name of interface */
+ cure->name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT));
+
+ /* name of the inherited interface (if any) */
+ cure->inherit_name = webidl_node_gettext(
+ webidl_node_find_type(
+ webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_INHERITANCE));
+
+ /* matching class from binding */
+ cure->class = genbind_node_find_type_ident(
+ genbind,
+ NULL,
+ GENBIND_NODE_TYPE_CLASS,
+ cure->name);
+
+ /* identify this is an interface entry */
+ cure->type = IR_ENTRY_TYPE_DICTIONARY;
+
+
+
+
+ /* move to next interface */
+ node = webidl_node_find_type(interface,
+ node,
+ WEBIDL_NODE_TYPE_DICTIONARY);
+ cure++;
}
/* compute inheritance and refcounts on map */
- compute_inherit_refcount(entries, interfacec);
+ compute_inherit_refcount(entries, entryc);
- /* sort interfaces to ensure correct ordering */
- sorted_entries = interface_topoligical_sort(entries, interfacec);
+ /* sort entries to ensure correct ordering */
+ sorted_entries = entry_topoligical_sort(entries, entryc);
free(entries);
if (sorted_entries == NULL) {
return -1;
}
/* compute inheritance and refcounts on sorted map */
- compute_inherit_refcount(sorted_entries, interfacec);
-
- map = malloc(sizeof(struct interface_map));
- map->entryc = interfacec;
- map->entries = sorted_entries;
- map->webidl = webidl;
- map->binding_node = genbind_node_find_type(genbind, NULL,
- GENBIND_NODE_TYPE_BINDING);
+ compute_inherit_refcount(sorted_entries, entryc);
- *map_out = map;
+ *interfacec_out = entryc;
+ *interfacev_out = sorted_entries;
return 0;
}
-int interface_map_dump(struct interface_map *index)
+
+int ir_new(struct genbind_node *genbind,
+ struct webidl_node *webidl,
+ struct ir **map_out)
{
- FILE *dumpf;
- int eidx;
- struct interface_map_entry *ecur;
+ struct ir *map;
+ int ret;
- /* only dump AST to file if required */
- if (!options->debug) {
- return 0;
+ map = malloc(sizeof(struct ir));
+ if (map == NULL) {
+ return -1;
}
- dumpf = genb_fopen("interface-map", "w");
- if (dumpf == NULL) {
- return 2;
+ map->webidl = webidl;
+ map->binding_node = genbind_node_find_type(genbind, NULL,
+ GENBIND_NODE_TYPE_BINDING);
+
+ /* interfaces */
+ ret = entry_map_new(genbind,
+ webidl,
+ &map->entryc,
+ &map->entries);
+ if (ret != 0) {
+ free(map);
+ return ret;
}
- ecur = index->entries;
- for (eidx = 0; eidx < index->entryc; eidx++) {
- fprintf(dumpf, "%d %s\n", eidx, ecur->name);
- if (ecur->inherit_name != NULL) {
- fprintf(dumpf, "\tinherit:%s\n",
ecur->inherit_name);
- }
- if (ecur->class != NULL) {
- fprintf(dumpf, "\tclass:%p\n", ecur->class);
- }
+ *map_out = map;
+
+ return 0;
+}
- if (ecur->operationc > 0) {
- int opc;
+static int ir_dump_interface(FILE *dumpf, struct ir_entry *ecur)
+{
+ if (ecur->u.interface.operationc > 0) {
+ int opc;
+
+ fprintf(dumpf, "\t%d operations\n",
+ ecur->u.interface.operationc);
- fprintf(dumpf, "\t%d operations\n",
- ecur->operationc);
+ for (opc = 0; opc < ecur->u.interface.operationc; opc++) {
+ int ovlc;
+ struct ir_operation_entry *ope;
- for (opc = 0; opc < ecur->operationc; opc++) {
- int ovlc;
- struct interface_map_operation_entry *ope;
+ ope = ecur->u.interface.operationv + opc;
- ope = ecur->operationv + opc;
+ fprintf(dumpf,
+ "\t\t%s\n",
+ ope->name);
+ fprintf(dumpf,
+ "\t\t\tmethod:%p\n",
+ ope->method);
+ for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
+ int argc;
+ struct ir_operation_overload_entry *ovle;
+ ovle = ope->overloadv + ovlc;
fprintf(dumpf,
- "\t\t%s\n",
- ope->name);
+ "\t\t\toverload:%d\n", ovlc);
+
fprintf(dumpf,
- "\t\t\tmethod:%p\n",
- ope->method);
- for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
- int argc;
- struct interface_map_operation_overload_entry
*ovle;
- ovle = ope->overloadv + ovlc;
+ "\t\t\t\treturn type:%p\n",
+ ovle->type);
- fprintf(dumpf,
- "\t\t\toverload:%d\n", ovlc);
+ fprintf(dumpf,
+ "\t\t\t\targuments:%d\n",
+ ovle->argumentc);
- fprintf(dumpf,
- "\t\t\t\treturn type:%p\n",
- ovle->type);
+ fprintf(dumpf,
+ "\t\t\t\toptionals:%d\n",
+ ovle->optionalc);
- fprintf(dumpf,
- "\t\t\t\targuments:%d\n",
- ovle->argumentc);
+ fprintf(dumpf,
+ "\t\t\t\telipsis:%d\n",
+ ovle->elipsisc);
- fprintf(dumpf,
- "\t\t\t\toptionals:%d\n",
- ovle->optionalc);
+ for (argc = 0; argc < ovle->argumentc; argc++) {
+ struct ir_operation_argument_entry *arge;
+ arge = ovle->argumentv + argc;
fprintf(dumpf,
- "\t\t\t\telipsis:%d\n",
- ovle->elipsisc);
-
- for (argc = 0; argc < ovle->argumentc;
argc++) {
- struct
interface_map_operation_argument_entry *arge;
- arge = ovle->argumentv + argc;
+ "\t\t\t\t\t%s\n",
+ arge->name);
+ if (arge->optionalc != 0) {
fprintf(dumpf,
- "\t\t\t\t\t%s\n",
- arge->name);
-
- if (arge->optionalc != 0) {
- fprintf(dumpf,
-
"\t\t\t\t\t\toptional:%d\n",
- arge->optionalc);
- }
-
- if (arge->elipsisc != 0) {
- fprintf(dumpf,
-
"\t\t\t\t\t\telipsis:%d\n",
- arge->elipsisc);
- }
+
"\t\t\t\t\t\toptional:%d\n",
+ arge->optionalc);
+ }
+ if (arge->elipsisc != 0) {
+ fprintf(dumpf,
+
"\t\t\t\t\t\telipsis:%d\n",
+ arge->elipsisc);
}
+
}
}
}
+ }
- if (ecur->attributec > 0) {
- int attrc = ecur->attributec;
- struct interface_map_attribute_entry *attre;
-
- fprintf(dumpf, "\t%d attributes\n", attrc);
-
- attre = ecur->attributev;
- while (attre != NULL) {
- fprintf(dumpf, "\t\t%s %p",
- attre->name,
- attre->getter);
- if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
- fprintf(dumpf, " %p\n",
attre->setter);
- } else {
- fprintf(dumpf, "\n");
- }
- attre++;
- attrc--;
- if (attrc == 0) {
- break;
- }
+ if (ecur->u.interface.attributec > 0) {
+ int attrc = ecur->u.interface.attributec;
+ struct ir_attribute_entry *attre;
+
+ fprintf(dumpf, "\t%d attributes\n", attrc);
+
+ attre = ecur->u.interface.attributev;
+ while (attre != NULL) {
+ fprintf(dumpf, "\t\t%s %p",
+ attre->name,
+ attre->getter);
+ if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
+ fprintf(dumpf, " %p\n", attre->setter);
+ } else {
+ fprintf(dumpf, "\n");
+ }
+ attre++;
+ attrc--;
+ if (attrc == 0) {
+ break;
}
}
- if (ecur->constantc > 0) {
- int idx;
+ }
+ if (ecur->u.interface.constantc > 0) {
+ int idx;
- fprintf(dumpf, "\t%d constants\n",
- ecur->constantc);
+ fprintf(dumpf, "\t%d constants\n",
+ ecur->u.interface.constantc);
- for (idx = 0; idx < ecur->constantc; idx++) {
- struct interface_map_constant_entry *cone;
- cone = ecur->constantv + idx;
- fprintf(dumpf, "\t\t%s\n",
- cone->name);
- }
+ for (idx = 0; idx < ecur->u.interface.constantc; idx++) {
+ struct ir_constant_entry *cone;
+ cone = ecur->u.interface.constantv + idx;
+ fprintf(dumpf, "\t\t%s\n", cone->name);
+ }
+ }
+ return 0;
+}
+
+int ir_dump(struct ir *ir)
+{
+ FILE *dumpf;
+ int eidx;
+ struct ir_entry *ecur;
+
+ /* only dump AST to file if required */
+ if (!options->debug) {
+ return 0;
+ }
+
+ dumpf = genb_fopen("ir-map", "w");
+ if (dumpf == NULL) {
+ return 2;
+ }
+
+ ecur = ir->entries;
+ for (eidx = 0; eidx < ir->entryc; eidx++) {
+ fprintf(dumpf, "%d %s\n", eidx, ecur->name);
+ if (ecur->inherit_name != NULL) {
+ fprintf(dumpf, "\tinherit:%s\n",
ecur->inherit_name);
+ }
+ if (ecur->class != NULL) {
+ fprintf(dumpf, "\tclass:%p\n", ecur->class);
+ }
+
+ if (ecur->type == IR_ENTRY_TYPE_INTERFACE) {
+ ir_dump_interface(dumpf, ecur);
}
ecur++;
}
@@ -811,18 +897,18 @@ int interface_map_dump(struct interface_map *index)
return 0;
}
-int interface_map_dumpdot(struct interface_map *index)
+int ir_dumpdot(struct ir *index)
{
FILE *dumpf;
int eidx;
- struct interface_map_entry *ecur;
+ struct ir_entry *ecur;
/* only dump AST to file if required */
if (!options->debug) {
return 0;
}
- dumpf = genb_fopen("interface.dot", "w");
+ dumpf = genb_fopen("ir.dot", "w");
if (dumpf == NULL) {
return 2;
}
@@ -834,13 +920,15 @@ int interface_map_dumpdot(struct interface_map *index)
ecur = index->entries;
for (eidx = 0; eidx < index->entryc; eidx++) {
fprintf(dumpf, "%04d [label=\"%s\"", eidx,
ecur->name);
- if (ecur->noobject == true) {
+ if ((ecur == IR_ENTRY_TYPE_INTERFACE) &&
+ (ecur->u.interface.noobject == true)) {
/* noobject interfaces in red */
fprintf(dumpf, "fontcolor=\"red\"");
} else if (ecur->class != NULL) {
/* interfaces bound to a class are shown in blue */
fprintf(dumpf, "fontcolor=\"blue\"");
}
+
fprintf(dumpf, "];\n");
ecur++;
}
@@ -860,11 +948,11 @@ int interface_map_dumpdot(struct interface_map *index)
return 0;
}
-struct interface_map_entry *
-interface_map_inherit_entry(struct interface_map *map,
- struct interface_map_entry *entry)
+struct ir_entry *
+ir_inherit_entry(struct ir *map,
+ struct ir_entry *entry)
{
- struct interface_map_entry *res = NULL;
+ struct ir_entry *res = NULL;
if ((entry != NULL) &&
(entry->inherit_idx != -1)) {
diff --git a/src/interface-map.h b/src/ir.h
similarity index 70%
rename from src/interface-map.h
rename to src/ir.h
index 079ed96..cf431f6 100644
--- a/src/interface-map.h
+++ b/src/ir.h
@@ -1,4 +1,4 @@
-/* Interface mapping
+/* intermediate representation of WebIDL and binding data
*
* This file is part of nsgenbind.
* Licensed under the MIT License,
@@ -6,8 +6,8 @@
* Copyright 2012 Vincent Sanders <vince(a)netsurf-browser.org>
*/
-#ifndef nsgenbind_interface_map_h
-#define nsgenbind_interface_map_h
+#ifndef nsgenbind_ir_h
+#define nsgenbind_ir_h
struct genbind_node;
struct webidl_node;
@@ -15,7 +15,7 @@ struct webidl_node;
/**
* map entry for each argument of an overload on an operation
*/
-struct interface_map_operation_argument_entry {
+struct ir_operation_argument_entry {
const char *name;
int optionalc; /**< 1 if the argument is optional */
@@ -25,28 +25,28 @@ struct interface_map_operation_argument_entry {
};
/** map entry for each overload of an operation */
-struct interface_map_operation_overload_entry {
+struct ir_operation_overload_entry {
struct webidl_node *type; /**< The return type of this overload */
int optionalc; /**< Number of parameters that are optional */
int elipsisc; /**< Number of elipsis parameters */
int argumentc; /**< the number of parameters */
- struct interface_map_operation_argument_entry *argumentv;
+ struct ir_operation_argument_entry *argumentv;
};
/** map entry for operations on an interface */
-struct interface_map_operation_entry {
+struct ir_operation_entry {
const char *name; /** operation name */
struct webidl_node *node; /**< AST operation node */
struct genbind_node *method; /**< method from binding */
int overloadc; /**< Number of overloads of this operation */
- struct interface_map_operation_overload_entry *overloadv;
+ struct ir_operation_overload_entry *overloadv;
};
/** map entry for attributes on an interface */
-struct interface_map_attribute_entry {
+struct ir_attribute_entry {
const char *name; /** attribute name */
struct webidl_node *node; /**< AST attribute node */
enum webidl_type_modifier modifier;
@@ -55,22 +55,14 @@ struct interface_map_attribute_entry {
};
/** map entry for constants on an interface */
-struct interface_map_constant_entry {
+struct ir_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 */
- const char *inherit_name; /**< Name of interface inhertited from */
- int inherit_idx; /**< index into map of inherited interface or -1 for
- * not in map
- */
- int refcount; /**< number of interfacess in map that refer to this
- * interface
- */
+struct ir_interface_entry {
bool noobject; /**< flag indicating if no interface object should eb
* generated. This allows for interfaces which do not
* generate code. For implements (mixin) interfaces
@@ -80,19 +72,46 @@ struct interface_map_entry {
*/
int operationc; /**< number of operations on interface */
- struct interface_map_operation_entry *operationv;
+ struct ir_operation_entry *operationv;
int attributec; /**< number of attributes on interface */
- struct interface_map_attribute_entry *attributev;
+ struct ir_attribute_entry *attributev;
int constantc; /**< number of constants on interface */
- struct interface_map_constant_entry *constantv;
+ struct ir_constant_entry *constantv;
+};
+/** map entry for a dictionary */
+struct ir_dictionary_entry {
+};
+enum ir_entry_type {
+ IR_ENTRY_TYPE_INTERFACE,
+ IR_ENTRY_TYPE_DICTIONARY,
+};
+
+/** top level entry info common to interfaces and dictionaries */
+struct ir_entry {
+ const char *name; /** dictionary name */
+ struct webidl_node *node; /**< AST dictionary node */
+ const char *inherit_name; /**< Name of interface inhertited from */
struct genbind_node *class; /**< class from binding (if any) */
+ enum ir_entry_type type;
+ union {
+ struct ir_dictionary_entry dictionary;
+ struct ir_interface_entry interface;
+ } u;
+
+ int inherit_idx; /**< index into map of inherited interface or -1 for
+ * not in map
+ */
+ int refcount; /**< number of interfacess in map that refer to this
+ * interface
+ */
+
/* The variables are created and used by the output generation but
- * rtaher than have another allocation and pointer the data they are
+ * rather than have another allocation and pointer the data they are
* just inline here.
*/
@@ -108,10 +127,10 @@ struct interface_map_entry {
*/
};
-/** WebIDL interface map */
-struct interface_map {
- int entryc; /**< count of interfaces */
- struct interface_map_entry *entries; /**< interface entries */
+/** intermediate representation of WebIDL and binding data */
+struct ir {
+ int entryc; /**< count of entries */
+ struct ir_entry *entries; /**< interface entries */
/** The AST node of the binding information */
struct genbind_node *binding_node;
@@ -123,19 +142,19 @@ struct interface_map {
/**
* Create a new interface map
*/
-int interface_map_new(struct genbind_node *genbind,
+int ir_new(struct genbind_node *genbind,
struct webidl_node *webidl,
- struct interface_map **map_out);
+ struct ir **map_out);
-int interface_map_dump(struct interface_map *map);
+int ir_dump(struct ir *map);
-int interface_map_dumpdot(struct interface_map *map);
+int ir_dumpdot(struct ir *map);
/**
* interface map parent entry
*
* \return inherit entry or NULL if there is not one
*/
-struct interface_map_entry *interface_map_inherit_entry(struct interface_map *map, struct
interface_map_entry *entry);
+struct ir_entry *ir_inherit_entry(struct ir *map, struct ir_entry *entry);
#endif
diff --git a/src/nsgenbind.c b/src/nsgenbind.c
index 9558b95..135c5c0 100644
--- a/src/nsgenbind.c
+++ b/src/nsgenbind.c
@@ -17,7 +17,7 @@
#include "options.h"
#include "nsgenbind-ast.h"
#include "webidl-ast.h"
-#include "interface-map.h"
+#include "ir.h"
#include "jsapi-libdom.h"
#include "duk-libdom.h"
@@ -192,7 +192,7 @@ int main(int argc, char **argv)
int res;
struct genbind_node *genbind_root = NULL;
struct webidl_node *webidl_root = NULL;
- struct interface_map *interface_map = NULL;
+ struct ir *ir = NULL;
enum bindingtype_e bindingtype;
options = process_cmdline(argc, argv);
@@ -225,20 +225,20 @@ int main(int argc, char **argv)
/* debug dump of web idl AST */
webidl_dump_ast(webidl_root);
- /* generate map of WebIDL interfaces sorted by inheritance */
- res = interface_map_new(genbind_root, webidl_root, &interface_map);
+ /* generate intermediate representation */
+ res = ir_new(genbind_root, webidl_root, &ir);
if (res != 0) {
return 5;
}
- /* dump the interface mapping */
- interface_map_dump(interface_map);
- interface_map_dumpdot(interface_map);
+ /* dump the intermediate representation */
+ ir_dump(ir);
+ ir_dumpdot(ir);
/* generate binding */
switch (bindingtype) {
case BINDINGTYPE_DUK_LIBDOM:
- res = duk_libdom_output(interface_map);
+ res = duk_libdom_output(ir);
break;
default:
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 87e3485..dc78e1f 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -96,6 +96,7 @@ webidl_node_add(struct webidl_node *node, struct webidl_node *list)
switch (node->type) {
case WEBIDL_NODE_TYPE_ROOT:
case WEBIDL_NODE_TYPE_INTERFACE:
+ case WEBIDL_NODE_TYPE_DICTIONARY:
case WEBIDL_NODE_TYPE_LIST:
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
@@ -265,7 +266,7 @@ char *webidl_node_gettext(struct webidl_node *node)
switch(node->type) {
case WEBIDL_NODE_TYPE_IDENT:
- case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
+ case WEBIDL_NODE_TYPE_INHERITANCE:
case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
case WEBIDL_NODE_TYPE_LITERAL_STRING:
return node->r.text;
@@ -311,6 +312,7 @@ struct webidl_node *webidl_node_getnode(struct webidl_node *node)
switch (node->type) {
case WEBIDL_NODE_TYPE_ROOT:
case WEBIDL_NODE_TYPE_INTERFACE:
+ case WEBIDL_NODE_TYPE_DICTIONARY:
case WEBIDL_NODE_TYPE_LIST:
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
case WEBIDL_NODE_TYPE_ATTRIBUTE:
@@ -338,7 +340,7 @@ static const char *webidl_node_type_to_str(enum webidl_node_type
type)
case WEBIDL_NODE_TYPE_IDENT:
return "Ident";
- case WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE:
+ case WEBIDL_NODE_TYPE_INHERITANCE:
return "Inherit";
case WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS:
@@ -347,6 +349,9 @@ static const char *webidl_node_type_to_str(enum webidl_node_type
type)
case WEBIDL_NODE_TYPE_INTERFACE:
return "Interface";
+ case WEBIDL_NODE_TYPE_DICTIONARY:
+ return "Dictionary";
+
case WEBIDL_NODE_TYPE_LIST:
return "List";
@@ -600,7 +605,7 @@ static int implements_copy_nodes(struct webidl_node *src_node,
while (src != NULL) {
if (src->type == WEBIDL_NODE_TYPE_LIST) {
- /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE */
+ /** @todo technicaly this should copy WEBIDL_NODE_TYPE_INHERITANCE */
dst = webidl_node_new(src->type, dst, src->r.text);
}
src = src->l;
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 109159f..0872965 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -19,14 +19,16 @@ enum webidl_node_type {
WEBIDL_NODE_TYPE_LIST,
/* non structural node types */
- WEBIDL_NODE_TYPE_INTERFACE,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
+ WEBIDL_NODE_TYPE_INTERFACE, /**< node is an interface*/
WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS,
WEBIDL_NODE_TYPE_ATTRIBUTE,
WEBIDL_NODE_TYPE_OPERATION,
WEBIDL_NODE_TYPE_CONST,
+ WEBIDL_NODE_TYPE_DICTIONARY, /**< node is a dictionary */
+
+ WEBIDL_NODE_TYPE_INHERITANCE, /**< node has inheritance */
WEBIDL_NODE_TYPE_SPECIAL,
WEBIDL_NODE_TYPE_ARGUMENT,
WEBIDL_NODE_TYPE_OPTIONAL,
diff --git a/src/webidl-lexer.l b/src/webidl-lexer.l
index 8c68fdf..4788610 100644
--- a/src/webidl-lexer.l
+++ b/src/webidl-lexer.l
@@ -213,6 +213,8 @@ iterable return TOK_ITERABLE;
legacyiterable return TOK_LEGACYITERABLE;
+required return TOK_REQUIRED;
+
{identifier} {
/* A leading "_" is used to escape an identifier from
* looking like a reserved word terminal. */
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index 42fed63..406962f 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -66,7 +66,6 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char
*str)
%token TOK_BOOLEAN
%token TOK_BYTE
%token TOK_CALLBACK
-%token TOK_LEGACYCALLER
%token TOK_CONST
%token TOK_CREATOR
%token TOK_DATE
@@ -87,6 +86,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char
*str)
%token TOK_INHERIT
%token TOK_INTERFACE
%token TOK_ITERABLE
+%token TOK_LEGACYCALLER
%token TOK_LEGACYITERABLE
%token TOK_LONG
%token TOK_MODULE
@@ -102,6 +102,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%token TOK_PROMISE
%token TOK_RAISES
%token TOK_READONLY
+%token TOK_REQUIRED
%token TOK_SETRAISES
%token TOK_SETTER
%token TOK_SEQUENCE
@@ -134,6 +135,8 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <node> Dictionary
%type <node> PartialDictionary
+%type <node> DictionaryMembers
+%type <node> DictionaryMember
%type <node> Exception
%type <node> Enum
@@ -151,6 +154,8 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <node> Attribute
%type <node> AttributeRest
+%type <text> AttributeName
+%type <text> AttributeNameKeyword
%type <node> AttributeOrOperation
%type <node> StringifierAttributeOrOperation
%type <node> Const
@@ -201,6 +206,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <isit> ReadOnly
%type <isit> OptionalLong
%type <isit> Inherit
+ //%type <isit> Required
%type <node> ExtendedAttributeList
%type <node> ExtendedAttributes
@@ -210,6 +216,7 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const
char *str)
%type <text> Other
%type <text> OtherOrComma
+
%%
/* [1] default rule to add built AST to passed in one, altered from
@@ -274,34 +281,40 @@ CallbackRestOrInterface:
Interface:
TOK_INTERFACE TOK_IDENTIFIER Inheritance '{' InterfaceMembers '}'
';'
{
- /* extend interface with additional members */
- struct webidl_node *interface_node;
- struct webidl_node *members = NULL;
+ /* extend interface with additional members */
+ struct webidl_node *interface_node;
+ struct webidl_node *members = NULL;
- if ($3 != NULL) {
- members = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE,
members, $3);
- }
+ if ($3 != NULL) {
+ members = webidl_node_new(WEBIDL_NODE_TYPE_INHERITANCE,
+ members,
+ $3);
+ }
- members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
- interface_node = webidl_node_find_type_ident(*webidl_ast,
+ interface_node = webidl_node_find_type_ident(*webidl_ast,
WEBIDL_NODE_TYPE_INTERFACE,
- $2);
+ $2);
- if (interface_node == NULL) {
- /* no existing interface - create one with ident */
- members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, members, $2);
+ if (interface_node == NULL) {
+ /* no existing interface - create one with ident */
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE, NULL, members);
- } else {
- /* update the existing interface */
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_INTERFACE,
+ NULL,
+ members);
+ } else {
+ /* update the existing interface */
- /* link member node into interfaces_node */
- webidl_node_add(interface_node, members);
+ /* link member node into interfaces_node */
+ webidl_node_add(interface_node, members);
- $$ = NULL; /* updating so no need to add a new node */
- }
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;
@@ -353,64 +366,65 @@ PartialInterface:
/* [9] slightly altered from original grammar to be left recursive */
InterfaceMembers:
- /* empty */
{
- $$ = NULL;
+ $$ = NULL; /* empty */
}
|
InterfaceMembers ExtendedAttributeList InterfaceMember
- /* This needs to deal with members with the same identifier which
- * indicate polymorphism. this is handled in the AST by adding the
- * argument lists for each polymorphism to the same
- * WEBIDL_NODE_TYPE_OPERATION
- *
- * @todo need to consider qualifer/stringifier compatibility
- */
- {
- struct webidl_node *member_node;
- struct webidl_node *ident_node;
- struct webidl_node *list_node;
-
- ident_node = webidl_node_find_type(webidl_node_getnode($3),
- NULL,
- WEBIDL_NODE_TYPE_IDENT);
-
- list_node = webidl_node_find_type(webidl_node_getnode($3),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
-
- if (ident_node == NULL) {
- /* something with no ident - possibly constructors? */
- /* @todo understand this better */
-
- $$ = webidl_node_prepend($1, $3);
-
- } else if (list_node == NULL) {
- /* member with no argument list, usually an attribute, cannot
- * be polymorphic
+ {
+ /* This needs to deal with members with the same
+ * identifier which indicate polymorphism. this is
+ * handled in the AST by adding the argument lists for
+ * each polymorphism to the same
+ * WEBIDL_NODE_TYPE_OPERATION
+ *
+ * @todo need to consider qualifer/stringifier compatibility
*/
+ struct webidl_node *member_node;
+ struct webidl_node *ident_node;
+ struct webidl_node *list_node;
- /* add extended attributes to parameter list */
- webidl_node_add($3, $2);
+ ident_node = webidl_node_find_type(webidl_node_getnode($3),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT);
- $$ = webidl_node_prepend($1, $3);
+ list_node = webidl_node_find_type(webidl_node_getnode($3),
+ NULL,
+ WEBIDL_NODE_TYPE_LIST);
+
+ if (ident_node == NULL) {
+ /* something with no ident - possibly constructors? */
+ /* @todo understand this better */
+
+ $$ = webidl_node_prepend($1, $3);
+
+ } else if (list_node == NULL) {
+ /* member with no argument list, usually an
+ * attribute, cannot be polymorphic
+ */
+
+ /* add extended attributes to parameter list */
+ webidl_node_add($3, $2);
+
+ $$ = webidl_node_prepend($1, $3);
- } else {
- /* add extended attributes to parameter list */
- webidl_node_add(list_node, $2);
-
- /* has an arguemnt list so can be polymorphic */
- member_node = webidl_node_find_type_ident($1,
- webidl_node_gettype($3),
- webidl_node_gettext(ident_node));
- if (member_node == NULL) {
- /* not a member with that ident already present */
- $$ = webidl_node_prepend($1, $3);
} else {
- webidl_node_add(member_node, list_node);
- $$ = $1; /* updated existing node do not add new one */
+ /* add extended attributes to parameter list */
+ webidl_node_add(list_node, $2);
+
+ /* has an arguemnt list so can be polymorphic */
+ member_node = webidl_node_find_type_ident(
+ $1,
+ webidl_node_gettype($3),
+ webidl_node_gettext(ident_node));
+ if (member_node == NULL) {
+ /* not a member with that ident already present */
+ $$ = webidl_node_prepend($1, $3);
+ } else {
+ webidl_node_add(member_node, list_node);
+ $$ = $1; /* updated existing node do not add new one */
+ }
}
- }
}
;
@@ -433,28 +447,134 @@ InterfaceMember:
Dictionary:
TOK_DICTIONARY TOK_IDENTIFIER Inheritance '{' DictionaryMembers
'}' ';'
{
- $$ = NULL;
+ /* extend dictionary with additional members */
+ struct webidl_node *dictionary_node;
+ struct webidl_node *members = NULL;
+
+ if ($3 != NULL) {
+ members = webidl_node_new(WEBIDL_NODE_TYPE_INHERITANCE,
+ members,
+ $3);
+ }
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, members, $5);
+
+ dictionary_node = webidl_node_find_type_ident(
+ *webidl_ast,
+ WEBIDL_NODE_TYPE_DICTIONARY,
+ $2);
+
+ if (dictionary_node == NULL) {
+ /* no existing interface - create one with ident */
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_DICTIONARY,
+ NULL,
+ members);
+ } else {
+ /* update the existing interface */
+
+ /* link member node into interfaces_node */
+ webidl_node_add(dictionary_node, members);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
;
- /* [12] */
+ /* SE[12] */
DictionaryMembers:
- /* empty */
+ {
+ $$ = NULL; /* empty */
+ }
|
ExtendedAttributeList DictionaryMember DictionaryMembers
+ {
+ /** \todo handle ExtendedAttributeList */
+ $$ = webidl_node_append($3, $2);
+ }
;
- /* [13] */
+ /* SE[13]
+ * Second edition introduces Required except required type may not
+ * have default so why not express this in grammar here and remove
+ * rule 14?
+ */
DictionaryMember:
+ TOK_REQUIRED Type TOK_IDENTIFIER ';'
+ {
+ struct webidl_node *member;
+ /* add name */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $3);
+ /* add type node */
+ member = webidl_node_prepend(member, $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, member);
+ }
+ |
Type TOK_IDENTIFIER Default ';'
+ {
+ struct webidl_node *member;
+ /* add name */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, NULL, $2);
+ /* add default */
+ member = webidl_node_new(WEBIDL_NODE_TYPE_OPTIONAL, member, $3);
+ /* add type node */
+ member = webidl_node_prepend(member, $1);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_ARGUMENT, NULL, member);
+ }
;
+/* SE[14] */
+//Required:
+// {
+// $$ = false; /* empty */
+// }
+// |
+// TOK_REQUIRED
+// {
+// $$ = true;
+// }
+// ;
+
/* [14] */
PartialDictionary:
TOK_DICTIONARY TOK_IDENTIFIER '{' DictionaryMembers '}'
';'
{
- $$ = NULL;
+ /* extend dictionary with additional members */
+ struct webidl_node *members;
+ struct webidl_node *dictionary_node;
+
+ dictionary_node = webidl_node_find_type_ident(
+ *webidl_ast,
+ WEBIDL_NODE_TYPE_DICTIONARY,
+ $2);
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, $4);
+
+ if (dictionary_node == NULL) {
+ /* doesnt already exist so create it */
+
+ members = webidl_node_new(WEBIDL_NODE_TYPE_IDENT,
+ members,
+ $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_DICTIONARY,
+ NULL,
+ members);
+ } else {
+ /* update the existing dictionary */
+
+ /* link member node into dictionary node */
+ webidl_node_add(dictionary_node, members);
+
+ $$ = NULL; /* updating so no need to add a new node */
+ }
}
+ ;
/* [15] */
Default:
@@ -778,12 +898,25 @@ StaticMemberRest:
/* SE[42] */
AttributeRest:
- TOK_ATTRIBUTE Type TOK_IDENTIFIER ';'
+ TOK_ATTRIBUTE Type AttributeName ';'
{
$$ = webidl_node_new(WEBIDL_NODE_TYPE_IDENT, $2, $3);
}
;
+/* SE[43] */
+AttributeName:
+ AttributeNameKeyword
+ |
+ TOK_IDENTIFIER
+ ;
+
+/* SE[44] */
+AttributeNameKeyword:
+ TOK_REQUIRED
+ {
+ $$ = strdup("required");
+ }
/* [33]
* SE[45]
@@ -1333,7 +1466,9 @@ Other:
}
;
- /* [55] */
+ /* [55]
+ * SE[71] extended with new keywords
+ */
ArgumentNameKeyword:
TOK_ATTRIBUTE
{
@@ -1395,16 +1530,31 @@ ArgumentNameKeyword:
$$ = strdup("interface");
}
|
+ TOK_ITERABLE
+ {
+ $$ = strdup("iterable");
+ }
+ |
TOK_LEGACYCALLER
{
$$ = strdup("legacycaller");
}
|
+ TOK_LEGACYITERABLE
+ {
+ $$ = strdup("legacyiterable");
+ }
+ |
TOK_PARTIAL
{
$$ = strdup("partial");
}
|
+ TOK_REQUIRED
+ {
+ $$ = strdup("required");
+ }
+ |
TOK_SETTER
{
$$ = strdup("setter");
--
NetSurf Generator for JavaScript bindings