From 74158664a1826e5763e7c6949a915c75c8c1a23d Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sat, 4 Jan 2014 09:38:43 +0000 Subject: split out jsapi class generation and make use interface map --- src/Makefile | 2 +- src/jsapi-libdom-infmap.c | 41 ++++++---- src/jsapi-libdom-init.c | 169 +++++++++++++------------------------- src/jsapi-libdom-jsclass.c | 180 +++++++++++++++++++++++++++++++++++++++++ src/jsapi-libdom.c | 196 ++++++--------------------------------------- src/jsapi-libdom.h | 8 +- 6 files changed, 293 insertions(+), 303 deletions(-) create mode 100644 src/jsapi-libdom-jsclass.c (limited to 'src') diff --git a/src/Makefile b/src/Makefile index 6b98bd8..e93cb99 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ CFLAGS := $(CFLAGS) -I$(BUILDDIR) -Isrc/ -g -DYYENABLE_NLS=0 # Sources in this directory -DIR_SOURCES := nsgenbind.c webidl-ast.c nsgenbind-ast.c jsapi-libdom.c jsapi-libdom-function.c jsapi-libdom-property.c jsapi-libdom-init.c jsapi-libdom-new.c jsapi-libdom-infmap.c +DIR_SOURCES := nsgenbind.c webidl-ast.c nsgenbind-ast.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/jsapi-libdom-infmap.c b/src/jsapi-libdom-infmap.c index d02ae65..d0ffbd8 100644 --- a/src/jsapi-libdom-infmap.c +++ b/src/jsapi-libdom-infmap.c @@ -160,7 +160,7 @@ interface_topoligical_sort(struct binding_interface *srcinf, int infc) } /* build interface map and return the first interface */ -struct genbind_node * +int build_interface_map(struct genbind_node *binding_node, struct webidl_node *webidl_ast, int *interfacec_out, @@ -179,7 +179,7 @@ build_interface_map(struct genbind_node *binding_node, GENBIND_NODE_TYPE_BINDING_INTERFACE); if (interfacec == 0) { - return NULL; + return -1; } if (options->verbose) { printf("Binding has %d interfaces\n", interfacec); @@ -187,15 +187,14 @@ build_interface_map(struct genbind_node *binding_node, interfaces = calloc(interfacec, sizeof(struct binding_interface)); if (interfaces == NULL) { - return NULL; + return -1; } /* fill in map with binding node data */ idx = 0; - node = genbind_node_find_type( - genbind_node_getnode(binding_node), - node, - GENBIND_NODE_TYPE_BINDING_INTERFACE); + node = genbind_node_find_type(genbind_node_getnode(binding_node), + node, + GENBIND_NODE_TYPE_BINDING_INTERFACE); while (node != NULL) { /* binding node */ @@ -208,13 +207,13 @@ build_interface_map(struct genbind_node *binding_node, GENBIND_NODE_TYPE_IDENT)); if (interfaces[idx].name == NULL) { free(interfaces); - return NULL; + return -1; } /* get interface info from webidl */ if (fill_binding_interface(webidl_ast, interfaces + idx) == -1) { free(interfaces); - return NULL; + return -1; } interfaces[idx].refcount = 0; @@ -260,7 +259,7 @@ build_interface_map(struct genbind_node *binding_node, if (reinterfaces == NULL) { fprintf(stderr,"Unable to grow interface map\n"); free(interfaces); - return NULL; + return -1; } interfaces = reinterfaces; @@ -280,7 +279,7 @@ build_interface_map(struct genbind_node *binding_node, interfaces[idx].name, interfaces[idx].inherit_name); free(interfaces); - return NULL; + return -1; } interfaces[interfacec].inherit_idx = -1; @@ -305,20 +304,31 @@ build_interface_map(struct genbind_node *binding_node, reinterfaces = interface_topoligical_sort(interfaces, interfacec); free(interfaces); if (reinterfaces == NULL) { - return NULL; + return -1; } interfaces = reinterfaces; /* compute inheritance and refcounts on sorted map */ compute_inherit_refcount(interfaces, interfacec); + /* setup output index values */ + inf = 0; + for (idx = 0; idx < interfacec; idx++ ) { + if (interfaces[idx].node == NULL) { + interfaces[idx].output_idx = -1; + } else { + interfaces[idx].output_idx = inf; + inf++; + } + } + /* show the interface map */ if (options->verbose) { for (idx = 0; idx < interfacec; idx++ ) { printf("interface num:%d\n" " name:%s node:%p widl:%p\n" " inherit:%s inherit idx:%d refcount:%d\n" - " own functions:%d own properties:%d\n", + " own functions:%d own properties:%d output idx:%d\n", idx, interfaces[idx].name, interfaces[idx].node, @@ -327,12 +337,13 @@ build_interface_map(struct genbind_node *binding_node, interfaces[idx].inherit_idx, interfaces[idx].refcount, interfaces[idx].own_functions, - interfaces[idx].own_properties); + interfaces[idx].own_properties, + interfaces[idx].output_idx); } } *interfacec_out = interfacec; *interfaces_out = interfaces; - return interfaces[0].node; + return 0; } diff --git a/src/jsapi-libdom-init.c b/src/jsapi-libdom-init.c index 6dfc66f..1077c2d 100644 --- a/src/jsapi-libdom-init.c +++ b/src/jsapi-libdom-init.c @@ -19,8 +19,6 @@ #include "webidl-ast.h" #include "jsapi-libdom.h" -static int output_const_defines(struct binding *binding, const char *interface); - static int output_cast_literal(struct binding *binding, struct webidl_node *node) { @@ -159,60 +157,64 @@ output_interface_consts(struct binding *binding, return 0; } -/* callback to emit implements property spec */ -static int webidl_const_spec_implements_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - return output_const_defines(binding, webidl_node_gettext(node)); -} - -/** generate property definitions for constants */ -static int -output_const_defines(struct binding *binding, const char *interface) +static int generate_prototype_init(struct binding *binding, int inf) { - struct webidl_node *interface_node; - struct webidl_node *inherit_node; - int res = 0; + int inherit_inf; - /* find interface in webidl with correct ident attached */ - interface_node = webidl_node_find_type_ident(binding->wi_ast, - WEBIDL_NODE_TYPE_INTERFACE, - interface); - - if (interface_node == NULL) { - fprintf(stderr, - "Unable to find interface %s in loaded WebIDL\n", - interface); - return -1; + /* find this interfaces parent interface to inherit prototype from */ + inherit_inf = binding->interfaces[inf].inherit_idx; + while ((inherit_inf != -1) && + (binding->interfaces[inherit_inf].node == NULL)) { + inherit_inf = binding->interfaces[inherit_inf].inherit_idx; } - fprintf(binding->outfile, "\t/**** %s ****/\n", interface); - - /* write the property defines for this interface */ - res = output_interface_consts(binding, interface_node); - + fprintf(binding->outfile, + "\n" + "\tprototype = JS_InitClass(cx, " + "parent, "); + + /* either this init is being constructed without a chain or is + * using a prototype of a previously initialised class + */ + if (inherit_inf == -1) { + fprintf(binding->outfile, + "NULL, "); + } else { + fprintf(binding->outfile, + "prototypes[%d], ", + binding->interfaces[inherit_inf].output_idx); + } - /* check for inherited nodes and insert them too */ - inherit_node = webidl_node_find_type( - webidl_node_getnode(interface_node), - NULL, - WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE); + fprintf(binding->outfile, + "&JSClass_%s, " + "NULL, " + "0, " + "NULL, " + "NULL, " + "NULL, " + "NULL);\n", + binding->interfaces[inf].name); + + /* check prototype construction */ + fprintf(binding->outfile, + "\tif (prototype == NULL) {\n" + "\t\treturn %d;\n" + "\t}\n\n", + binding->interfaces[inf].output_idx); - if (inherit_node != NULL) { - res = output_const_defines(binding, - webidl_node_gettext(inherit_node)); - } + /* store result */ + fprintf(binding->outfile, + "\tprototypes[%d] = prototype;\n", + binding->interfaces[inf].output_idx); - if (res == 0) { - res = webidl_node_for_each_type( - webidl_node_getnode(interface_node), - WEBIDL_NODE_TYPE_INTERFACE_IMPLEMENTS, - webidl_const_spec_implements_cb, - binding); - } + /* output the consts for the interface and ancestors if necessary */ + do { + output_interface_consts(binding, binding->interfaces[inf].widl_node); + inf = binding->interfaces[inf].inherit_idx; + } while (inf != inherit_inf); - return res; + return 0; } /** generate class initialisers @@ -263,75 +265,16 @@ int output_class_init(struct binding *binding) if (api_node != NULL) { output_code_block(binding, genbind_node_getnode(api_node)); } else { + /* generate interface init for each class in binding */ for (inf = 0; inf < binding->interfacec; inf++) { - - fprintf(binding->outfile, - "\n" - "\tprototype = JS_InitClass(cx, " - "parent, "); - - if (binding->interfaces[inf].inherit_idx == -1) { - /* interface does not get its - * prototypes from another interface - * we are generating - */ - fprintf(binding->outfile, - "NULL, " - "&JSClass_%s, " - "NULL, " - "0, " - "NULL, " - "NULL, " - "NULL, " - "NULL);\n", - binding->interfaces[inf].name); - - fprintf(binding->outfile, - "\tif (prototype == NULL) {\n" - "\t\treturn %d;\n" - "\t}\n\n", - inf); - - fprintf(binding->outfile, - "\tprototypes[%d] = prototype;\n", - inf); - - output_const_defines(binding, - binding->interfaces[inf].name); - - } else { - /* interface prototype is based on one - * we already generated (interface map - * is topologicaly sorted */ - assert(binding->interfaces[inf].inherit_idx < inf); - - fprintf(binding->outfile, - "prototypes[%d], " - "&JSClass_%s, " - "NULL, " - "0, " - "NULL, " - "NULL, " - "NULL, " - "NULL);\n", - binding->interfaces[inf].inherit_idx, - binding->interfaces[inf].name); - - fprintf(binding->outfile, - "\tif (prototype == NULL) {\n" - "\t\treturn %d;\n" - "\t}\n\n", - inf); - - fprintf(binding->outfile, - "\tprototypes[%d] = prototype;\n", - inf); - - output_interface_consts(binding, - binding->interfaces[inf].widl_node); - + /* skip generating javascript class + * initialisation for interfaces not in binding + */ + if (binding->interfaces[inf].node != NULL) { + generate_prototype_init(binding, inf); } } + fprintf(binding->outfile, "\n\treturn %d;\n", inf); diff --git a/src/jsapi-libdom-jsclass.c b/src/jsapi-libdom-jsclass.c new file mode 100644 index 0000000..3a5a84c --- /dev/null +++ b/src/jsapi-libdom-jsclass.c @@ -0,0 +1,180 @@ +/* Javascript spidemonkey API to libdom binding generation for class + * initilisation + * + * This file is part of nsgenbind. + * Licensed under the MIT License, + * http://www.opensource.org/licenses/mit-license.php + * Copyright 2012 Vincent Sanders + */ + +#include +#include +#include +#include +#include +#include + +#include "options.h" +#include "nsgenbind-ast.h" +#include "webidl-ast.h" +#include "jsapi-libdom.h" + +#define HDROUTF(bndg, fmt, args...) do { \ + if (bndg->hdrfile != NULL) { \ + fprintf(bndg->hdrfile, fmt, ##args); \ + } \ + } while(0) + +static bool interface_is_global(struct genbind_node *interface_node) +{ + if (genbind_node_find_type_ident( + genbind_node_getnode(interface_node), + NULL, + GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS, + "global") != NULL) { + return true; + } + + return false; +} + +static int output_jsclass(struct binding *binding, + const char *interface_name, + struct genbind_node *interface_node) +{ + /* output the class declaration */ + HDROUTF(binding, "JSClass JSClass_%s;\n", interface_name); + + /* output the class definition */ + fprintf(binding->outfile, + "JSClass JSClass_%s = {\n" + "\t\"%s\",\n", + interface_name, + interface_name); + + /* generate class flags */ + if (interface_is_global(interface_node)) { + fprintf(binding->outfile, "\tJSCLASS_GLOBAL_FLAGS"); + } else { + fprintf(binding->outfile, "\t0"); + } + + if (binding->resolve != NULL) { + fprintf(binding->outfile, " | JSCLASS_NEW_RESOLVE"); + } + + if (binding->mark != NULL) { + fprintf(binding->outfile, " | JSAPI_JSCLASS_MARK_IS_TRACE"); + } + + if (binding->has_private) { + fprintf(binding->outfile, " | JSCLASS_HAS_PRIVATE"); + } + + fprintf(binding->outfile, ",\n"); + + /* add property */ + if (binding->addproperty != NULL) { + fprintf(binding->outfile, + "\tjsapi_property_add,\t/* addProperty */\n"); + } else { + fprintf(binding->outfile, + "\tJS_PropertyStub,\t/* addProperty */\n"); + } + + /* del property */ + if (binding->delproperty != NULL) { + fprintf(binding->outfile, + "\tjsapi_property_del,\t/* delProperty */\n"); + } else { + fprintf(binding->outfile, + "\tJS_PropertyStub,\t/* delProperty */\n"); + } + + /* get property */ + if (binding->getproperty != NULL) { + fprintf(binding->outfile, + "\tjsapi_property_get,\t/* getProperty */\n"); + } else { + fprintf(binding->outfile, + "\tJS_PropertyStub,\t/* getProperty */\n"); + } + + /* set property */ + if (binding->setproperty != NULL) { + fprintf(binding->outfile, + "\tjsapi_property_set,\t/* setProperty */\n"); + } else { + fprintf(binding->outfile, + "\tJS_StrictPropertyStub,\t/* setProperty */\n"); + } + + /* enumerate */ + if (binding->enumerate != NULL) { + fprintf(binding->outfile, + "\tjsclass_enumerate,\t/* enumerate */\n"); + } else { + fprintf(binding->outfile, + "\tJS_EnumerateStub,\t/* enumerate */\n"); + } + + /* resolver */ + if (binding->resolve != NULL) { + fprintf(binding->outfile, + "\t(JSResolveOp)jsclass_resolve,\t/* resolve */\n"); + } else { + fprintf(binding->outfile, + "\tJS_ResolveStub,\t\t/* resolve */\n"); + } + + fprintf(binding->outfile, "\tJS_ConvertStub,\t\t/* convert */\n"); + + if (binding->has_private || (binding->finalise != NULL)) { + fprintf(binding->outfile, + "\tjsclass_finalize,\t/* finalizer */\n"); + } else { + fprintf(binding->outfile, + "\tJS_FinalizeStub,\t/* finalizer */\n"); + } + fprintf(binding->outfile, + "\t0,\t\t\t/* reserved */\n" + "\tNULL,\t\t\t/* checkAccess */\n" + "\tNULL,\t\t\t/* call */\n" + "\tNULL,\t\t\t/* construct */\n" + "\tNULL,\t\t\t/* xdr Object */\n" + "\tNULL,\t\t\t/* hasInstance */\n"); + + /* trace/mark */ + if (binding->mark != NULL) { + fprintf(binding->outfile, + "\tJSAPI_JSCLASS_MARKOP(jsclass_mark),\n"); + } else { + fprintf(binding->outfile, "\tNULL,\t\t\t/* trace/mark */\n"); + } + + fprintf(binding->outfile, + "\tJSAPI_CLASS_NO_INTERNAL_MEMBERS\n" + "};\n\n"); + + return 0; +} + +int +output_jsclasses(struct binding *binding) +{ + int inf; + + for (inf = 0; inf < binding->interfacec; inf++) { + /* skip generating javascript classes for interfaces + * not in binding + */ + if (binding->interfaces[inf].node == NULL) { + continue; + } + + output_jsclass(binding, + binding->interfaces[inf].name, + binding->interfaces[inf].node); + } + return 0; +} diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c index f011342..1bb6d28 100644 --- a/src/jsapi-libdom.c +++ b/src/jsapi-libdom.c @@ -25,11 +25,6 @@ " * nsgenbind is similar to a compiler is a purely transformative tool which\n" \ " * explicitly makes no copyright claim on this generated output" -#define HDROUTF(bndg, fmt, args...) do { \ - if (bndg->hdrfile != NULL) { \ - fprintf(bndg->hdrfile, fmt, ##args); \ - } \ - } while(0) static int webidl_file_cb(struct genbind_node *node, void *ctx) @@ -543,163 +538,7 @@ output_forward_declarations(struct binding *binding) return 0; } -static bool interface_is_global(struct genbind_node *interface_node) -{ - if (genbind_node_find_type_ident( - genbind_node_getnode(interface_node), - NULL, - GENBIND_NODE_TYPE_BINDING_INTERFACE_FLAGS, - "global") != NULL) { - return true; - } - - return false; -} - -static int output_jsclass(struct genbind_node *interface_node, void *ctx) -{ - struct binding *binding = ctx; - struct genbind_node *interface_list; - const char *interface_ident; - - interface_list = genbind_node_getnode(interface_node); - if (interface_list == NULL) - return -1; /* bad AST */ - - interface_ident = genbind_node_gettext( - genbind_node_find_type(interface_list, - NULL, - GENBIND_NODE_TYPE_IDENT)); - if (interface_ident == NULL) - return -1; /* bad AST */ - - /* output the class declaration */ - HDROUTF(binding, "JSClass JSClass_%s;\n", interface_ident); - - /* output the class definition */ - fprintf(binding->outfile, - "JSClass JSClass_%s = {\n" - "\t\"%s\",\n", - interface_ident, - interface_ident); - - /* generate class flags */ - if (interface_is_global(interface_node)) { - fprintf(binding->outfile, "\tJSCLASS_GLOBAL_FLAGS"); - } else { - fprintf(binding->outfile, "\t0"); - } - - if (binding->resolve != NULL) { - fprintf(binding->outfile, " | JSCLASS_NEW_RESOLVE"); - } - - if (binding->mark != NULL) { - fprintf(binding->outfile, " | JSAPI_JSCLASS_MARK_IS_TRACE"); - } - - if (binding->has_private) { - fprintf(binding->outfile, " | JSCLASS_HAS_PRIVATE"); - } - - fprintf(binding->outfile, ",\n"); - - /* add property */ - if (binding->addproperty != NULL) { - fprintf(binding->outfile, - "\tjsapi_property_add,\t/* addProperty */\n"); - } else { - fprintf(binding->outfile, - "\tJS_PropertyStub,\t/* addProperty */\n"); - } - - /* del property */ - if (binding->delproperty != NULL) { - fprintf(binding->outfile, - "\tjsapi_property_del,\t/* delProperty */\n"); - } else { - fprintf(binding->outfile, - "\tJS_PropertyStub,\t/* delProperty */\n"); - } - - /* get property */ - if (binding->getproperty != NULL) { - fprintf(binding->outfile, - "\tjsapi_property_get,\t/* getProperty */\n"); - } else { - fprintf(binding->outfile, - "\tJS_PropertyStub,\t/* getProperty */\n"); - } - /* set property */ - if (binding->setproperty != NULL) { - fprintf(binding->outfile, - "\tjsapi_property_set,\t/* setProperty */\n"); - } else { - fprintf(binding->outfile, - "\tJS_StrictPropertyStub,\t/* setProperty */\n"); - } - - /* enumerate */ - if (binding->enumerate != NULL) { - fprintf(binding->outfile, - "\tjsclass_enumerate,\t/* enumerate */\n"); - } else { - fprintf(binding->outfile, - "\tJS_EnumerateStub,\t/* enumerate */\n"); - } - - /* resolver */ - if (binding->resolve != NULL) { - fprintf(binding->outfile, - "\t(JSResolveOp)jsclass_resolve,\t/* resolve */\n"); - } else { - fprintf(binding->outfile, - "\tJS_ResolveStub,\t\t/* resolve */\n"); - } - - fprintf(binding->outfile, "\tJS_ConvertStub,\t\t/* convert */\n"); - - if (binding->has_private || (binding->finalise != NULL)) { - fprintf(binding->outfile, - "\tjsclass_finalize,\t/* finalizer */\n"); - } else { - fprintf(binding->outfile, - "\tJS_FinalizeStub,\t/* finalizer */\n"); - } - fprintf(binding->outfile, - "\t0,\t\t\t/* reserved */\n" - "\tNULL,\t\t\t/* checkAccess */\n" - "\tNULL,\t\t\t/* call */\n" - "\tNULL,\t\t\t/* construct */\n" - "\tNULL,\t\t\t/* xdr Object */\n" - "\tNULL,\t\t\t/* hasInstance */\n"); - - /* trace/mark */ - if (binding->mark != NULL) { - fprintf(binding->outfile, - "\tJSAPI_JSCLASS_MARKOP(jsclass_mark),\n"); - } else { - fprintf(binding->outfile, "\tNULL,\t\t\t/* trace/mark */\n"); - } - - fprintf(binding->outfile, - "\tJSAPI_CLASS_NO_INTERNAL_MEMBERS\n" - "};\n\n"); - - return 0; -} - -static int -output_jsclasses(struct binding *binding) -{ - - return genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_INTERFACE, - output_jsclass, - binding); - -} /** generate structure definition for internal class data * @@ -821,6 +660,24 @@ binding_has_private(struct genbind_node *binding_list) +/** obtain the name to use for the binding. + * + * @todo it should be possible to specify the binding name instead of + * just using the name of the first interface. + */ +static const char *get_binding_name(struct genbind_node *binding_node) +{ + return genbind_node_gettext( + genbind_node_find_type( + genbind_node_getnode( + genbind_node_find_type( + genbind_node_getnode(binding_node), + NULL, + GENBIND_NODE_TYPE_BINDING_INTERFACE)), + NULL, + GENBIND_NODE_TYPE_IDENT)); +} + static struct binding * binding_new(struct options *options, struct genbind_node *genbind_ast, @@ -831,7 +688,6 @@ binding_new(struct options *options, int interfacec; /* numer of interfaces in the interface map */ struct binding_interface *interfaces; /* binding interface map */ - struct genbind_node *interface_node; struct genbind_node *binding_list; char *hdrguard = NULL; struct webidl_node *webidl_ast = NULL; @@ -845,11 +701,10 @@ binding_new(struct options *options, } /* build the bindings interface (class) name map */ - interface_node = build_interface_map(binding_node, - webidl_ast, - &interfacec, - &interfaces); - if (interface_node == NULL) { + if (build_interface_map(binding_node, + webidl_ast, + &interfacec, + &interfaces) != 0) { /* the binding must have at least one interface */ fprintf(stderr, "Error: Binding must have a valid interface\n"); return NULL; @@ -888,13 +743,10 @@ binding_new(struct options *options, nb->interfaces = interfaces; nb->interfacec = interfacec; - /* @todo it should be possible to specify the binding name - * instead of just using the name of the first interface. - * - * @todo get rid of the interface element out of the binding + /* @todo get rid of the interface element out of the binding * struct and use the interface map instead. */ - nb->name = nb->interface = interfaces[0].name; + nb->name = nb->interface = get_binding_name(binding_node); nb->outfile = options->outfilehandle; nb->srcfile = options->outfilehandle; nb->hdrfile = options->hdrfilehandle; diff --git a/src/jsapi-libdom.h b/src/jsapi-libdom.h index 82258ae..cf27318 100644 --- a/src/jsapi-libdom.h +++ b/src/jsapi-libdom.h @@ -21,6 +21,7 @@ struct binding_interface { int inherit_idx; /* index into binding map of inherited interface or -1 for not in map */ int refcount; /* number of entries in map that refer to this interface */ + int output_idx; /* for interfaces that will be output (node is valid) this is the output array index */ }; struct binding { @@ -59,15 +60,18 @@ struct binding { int jsapi_libdom_output(struct options *options, struct genbind_node *genbind_ast, struct genbind_node *binding_node); /** build interface mapping */ -struct genbind_node * -build_interface_map(struct genbind_node *binding_node, +int build_interface_map(struct genbind_node *binding_node, struct webidl_node *webidl_ast, int *interfacec_out, struct binding_interface **interfaces_out); + /** output code block from a node */ void output_code_block(struct binding *binding, struct genbind_node *codelist); +/** generate classes */ +int output_jsclasses(struct binding *binding); + /* Generate jsapi native function specifiers */ int output_function_spec(struct binding *binding); -- cgit v1.2.3