summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/duk-libdom.c401
-rw-r--r--src/ir.c434
-rw-r--r--src/ir.h55
3 files changed, 583 insertions, 307 deletions
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