From 56eee21ccb63cb7f040c5ce07bc226fbd229330d Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Fri, 21 Aug 2015 11:10:36 +0200 Subject: add dictionary support and generation The dictionary implementation is presetnt but incomplete. --- src/duk-libdom.c | 401 ++++++++++++++++++++++++++++++++++++-------------- src/ir.c | 434 +++++++++++++++++++++++++++++++++---------------------- src/ir.h | 55 ++++--- 3 files changed, 583 insertions(+), 307 deletions(-) (limited to 'src') 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 -- cgit v1.2.3