diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/jsapi-libdom-function.c | 837 | ||||
-rw-r--r-- | src/jsapi-libdom-init.c | 286 | ||||
-rw-r--r-- | src/jsapi-libdom-jsclass.c | 180 | ||||
-rw-r--r-- | src/jsapi-libdom-new.c | 395 | ||||
-rw-r--r-- | src/jsapi-libdom-property.c | 1156 | ||||
-rw-r--r-- | src/jsapi-libdom.c | 904 |
7 files changed, 0 insertions, 3760 deletions
diff --git a/src/Makefile b/src/Makefile index f6f5055..a525740 100644 --- a/src/Makefile +++ b/src/Makefile @@ -5,8 +5,6 @@ DIR_SOURCES := nsgenbind.c utils.c webidl-ast.c nsgenbind-ast.c ir.c \ duk-libdom.c duk-libdom-interface.c duk-libdom-dictionary.c \ duk-libdom-common.c duk-libdom-generated.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 $(BUILDDIR)/%-lexer.c $(BUILDDIR)/%-lexer.h: src/%-lexer.l diff --git a/src/jsapi-libdom-function.c b/src/jsapi-libdom-function.c deleted file mode 100644 index 4f62bcd..0000000 --- a/src/jsapi-libdom-function.c +++ /dev/null @@ -1,837 +0,0 @@ -/* jsapi function generation for webidl bodies - * - * This file is part of nsgenbind. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> - */ - -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include "options.h" -#include "nsgenbind-ast.h" -#include "webidl-ast.h" -#include "jsapi-libdom.h" - -static int webidl_operator_spec(struct binding *binding, - struct binding_interface *inf, - struct webidl_node *node) -{ - struct webidl_node *ident_node; - - ident_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - if (ident_node == NULL) { - /* operation without identifier - must have special keyword - * http://www.w3.org/TR/WebIDL/#idl-operations - */ - } else { - fprintf(binding->outfile, - "\tJSAPI_FS(%s, %s, 0, JSPROP_ENUMERATE ),\n", - inf->name, - webidl_node_gettext(ident_node)); - /* @todo number of args to that FN_FS() call should be correct */ - } - return 0; -} - -int output_function_spec(struct binding *binding) -{ - int inf; - int res; - struct webidl_node *list_node; - struct webidl_node *op_node; /* operation on list node */ - - /* generate functions for each interface in the map */ - for (inf = 0; inf < binding->interfacec; inf++) { - if (binding->interfaces[inf].own_functions == 0) { - continue; - } - - fprintf(binding->outfile, - "static JSFunctionSpec JSClass_%s_functions[] = {\n", - binding->interfaces[inf].name); - - /* iterate each list within an interface */ - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (list_node != NULL) { - /* iterate through operations in a list */ - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - NULL, - WEBIDL_NODE_TYPE_OPERATION); - - while (op_node != NULL) { - res = webidl_operator_spec( - binding, - &binding->interfaces[inf], - op_node); - if (res != 0) { - return res; - } - - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - op_node, - WEBIDL_NODE_TYPE_OPERATION); - } - - - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - list_node, - WEBIDL_NODE_TYPE_LIST); - } - - fprintf(binding->outfile, "\tJSAPI_FS_END\n};\n\n"); - - } - return 0; -} - -static int output_return(struct binding *binding, - const char *ident, - struct webidl_node *node) -{ - struct webidl_node *arglist_node = NULL; - struct webidl_node *type_node = NULL; - struct webidl_node *type_base = NULL; - enum webidl_type webidl_arg_type; - - arglist_node = webidl_node_find_type(node, - NULL, - WEBIDL_NODE_TYPE_LIST); - - if (arglist_node == NULL) { - return -1; /* @todo check if this is broken AST */ - } - - type_node = webidl_node_find_type(webidl_node_getnode(arglist_node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - type_base = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(type_base); - - switch (webidl_arg_type) { - case WEBIDL_TYPE_USER: - /* User type are represented with jsobject */ - fprintf(binding->outfile, - "\tJSAPI_FUNC_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n", - ident); - - break; - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - fprintf(binding->outfile, - "\tJSAPI_FUNC_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(%s));\n", - ident); - - break; - - case WEBIDL_TYPE_BYTE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_BYTE"); - break; - - case WEBIDL_TYPE_OCTET: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_OCTET"); - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - fprintf(binding->outfile, - "\tJSAPI_FUNC_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_SHORT: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_SHORT"); - break; - - case WEBIDL_TYPE_LONGLONG: - WARN(WARNING_UNIMPLEMENTED, - "Unhandled type WEBIDL_TYPE_LONGLONG"); - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - fprintf(binding->outfile, - "\tJSAPI_FUNC_SET_RVAL(cx, vp, INT_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_STRING: - /* JSString * */ - fprintf(binding->outfile, - "\tJSAPI_FUNC_SET_RVAL(cx, vp, JSAPI_STRING_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_SEQUENCE: - WARN(WARNING_UNIMPLEMENTED, - "Unhandled type WEBIDL_TYPE_SEQUENCE"); - break; - - case WEBIDL_TYPE_OBJECT: - /* JSObject * */ - fprintf(binding->outfile, - "\tJSAPI_FUNC_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_DATE: - WARN(WARNING_UNIMPLEMENTED, - "Unhandled type WEBIDL_TYPE_DATE"); - break; - - case WEBIDL_TYPE_VOID: - /* specifically requires no value */ - break; - - default: - break; - } - - return 0; -} - - -/* generate variable declaration of the correct type with appropriate default */ -static int output_return_declaration(struct binding *binding, - const char *ident, - struct webidl_node *node) -{ - struct webidl_node *arglist_node = NULL; - struct webidl_node *type_node = NULL; - struct webidl_node *type_name = NULL; - struct webidl_node *type_base = NULL; - enum webidl_type webidl_arg_type; - struct webidl_node *type_mod = NULL; - - arglist_node = webidl_node_find_type(node, - NULL, - WEBIDL_NODE_TYPE_LIST); - - if (arglist_node == NULL) { - return -1; /* @todo check if this is broken AST */ - } - - type_node = webidl_node_find_type(webidl_node_getnode(arglist_node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - type_base = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(type_base); - - - switch (webidl_arg_type) { - case WEBIDL_TYPE_USER: - /* User type are represented with jsobject */ - type_name = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - fprintf(binding->outfile, - "\tJSObject *%s = NULL; /* %s */\n", - ident, - webidl_node_gettext(type_name)); - - break; - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - fprintf(binding->outfile, "\tJSBool %s = JS_FALSE;\n",ident); - - break; - - case WEBIDL_TYPE_BYTE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_BYTE"); - break; - - case WEBIDL_TYPE_OCTET: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_OCTET"); - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - fprintf(binding->outfile, "\tdouble %s = 0;\n", ident); - break; - - case WEBIDL_TYPE_SHORT: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_SHORT"); - break; - - case WEBIDL_TYPE_LONGLONG: - WARN(WARNING_UNIMPLEMENTED, - "Unhandled type WEBIDL_TYPE_LONGLONG"); - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - type_mod = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && - (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, "\tuint32_t %s = 0;\n", ident); - } else { - fprintf(binding->outfile, "\tint32_t %s = 0;\n", ident); - } - break; - - case WEBIDL_TYPE_STRING: - /* JSString * */ - fprintf(binding->outfile, - "\tJSString *%s = NULL;\n", - ident); - break; - - case WEBIDL_TYPE_SEQUENCE: - WARN(WARNING_UNIMPLEMENTED, - "Unhandled type WEBIDL_TYPE_SEQUENCE"); - break; - - case WEBIDL_TYPE_OBJECT: - /* JSObject * */ - fprintf(binding->outfile, "\tJSObject *%s = NULL;\n", ident); - break; - - case WEBIDL_TYPE_DATE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_DATE"); - break; - - case WEBIDL_TYPE_VOID: - /* specifically requires no value */ - break; - - default: - break; - } - return 0; -} - -/** creates all the variable definitions - * - * generate functions variables (including return value) with default - * values as appropriate - */ -static void -output_variable_definitions(struct binding *binding, - struct webidl_node *operation_list) -{ - struct webidl_node *operation_ident; - struct webidl_node *arglist_node; - struct webidl_node *arglist; /* argument list */ - struct webidl_node *arg_node = NULL; - struct webidl_node *arg_ident = NULL; - struct webidl_node *arg_type = NULL; - struct webidl_node *arg_type_base = NULL; - struct webidl_node *arg_type_ident = NULL; - enum webidl_type webidl_arg_type; - struct webidl_node *type_mod = NULL; - - /* input variables */ - arglist_node = webidl_node_find_type(operation_list, - NULL, - WEBIDL_NODE_TYPE_LIST); - - if (arglist_node == NULL) { - return; /* @todo check if this is broken AST */ - } - - arglist = webidl_node_getnode(arglist_node); - - arg_node = webidl_node_find_type(arglist, - arg_node, - WEBIDL_NODE_TYPE_ARGUMENT); - - /* at least one argument or private need to generate argv variable */ - if ((arg_node != NULL) || binding->has_private) { - fprintf(binding->outfile, - "\tjsval *argv = JSAPI_FUNC_ARGV(cx, vp);\n"); - } - - while (arg_node != NULL) { - /* generate variable to hold the argument */ - arg_ident = webidl_node_find_type(webidl_node_getnode(arg_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - - arg_type = webidl_node_find_type(webidl_node_getnode(arg_node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - arg_type_base = webidl_node_find_type(webidl_node_getnode(arg_type), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(arg_type_base); - - switch (webidl_arg_type) { - case WEBIDL_TYPE_USER: - if (options->verbose) { - - operation_ident = webidl_node_find_type(operation_list, - NULL, - WEBIDL_NODE_TYPE_IDENT); - - arg_type_ident = webidl_node_find_type(webidl_node_getnode(arg_type), - NULL, - WEBIDL_NODE_TYPE_IDENT); - - fprintf(stderr, - "User type: %s:%s %s\n", - webidl_node_gettext(operation_ident), - webidl_node_gettext(arg_type_ident), - webidl_node_gettext(arg_ident)); - } - /* User type - jsobject then */ - fprintf(binding->outfile, - "\tJSObject *%s = NULL;\n", - webidl_node_gettext(arg_ident)); - - break; - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - fprintf(binding->outfile, - "\tJSBool %s = JS_FALSE;\n", - webidl_node_gettext(arg_ident)); - - break; - - case WEBIDL_TYPE_BYTE: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_BYTE\n"); - break; - - case WEBIDL_TYPE_OCTET: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_OCTET\n"); - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - fprintf(binding->outfile, - "\tdouble %s = 0;\n", - webidl_node_gettext(arg_ident)); - break; - - case WEBIDL_TYPE_SHORT: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_SHORT\n"); - break; - - case WEBIDL_TYPE_LONGLONG: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_LONGLONG\n"); - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - type_mod = webidl_node_find_type(webidl_node_getnode(arg_type), - NULL, - WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && - (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, - "\tuint32_t %s = 0;\n", - webidl_node_gettext(arg_ident)); - } else { - fprintf(binding->outfile, - "\tint32_t %s = 0;\n", - webidl_node_gettext(arg_ident)); - } - - break; - - case WEBIDL_TYPE_STRING: - /* JSString * */ - fprintf(binding->outfile, - "\tJSString *%s_jsstr = NULL;\n" - "\tint %s_len = 0;\n" - "\tchar *%s = NULL;\n", - webidl_node_gettext(arg_ident), - webidl_node_gettext(arg_ident), - webidl_node_gettext(arg_ident)); - break; - - case WEBIDL_TYPE_SEQUENCE: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_SEQUENCE\n"); - break; - - case WEBIDL_TYPE_OBJECT: - /* JSObject * */ - fprintf(binding->outfile, - "\tJSObject *%s = NULL;\n", - webidl_node_gettext(arg_ident)); - break; - - case WEBIDL_TYPE_DATE: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_DATE\n"); - break; - - case WEBIDL_TYPE_VOID: - fprintf(stderr, "Unsupported: WEBIDL_TYPE_VOID\n"); - break; - - default: - break; - } - - - /* next argument */ - arg_node = webidl_node_find_type(arglist, - arg_node, - WEBIDL_NODE_TYPE_ARGUMENT); - } - -} - -/** generate code to process operation input from javascript */ -static void -output_operation_input(struct binding *binding, - struct webidl_node *operation_list) -{ - struct webidl_node *arglist_node; - struct webidl_node *arglist; /* argument list */ - struct webidl_node *arg_node = NULL; - struct webidl_node *arg_ident = NULL; - struct webidl_node *arg_type = NULL; - struct webidl_node *arg_type_base = NULL; - struct webidl_node *type_mod = NULL; - enum webidl_type webidl_arg_type; - - int arg_cur = 0; /* current position in the input argument vector */ - - /* input variables */ - arglist_node = webidl_node_find_type(operation_list, - NULL, - WEBIDL_NODE_TYPE_LIST); - - if (arglist_node == NULL) { - return; /* @todo check if this is broken AST */ - } - - arglist = webidl_node_getnode(arglist_node); - - arg_node = webidl_node_find_type(arglist, - arg_node, - WEBIDL_NODE_TYPE_ARGUMENT); - while (arg_node != NULL) { - /* generate variable to hold the argument */ - arg_ident = webidl_node_find_type(webidl_node_getnode(arg_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - - arg_type = webidl_node_find_type(webidl_node_getnode(arg_node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - arg_type_base = webidl_node_find_type(webidl_node_getnode(arg_type), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(arg_type_base); - - switch (webidl_arg_type) { - case WEBIDL_TYPE_USER: - fprintf(binding->outfile, - "\tif (!JSAPI_JSVAL_IS_OBJECT(argv[%d])) {\n" - "\t\tJSType argtype;\n" - "\t\targtype = JS_TypeOfValue(cx, argv[%d]);\n" - "\t\tJSLOG(\"User argument is type %%s not an object\", JS_GetTypeName(cx, argtype));\n" - "\t\treturn JS_FALSE;\n" - "\t}\n" - "\t%s = JSVAL_TO_OBJECT(argv[%d]);\n", - arg_cur, - arg_cur, - webidl_node_gettext(arg_ident), - arg_cur); - break; - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - fprintf(binding->outfile, - "\tif (!JS_ValueToBoolean(cx, argv[%d], &%s)) {\n" - "\t\treturn JS_FALSE;\n" - "\t}\n", - arg_cur, - webidl_node_gettext(arg_ident)); - - break; - - case WEBIDL_TYPE_BYTE: - case WEBIDL_TYPE_OCTET: - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - fprintf(binding->outfile, - "\tdouble %s = 0;\n", - webidl_node_gettext(arg_ident)); - break; - - case WEBIDL_TYPE_SHORT: - case WEBIDL_TYPE_LONGLONG: - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - type_mod = webidl_node_find_type(webidl_node_getnode(arg_type), - NULL, - WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && - (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, - "\tJS_ValueToECMAUint32(cx, argv[%d], &%s);\n", - arg_cur, - webidl_node_gettext(arg_ident)); - } else { - fprintf(binding->outfile, - "\tJS_ValueToECMAInt32(cx, argv[%d], &%s);\n", - arg_cur, - webidl_node_gettext(arg_ident)); - } - break; - - case WEBIDL_TYPE_STRING: - /* JSString * */ - fprintf(binding->outfile, - "\tif (argc > %d) {\n" - "\t\t%s_jsstr = JS_ValueToString(cx, argv[%d]);\n" - "\t} else {\n" - "\t\t%s_jsstr = JS_ValueToString(cx, JSVAL_VOID);\n" - "\t}\n" - "\tif (%s_jsstr != NULL) {\n" - "\t\tJSString_to_char(%s_jsstr, %s, %s_len);\n" - "\t}\n\n", - arg_cur, - webidl_node_gettext(arg_ident), - arg_cur, - webidl_node_gettext(arg_ident), - webidl_node_gettext(arg_ident), - webidl_node_gettext(arg_ident), - webidl_node_gettext(arg_ident), - webidl_node_gettext(arg_ident)); - - break; - - case WEBIDL_TYPE_SEQUENCE: - break; - - case WEBIDL_TYPE_OBJECT: - /* JSObject * */ - fprintf(binding->outfile, - "\tJSObject *%s = NULL;\n", - webidl_node_gettext(arg_ident)); - break; - - case WEBIDL_TYPE_DATE: - case WEBIDL_TYPE_VOID: - break; - - default: - break; - } - - - /* next argument */ - arg_node = webidl_node_find_type(arglist, - arg_node, - WEBIDL_NODE_TYPE_ARGUMENT); - - arg_cur++; - } - - -} - -static int -output_operator_placeholder(struct binding *binding, - struct webidl_node *oplist, - struct webidl_node *ident_node) -{ - oplist = oplist; - - WARN(WARNING_UNIMPLEMENTED, - "operation %s.%s has no implementation\n", - binding->interface, - webidl_node_gettext(ident_node)); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"operation %s.%s has no implementation\");\n", - binding->interface, - webidl_node_gettext(ident_node)); - } - - return 0; -} - - -/* generate context data fetcher if the binding has private data */ -static inline int -output_private_get(struct binding *binding, const char *argname) -{ - int ret = 0; - - if (binding->has_private) { - - ret = fprintf(binding->outfile, - "\tstruct jsclass_private *%s;\n" - "\n" - "\t%s = JS_GetInstancePrivate(cx,\n" - "\t\t\tJSAPI_THIS_OBJECT(cx,vp),\n" - "\t\t\t&JSClass_%s,\n" - "\t\t\targv);\n" - "\tif (%s == NULL) {\n" - "\t\treturn JS_FALSE;\n" - "\t}\n\n", - argname, argname, binding->interface, argname); - - if (options->dbglog) { - ret += fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, JSAPI_THIS_OBJECT(cx,vp), %s);\n", argname); - } - } else { - if (options->dbglog) { - ret += fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, JSAPI_THIS_OBJECT(cx,vp));\n"); - } - - } - - return ret; -} - -/** - * Generate operator (function) body - * - * - */ -static int webidl_operator_body(struct binding *binding, - struct binding_interface *inf, - struct webidl_node *node) -{ - struct webidl_node *ident_node; - struct genbind_node *operation_node; - - ident_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - - if (ident_node == NULL) { - /* operation without identifier - must have special keyword - * http://www.w3.org/TR/WebIDL/#idl-operations - */ - WARN(WARNING_UNIMPLEMENTED, - "Unhandled operation with no name on %s\n", - binding->interface); - - return 0; - } - - /* normal operation with identifier */ - - fprintf(binding->outfile, - "static JSBool JSAPI_FUNC(%s, %s, JSContext *cx, uintN argc, jsval *vp)\n" - "{\n", - inf->name, - webidl_node_gettext(ident_node)); - - /* return value declaration */ - output_return_declaration(binding, "jsret", webidl_node_getnode(node)); - - output_variable_definitions(binding, webidl_node_getnode(node)); - - output_private_get(binding, "private"); - - output_operation_input(binding, webidl_node_getnode(node)); - - operation_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_OPERATION, - webidl_node_gettext(ident_node)); - - if (operation_node != NULL) { - output_code_block(binding, - genbind_node_getnode(operation_node)); - - } else { - output_operator_placeholder(binding, webidl_node_getnode(node), ident_node); - } - - output_return(binding, "jsret", webidl_node_getnode(node)); - - /* set return value an return true */ - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - - return 0; -} - - -/* exported interface documented in jsapi-libdom.h */ -int output_function_bodies(struct binding *binding) -{ - int inf; - int res; - struct webidl_node *list_node; - struct webidl_node *op_node; /* operation on list node */ - - /* generate functions for each interface in the map */ - for (inf = 0; inf < binding->interfacec; inf++) { - /* iterate each list within an interface */ - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (list_node != NULL) { - /* iterate through operations in a list */ - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - NULL, - WEBIDL_NODE_TYPE_OPERATION); - - while (op_node != NULL) { - res = webidl_operator_body( - binding, - &binding->interfaces[inf], - op_node); - if (res != 0) { - return res; - } - - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - op_node, - WEBIDL_NODE_TYPE_OPERATION); - } - - - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - list_node, - WEBIDL_NODE_TYPE_LIST); - } - } - return 0; -} diff --git a/src/jsapi-libdom-init.c b/src/jsapi-libdom-init.c deleted file mode 100644 index 1077c2d..0000000 --- a/src/jsapi-libdom-init.c +++ /dev/null @@ -1,286 +0,0 @@ -/* 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 <vince@netsurf-browser.org> - */ - -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#include "options.h" -#include "nsgenbind-ast.h" -#include "webidl-ast.h" -#include "jsapi-libdom.h" - -static int output_cast_literal(struct binding *binding, - struct webidl_node *node) -{ - struct webidl_node *type_node = NULL; - struct webidl_node *literal_node = NULL; - struct webidl_node *type_base = NULL; - enum webidl_type webidl_arg_type; - - type_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - type_base = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(type_base); - - switch (webidl_arg_type) { - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - literal_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_LITERAL_BOOL); - fprintf(binding->outfile, "BOOLEAN_TO_JSVAL(JS_FALSE)"); - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - literal_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_LITERAL_FLOAT); - fprintf(binding->outfile, "DOUBLE_TO_JSVAL(0.0)"); - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - literal_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_LITERAL_INT); - fprintf(binding->outfile, - "INT_TO_JSVAL(%d)", - webidl_node_getint(literal_node)); - break; - - case WEBIDL_TYPE_SHORT: - /* int16_t */ - literal_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_LITERAL_INT); - fprintf(binding->outfile, - "INT_TO_JSVAL(%d)", - webidl_node_getint(literal_node)); - break; - - - case WEBIDL_TYPE_STRING: - case WEBIDL_TYPE_BYTE: - case WEBIDL_TYPE_OCTET: - case WEBIDL_TYPE_LONGLONG: - case WEBIDL_TYPE_SEQUENCE: - case WEBIDL_TYPE_OBJECT: - case WEBIDL_TYPE_DATE: - case WEBIDL_TYPE_VOID: - case WEBIDL_TYPE_USER: - default: - WARN(WARNING_UNIMPLEMENTED, "types not allowed as literal"); - break; /* @todo these types are not allowed here */ - } - - return 0; -} - -static int webidl_const_define_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct webidl_node *ident_node; - - ident_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - if (ident_node == NULL) { - /* Broken AST - must have ident */ - return 1; - } - - fprintf(binding->outfile, - "\tJS_DefineProperty(cx, " - "prototype, " - "\"%s\", ", - webidl_node_gettext(ident_node)); - - output_cast_literal(binding, node); - - fprintf(binding->outfile, - ", " - "JS_PropertyStub, " - "JS_StrictPropertyStub, " - "JSPROP_READONLY | JSPROP_ENUMERATE | JSPROP_PERMANENT);\n\n"); - - return 0; - -} - - -/** output all the constant property defines for an interface */ -static int -output_interface_consts(struct binding *binding, - struct webidl_node *interface_node) -{ - struct webidl_node *members_node; - - /* generate property entries for each list (partial interfaces) */ - members_node = webidl_node_find_type( - webidl_node_getnode(interface_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (members_node != NULL) { - - /* for each const emit a property define */ - webidl_node_for_each_type(webidl_node_getnode(members_node), - WEBIDL_NODE_TYPE_CONST, - webidl_const_define_cb, - binding); - - - members_node = webidl_node_find_type( - webidl_node_getnode(interface_node), - members_node, - WEBIDL_NODE_TYPE_LIST); - } - - return 0; -} - - -static int generate_prototype_init(struct binding *binding, int inf) -{ - int inherit_inf; - - /* 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, - "\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); - } - - 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); - - /* store result */ - fprintf(binding->outfile, - "\tprototypes[%d] = prototype;\n", - binding->interfaces[inf].output_idx); - - /* 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 0; -} - -/** generate class initialisers - * - * Generates function to create the javascript class prototypes for - * each interface in the binding. - * - */ -int output_class_init(struct binding *binding) -{ - int res = 0; - struct genbind_node *api_node; - int inf; - - /* class Initialisor declaration */ - if (binding->hdrfile) { - - if (binding->interfacec > 1) { - fprintf(binding->hdrfile, - "\n#define %s_INTERFACE_COUNT %d", - binding->name, - binding->interfacec); - } - - fprintf(binding->hdrfile, - "\nint jsapi_InitClass_%s(JSContext *cx, JSObject *parent, JSObject **prototypes);\n\n", - binding->name); - - - } - - /* class Initialisor definition */ - fprintf(binding->outfile, - "int\n" - "jsapi_InitClass_%s(JSContext *cx, " - "JSObject *parent, " - "JSObject **prototypes)\n" - "{\n" - "\tJSObject *prototype;\n", - binding->name); - - /* check for the binding having an init override */ - api_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_API, - "init"); - - 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++) { - /* 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); - } - - fprintf(binding->outfile, "}\n\n"); - - return res; -} diff --git a/src/jsapi-libdom-jsclass.c b/src/jsapi-libdom-jsclass.c deleted file mode 100644 index 3a5a84c..0000000 --- a/src/jsapi-libdom-jsclass.c +++ /dev/null @@ -1,180 +0,0 @@ -/* 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 <vince@netsurf-browser.org> - */ - -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#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-new.c b/src/jsapi-libdom-new.c deleted file mode 100644 index b78c715..0000000 --- a/src/jsapi-libdom-new.c +++ /dev/null @@ -1,395 +0,0 @@ -/* Spidemonkey Javascript API to libdom binding generation for class - * construction. - * - * This file is part of nsgenbind. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2013 Vincent Sanders <vince@netsurf-browser.org> - */ - -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> - -#include "options.h" -#include "nsgenbind-ast.h" -#include "webidl-ast.h" -#include "jsapi-libdom.h" - -static int webidl_private_param_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct genbind_node *ident_node; - struct genbind_node *type_node; - - - ident_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_IDENT); - if (ident_node == NULL) - return -1; /* bad AST */ - - type_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_STRING); - if (type_node == NULL) - return -1; /* bad AST */ - - fprintf(binding->outfile, - ",\n\t\t%s%s", - genbind_node_gettext(type_node), - genbind_node_gettext(ident_node)); - - return 0; -} - -static int webidl_private_assign_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct genbind_node *ident_node; - const char *ident; - - ident_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_IDENT); - if (ident_node == NULL) - return -1; /* bad AST */ - - ident = genbind_node_gettext(ident_node); - - fprintf(binding->outfile, "\tprivate->%s = %s;\n", ident, ident); - - return 0; -} - - - -static int -output_binding_constructor(struct binding *binding) -{ - fprintf(binding->outfile, - "JSObject *jsapi_new_%s(JSContext *cx, \n", - binding->name); - - fprintf(binding->outfile, "\t\tJSObject *prototype, \n"); - - if (binding->interfacec != 1) { - fprintf(binding->outfile, "\t\tconst char *interface_name, \n"); - } - - fprintf(binding->outfile, "\t\tJSObject *parent"); - - genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_PRIVATE, - webidl_private_param_cb, - binding); - - fprintf(binding->outfile, ")"); - - return 0; -} - -static int -output_class_wprivate_multi(struct binding *binding) -{ - int inf; - - /* create and initialise private data */ - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = malloc(sizeof(struct jsclass_private));\n" - "\tif (private == NULL) {\n" - "\t\treturn NULL;\n" - "\t}\n"); - - genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_PRIVATE, - webidl_private_assign_cb, - binding); - - - fprintf(binding->outfile, "\n\n\t"); - - /* for each interface in the map generate initialisor */ - for (inf = 0; inf < binding->interfacec; inf++) { - - fprintf(binding->outfile, - "if (strcmp(interface_name, JSClass_%s.name) == 0) {\n", - binding->interfaces[inf].name); - - fprintf(binding->outfile, - "\n" - "\t\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n", - binding->interface); - - - fprintf(binding->outfile, - "\t\tif (newobject == NULL) {\n" - "\t\t\tfree(private);\n" - "\t\t\treturn NULL;\n" - "\t\t}\n\n"); - - /* root object to stop it being garbage collected */ - fprintf(binding->outfile, - "\t\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n" - "\t\t\tfree(private);\n" - "\t\t\treturn NULL;\n" - "\t\t}\n\n"); - - fprintf(binding->outfile, - "\n" - "\t\t/* attach private pointer */\n" - "\t\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n" - "\t\t\tfree(private);\n" - "\t\t\treturn NULL;\n" - "\t\t}\n\n"); - - - /* attach operations and attributes (functions and properties) */ - fprintf(binding->outfile, - "\t\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n" - "\t\t\tfree(private);\n" - "\t\t\treturn NULL;\n" - "\t\t}\n\n"); - - fprintf(binding->outfile, - "\t\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n" - "\t\t\tfree(private);\n" - "\t\t\treturn NULL;\n" - "\t\t}\n\n"); - - /* unroot object */ - fprintf(binding->outfile, - "\t\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n" - "\t} else "); - } - fprintf(binding->outfile, - "{\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n"); - - return 0; -} - -static int -output_class_wprivate(struct binding *binding, struct genbind_node *api_node) -{ - /* create and initialise private data */ - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = malloc(sizeof(struct jsclass_private));\n" - "\tif (private == NULL) {\n" - "\t\treturn NULL;\n" - "\t}\n"); - - genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_PRIVATE, - webidl_private_assign_cb, - binding); - - if (api_node != NULL) { - output_code_block(binding, genbind_node_getnode(api_node)); - } else { - fprintf(binding->outfile, - "\n" - "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n", - binding->interface); - } - - fprintf(binding->outfile, - "\tif (newobject == NULL) {\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - /* root object to stop it being garbage collected */ - fprintf(binding->outfile, - "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - fprintf(binding->outfile, - "\n" - "\t/* attach private pointer */\n" - "\tif (JS_SetPrivate(cx, newobject, private) != JS_TRUE) {\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - - /* attach operations and attributes (functions and properties) */ - fprintf(binding->outfile, - "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - fprintf(binding->outfile, - "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - /* unroot object */ - fprintf(binding->outfile, - "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n"); - - return 0; -} - -static int -output_class_woprivate_multi(struct binding *binding) -{ - int inf; - - fprintf(binding->outfile, "\n\t"); - - /* for each interface in the map generate initialisor */ - for (inf = 0; inf < binding->interfacec; inf++) { - fprintf(binding->outfile, - "if (strcmp(interface_name, JSClass_%s.name) == 0) {\n", - binding->interfaces[inf].name); - - fprintf(binding->outfile, - "\t\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n", - binding->interface); - - - fprintf(binding->outfile, - "\tif (newobject == NULL) {\n" - "\t\treturn NULL;\n" - "\t}\n"); - - /* root object to stop it being garbage collected */ - fprintf(binding->outfile, - "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - /* attach operations and attributes (functions and properties) */ - fprintf(binding->outfile, - "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - fprintf(binding->outfile, - "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - /* unroot object */ - fprintf(binding->outfile, - "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n"); - - } - fprintf(binding->outfile, - "{\n" - "\t\tfree(private);\n" - "\t\treturn NULL;\n" - "\t}\n"); - - - return 0; -} - -static int -output_class_woprivate(struct binding *binding, struct genbind_node *api_node) -{ - - if (api_node != NULL) { - output_code_block(binding, genbind_node_getnode(api_node)); - } else { - fprintf(binding->outfile, - "\n" - "\tnewobject = JS_NewObject(cx, &JSClass_%s, prototype, parent);\n", - binding->interface); - - } - - fprintf(binding->outfile, - "\tif (newobject == NULL) {\n" - "\t\treturn NULL;\n" - "\t}\n"); - - /* root object to stop it being garbage collected */ - fprintf(binding->outfile, - "\tif (JSAPI_ADD_OBJECT_ROOT(cx, &newobject) != JS_TRUE) {\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - /* attach operations and attributes (functions and properties) */ - fprintf(binding->outfile, - "\tif (JS_DefineFunctions(cx, newobject, jsclass_functions) != JS_TRUE) {\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - fprintf(binding->outfile, - "\tif (JS_DefineProperties(cx, newobject, jsclass_properties) != JS_TRUE) {\n" - "\t\treturn NULL;\n" - "\t}\n\n"); - - /* unroot object */ - fprintf(binding->outfile, - "\tJSAPI_REMOVE_OBJECT_ROOT(cx, &newobject);\n\n"); - - return 0; -} - -int -output_class_new(struct binding *binding) -{ - int res = 0; - struct genbind_node *api_node; - - /* constructor declaration */ - if (binding->hdrfile) { - binding->outfile = binding->hdrfile; - - output_binding_constructor(binding); - - fprintf(binding->outfile, ";\n"); - - binding->outfile = binding->srcfile; - } - - /* constructor definition */ - output_binding_constructor(binding); - - fprintf(binding->outfile, - "\n{\n" - "\tJSObject *newobject;\n"); - - api_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_API, - "new"); - - /* generate correct constructor body */ - if (binding->has_private) { - if ((binding->interfacec == 1) || (api_node != NULL)) { - res = output_class_wprivate(binding, api_node); - } else { - res = output_class_wprivate_multi(binding); - } - } else { - if ((binding->interfacec == 1) || (api_node != NULL)) { - res = output_class_woprivate(binding, api_node); - } else { - res = output_class_woprivate_multi(binding); - } - } - - /* return newly created object */ - fprintf(binding->outfile, - "\treturn newobject;\n" - "}\n"); - - return res; -} diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c deleted file mode 100644 index 1a6cc33..0000000 --- a/src/jsapi-libdom-property.c +++ /dev/null @@ -1,1156 +0,0 @@ -/* property generation - * - * This file is part of nsgenbind. - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> - */ - -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> - -#include "options.h" -#include "nsgenbind-ast.h" -#include "webidl-ast.h" -#include "jsapi-libdom.h" - -static int generate_property_tinyid(struct binding *binding, const char *interface); -static int generate_property_spec(struct binding *binding, const char *interface); - - -/* generate context data fetcher if the binding has private data */ -static inline int -output_private_get(struct binding *binding, - struct binding_interface *inf, - const char *argname) -{ - int ret = 0; - - if (binding->has_private) { - - ret = fprintf(binding->outfile, - "\tstruct jsclass_private *%s;\n\n", argname); - - if (inf->refcount == 0) { - /* leaf class so use safer getinstance private */ - ret += fprintf(binding->outfile, - "\t%s = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - argname, - inf->name); - } else { - ret += fprintf(binding->outfile, - "\t%s = JS_GetPrivate(obj);\n", - argname); - } - - ret += fprintf(binding->outfile, - "\tif (%s == NULL) {\n" - "\t\treturn JS_FALSE;\n" - "\t}\n\n", - argname); - - if (options->dbglog) { - ret += fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, %s);\n", argname); - } - } else { - if (options->dbglog) { - ret += fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - return ret; -} - -/* generate vars for property name getter */ -static inline int -output_property_name_get_vars(struct binding *binding, const char *argname) -{ - /* get property name */ - return fprintf(binding->outfile, - "\tjsval %s_jsval;\n" - "\tJSString *%s_jsstr = NULL;\n" - "\tint %s_len = 0;\n" - "\tchar *%s = NULL;\n", - argname, argname, argname, argname); -} - -/* generate vars for property tinyid getter */ -static inline int -output_property_tinyid_get_vars(struct binding *binding, const char *argname) -{ - /* get property name */ - return fprintf(binding->outfile, - "\tjsval %s_jsval;\n" - "\tint8_t %s = JSAPI_PROP_TINYID_END;\n", - argname, argname); -} - -/* generate property name getter */ -static inline int -output_property_name_get(struct binding *binding, const char *argname) -{ - /* get property name */ - return fprintf(binding->outfile, - "\t /* obtain property name */\n" - "\tJSAPI_PROP_IDVAL(cx, &%s_jsval);\n" - "\t%s_jsstr = JS_ValueToString(cx, %s_jsval);\n" - "\tif (%s_jsstr != NULL) {\n" - "\t\tJSString_to_char(%s_jsstr, %s, %s_len);\n" - "\t}\n\n", - argname,argname,argname,argname,argname,argname,argname); -} - -/* generate property name getter */ -static inline int -output_property_tinyid_get(struct binding *binding, const char *argname) -{ - /* get property name */ - return fprintf(binding->outfile, - "\t /* obtain property tinyid */\n" - "\tJSAPI_PROP_IDVAL(cx, &%s_jsval);\n" - "\t%s = JSVAL_TO_INT(%s_jsval);\n\n", - argname, argname, argname); -} - - -/******************************** tinyid ********************************/ - -static int -webidl_property_tinyid_cb(struct webidl_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct webidl_node *ident_node; - const char *ident; - - ident_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - ident = webidl_node_gettext(ident_node); - if (ident == NULL) { - /* properties must have an operator - * http://www.w3.org/TR/WebIDL/#idl-attributes - */ - return -1; - } - - fprintf(binding->outfile, "\tJSAPI_PROP_TINYID_%s,\n", ident); - - return 0; -} - - -static int -generate_property_tinyid(struct binding *binding, const char *interface) -{ - struct webidl_node *interface_node; - struct webidl_node *members_node; - struct webidl_node *inherit_node; - int res = 0; - - /* 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; - } - - /* generate property entries for each list (partial interfaces) */ - members_node = webidl_node_find_type(webidl_node_getnode(interface_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (members_node != NULL) { - - fprintf(binding->outfile,"\t/**** %s ****/\n", interface); - - /* for each property emit a JSAPI_PS() */ - webidl_node_for_each_type(webidl_node_getnode(members_node), - WEBIDL_NODE_TYPE_ATTRIBUTE, - webidl_property_tinyid_cb, - binding); - - members_node = webidl_node_find_type(webidl_node_getnode(interface_node), - members_node, - WEBIDL_NODE_TYPE_LIST); - } - - /* check for inherited nodes and insert them too */ - inherit_node = webidl_node_find(webidl_node_getnode(interface_node), - NULL, - webidl_cmp_node_type, - (void *)WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE); - - if (inherit_node != NULL) { - res = generate_property_tinyid(binding, webidl_node_gettext(inherit_node)); - } - - return res; -} - -/* exported interface documented in jsapi-libdom.h */ -int -output_property_tinyid(struct binding *binding) -{ - int res; - - fprintf(binding->outfile, - "enum property_tinyid {\n"); - - res = generate_property_tinyid(binding, binding->interface); - - fprintf(binding->outfile, - "\tJSAPI_PROP_TINYID_END,\n" - "};\n\n"); - - return res; -} - - - -/******************************** specifier ********************************/ - - -/* search binding for property sharing modifier */ -static enum genbind_type_modifier -get_binding_shared_modifier(struct binding *binding, const char *type, const char *ident) -{ - struct genbind_node *shared_node; - struct genbind_node *shared_mod_node; - enum genbind_type_modifier *shared_modifier; - - /* look for node matching the ident first */ - shared_node = genbind_node_find_type_ident(binding->binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_PROPERTY, - ident); - - /* look for a node matching the type */ - if (shared_node == NULL) { - shared_node = genbind_node_find_type_ident(binding->binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_PROPERTY, - type); - - } - - - if (shared_node != NULL) { - /* no explicit shared status */ - shared_mod_node = genbind_node_find_type(genbind_node_getnode(shared_node), - NULL, - GENBIND_NODE_TYPE_MODIFIER); - shared_modifier = (enum genbind_type_modifier *)genbind_node_getint(shared_mod_node); - if (shared_modifier != NULL) { - return *shared_modifier; - } - - } - return GENBIND_TYPE_NONE; -} - -/* obtain the value for a key/value type extended attribute */ -static char * -get_keyval_extended_attribute(struct webidl_node *node, const char *attribute) -{ - struct webidl_node *ext_node; - struct webidl_node *ident_node; - char *value; - - ext_node = webidl_node_find_type_ident(webidl_node_getnode(node), - WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE, - attribute); - - if (ext_node == NULL) { - return NULL; /* no matching extended attribute at all */ - } - - /* should be extended atrribute name node */ - ident_node = webidl_node_find_type(webidl_node_getnode(ext_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - if (ident_node == NULL) { - /* not the attribute name already matched - bail - * somethings broken - */ - return NULL; - } - value = webidl_node_gettext(ident_node); - if (strcmp(attribute, value) != 0) { - /* not the attribute name already matched - bail - * somethings broken - */ - return NULL; - } - - /* should be an = sign for key/value pair */ - ident_node = webidl_node_find_type(webidl_node_getnode(ext_node), - ident_node, - WEBIDL_NODE_TYPE_IDENT); - if (ident_node == NULL) { - /* no additional attribute - not key/value then */ - return NULL; - } - value = webidl_node_gettext(ident_node); - if (strcmp("=", value) != 0) { - /* not a key/value pair then */ - return NULL; - } - - /* value */ - ident_node = webidl_node_find_type(webidl_node_getnode(ext_node), - ident_node, - WEBIDL_NODE_TYPE_IDENT); - if (ident_node == NULL) { - /* no value */ - return NULL; - } - value = webidl_node_gettext(ident_node); - - return value; -} - -static bool property_is_ro(struct webidl_node *node) -{ - struct webidl_node *modifier_node; - modifier_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_MODIFIER); - - if (webidl_node_getint(modifier_node) == WEBIDL_TYPE_READONLY) { - return true; - } - - return false; -} - -static int webidl_property_spec(struct binding *binding, - struct binding_interface *inf, - struct webidl_node *node) -{ - struct webidl_node *type_node; - const char *type = NULL; - struct webidl_node *ident_node; - const char *ident; - bool ro = false; - - ident_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - ident = webidl_node_gettext(ident_node); - if (ident == NULL) { - /* properties must have an operator - * http://www.w3.org/TR/WebIDL/#idl-attributes - */ - return -1; - } - - - /* get type name */ - type_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - ident_node = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - type = webidl_node_gettext(ident_node); - - - /* generate JSAPI_PS macro entry */ - /* if there is a putforwards the property requires a setter */ - if ((property_is_ro(node)) && - (get_keyval_extended_attribute(node, "PutForwards") == NULL)) { - ro = true; - } - - - /* generate property shared status */ - switch (get_binding_shared_modifier(binding, type, ident)) { - - default: - case GENBIND_TYPE_NONE: - /* shared property without type handler - * - * js doesnt provide storage and setter/getter must - * perform all GC management. - */ - fprintf(binding->outfile, - "\tJSAPI_PS_%s(%s, %s, JSPROP_SHARED),\n", - ro?"RO":"RW", - inf->name, - ident); - break; - - case GENBIND_TYPE_TYPE: - /* shared property with a type handler */ - fprintf(binding->outfile, - "\tJSAPI_PS_ID_%s(%s, %s, JSPROP_SHARED, %s),\n", - ro?"RO":"RW", - inf->name, - ident, - type); - break; - - case GENBIND_TYPE_UNSHARED: - /* unshared property without type handler */ - fprintf(binding->outfile, - "\tJSAPI_PS_%s(%s, %s, 0),\n", - ro?"RO":"RW", - inf->name, - ident); - break; - - case GENBIND_TYPE_TYPE_UNSHARED: - /* unshared property with a type handler */ - fprintf(binding->outfile, - "\tJSAPI_PS_ID_%s(%s, %s, 0, %s),\n", - ro?"RO":"RW", - inf->name, - ident, - type); - break; - - } - - return 0; -} - - -/* exported interface documented in jsapi-libdom.h */ -int -output_property_spec(struct binding *binding) -{ - int inf; - int res; - struct webidl_node *list_node; - struct webidl_node *op_node; /* operation on list node */ - - /* for each interface in the map */ - for (inf = 0; inf < binding->interfacec; inf++) { - if (binding->interfaces[inf].own_properties == 0) { - /* if the interface has no properties then - * there is nothing to generate. - */ - continue; - } - - /* generate property specifier */ - fprintf(binding->outfile, - "static JSPropertySpec JSClass_%s_properties[] = {\n", - binding->interfaces[inf].name); - - /* iterate each list within an interface */ - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (list_node != NULL) { - /* iterate through operations in a list */ - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - NULL, - WEBIDL_NODE_TYPE_ATTRIBUTE); - - while (op_node != NULL) { - res = webidl_property_spec( - binding, - &binding->interfaces[inf], - op_node); - if (res != 0) { - return res; - } - - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - op_node, - WEBIDL_NODE_TYPE_ATTRIBUTE); - } - - - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - list_node, - WEBIDL_NODE_TYPE_LIST); - } - - fprintf(binding->outfile, "\tJSAPI_PS_END\n};\n\n"); - - } - return 0; -} - - -/******************************** body ********************************/ - - -static int output_return(struct binding *binding, - const char *ident, - struct webidl_node *node) -{ - struct webidl_node *type_node = NULL; - struct webidl_node *type_base = NULL; - struct webidl_node *type_nullable = NULL; - enum webidl_type webidl_arg_type; - - type_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - type_base = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(type_base); - - type_nullable = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_TYPE_NULLABLE); - - switch (webidl_arg_type) { - case WEBIDL_TYPE_USER: - /* User type are represented with jsobject */ - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n", - ident); - - break; - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(%s));\n", - ident); - - break; - - case WEBIDL_TYPE_BYTE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_BYTE"); - break; - - case WEBIDL_TYPE_OCTET: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_OCTET"); - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_SHORT: - /* int16_t */ - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, INT_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_LONGLONG: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_LONGLONG"); - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, INT_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_STRING: - /* JSString * */ - if (type_nullable == NULL) { - /* entry is not nullable ensure it is set to a string */ - fprintf(binding->outfile, - "\tif (%s == NULL) {\n" - "\t\t%s = JS_NewStringCopyN(cx, NULL, 0);\n" - "\t}\n", - ident, ident); - } - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, JSAPI_STRING_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_SEQUENCE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_SEQUENCE"); - break; - - case WEBIDL_TYPE_OBJECT: - /* JSObject * */ - fprintf(binding->outfile, - "\tJSAPI_PROP_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n", - ident); - break; - - case WEBIDL_TYPE_DATE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_DATE"); - break; - - case WEBIDL_TYPE_VOID: - /* specifically requires no value */ - break; - - default: - break; - } - - return 0; -} - - - -/* generate variable declaration of the correct type with appropriate default */ -static int output_return_declaration(struct binding *binding, - const char *ident, - struct webidl_node *node) -{ - struct webidl_node *type_node = NULL; - struct webidl_node *type_base = NULL; - struct webidl_node *type_name = NULL; - struct webidl_node *type_mod = NULL; - enum webidl_type webidl_arg_type; - - type_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - - type_base = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_TYPE_BASE); - - webidl_arg_type = webidl_node_getint(type_base); - - switch (webidl_arg_type) { - case WEBIDL_TYPE_USER: - /* User type are represented with jsobject */ - type_name = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - fprintf(binding->outfile, - "\tJSObject *%s = NULL; /* %s */\n", - ident, - webidl_node_gettext(type_name)); - - break; - - case WEBIDL_TYPE_BOOL: - /* JSBool */ - fprintf(binding->outfile, "\tJSBool %s = JS_FALSE;\n",ident); - - break; - - case WEBIDL_TYPE_BYTE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_BYTE"); - break; - - case WEBIDL_TYPE_OCTET: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_OCTET"); - break; - - case WEBIDL_TYPE_FLOAT: - case WEBIDL_TYPE_DOUBLE: - /* double */ - fprintf(binding->outfile, "\tdouble %s = 0;\n", ident); - break; - - case WEBIDL_TYPE_SHORT: - /* int16_t */ - type_mod = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && - (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, - "\tuint16_t %s = 0;\n", - ident); - } else { - fprintf(binding->outfile, - "\tint16_t %s = 0;\n", - ident); - } - - break; - - case WEBIDL_TYPE_LONGLONG: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_LONGLONG"); - break; - - case WEBIDL_TYPE_LONG: - /* int32_t */ - type_mod = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_MODIFIER); - if ((type_mod != NULL) && - (webidl_node_getint(type_mod) == WEBIDL_TYPE_MODIFIER_UNSIGNED)) { - fprintf(binding->outfile, - "\tuint32_t %s = 0;\n", - ident); - } else { - fprintf(binding->outfile, - "\tint32_t %s = 0;\n", - ident); - } - - break; - - case WEBIDL_TYPE_STRING: - /* JSString * */ - fprintf(binding->outfile, - "\tJSString *%s = NULL;\n", - ident); - break; - - case WEBIDL_TYPE_SEQUENCE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_SEQUENCE"); - break; - - case WEBIDL_TYPE_OBJECT: - /* JSObject * */ - fprintf(binding->outfile, "\tJSObject *%s = NULL;\n", ident); - break; - - case WEBIDL_TYPE_DATE: - WARN(WARNING_UNIMPLEMENTED, "Unhandled type WEBIDL_TYPE_DATE"); - break; - - case WEBIDL_TYPE_VOID: - /* specifically requires no value */ - break; - - default: - break; - } - return 0; -} - -static int -output_property_placeholder(struct binding *binding, - struct binding_interface *inf, - struct webidl_node* oplist, - const char *ident) -{ - oplist=oplist; - - WARN(WARNING_UNIMPLEMENTED, - "property %s.%s has no implementation\n", - inf->name, - ident); - - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"property %s.%s has no implementation\");\n", - inf->name, - ident); - } - return 0; -} - -static int output_property_getter(struct binding *binding, - struct binding_interface *inf, - struct webidl_node *node, - const char *ident) -{ - struct genbind_node *property_node; - - fprintf(binding->outfile, - "static JSBool JSAPI_PROP_GET(%s, %s, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n", - inf->name, - ident); - - /* return value declaration */ - output_return_declaration(binding, "jsret", node); - - output_private_get(binding, inf, "private"); - - property_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_GETTER, - ident); - - if (property_node != NULL) { - /* binding source block */ - output_code_block(binding, genbind_node_getnode(property_node)); - } else { - /* examine internal variables and see if they are gettable */ - struct genbind_node *binding_node; - struct genbind_node *internal_node = NULL; - - binding_node = genbind_node_find_type(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_BINDING); - - if (binding_node != NULL) { - internal_node = genbind_node_find_type_ident(genbind_node_getnode(binding_node), - NULL, - GENBIND_NODE_TYPE_BINDING_INTERNAL, - ident); - - } - - if (internal_node != NULL) { - /** @todo fetching from internal entries ought to be type sensitive */ - fprintf(binding->outfile, - "\tjsret = private->%s;\n", - ident); - } else { - output_property_placeholder(binding, inf, node, ident); - } - - } - - output_return(binding, "jsret", node); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - - return 0; -} - -static int output_property_setter(struct binding *binding, - struct binding_interface *inf, - struct webidl_node *node, - const char *property_ident) -{ - struct genbind_node *property_node; - char *putforwards; - putforwards = get_keyval_extended_attribute(node, "PutForwards"); - - if (putforwards != NULL) { - /* generate a putforwards setter */ - fprintf(binding->outfile, - "/* PutForwards setter */\n" - "static JSBool JSAPI_PROP_SET(%s, %s, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n", - inf->name, - property_ident); - - fprintf(binding->outfile, - "\tjsval propval;\n" - "\tif (JS_GetProperty(cx, obj, \"%s\", &propval) == JS_TRUE) {\n" - "\t\tJS_SetProperty(cx, JSVAL_TO_OBJECT(propval), \"%s\", vp);\n" - "\t}\n", - property_ident, - putforwards); - - fprintf(binding->outfile, - "\treturn JS_FALSE; /* disallow the asignment */\n" - "}\n\n"); - - return 0; - } - - if (property_is_ro(node)) { - /* readonly so a set function is not required */ - return 0; - } - - property_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_SETTER, - property_ident); - - fprintf(binding->outfile, - "static JSBool JSAPI_PROP_SET(%s, %s, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n", - inf->name, - property_ident); - - output_private_get(binding, inf, "private"); - - if (property_node != NULL) { - /* binding source block */ - output_code_block(binding, genbind_node_getnode(property_node)); - } else { - output_property_placeholder(binding, inf, node, property_ident); - } - - fprintf(binding->outfile, - " return JS_FALSE; /* disallow the asignment by default */\n" - "}\n\n"); - - - return 0; -} - -/** - * generate atribute (property) body. - */ -static int webidl_property_body(struct binding *binding, - struct binding_interface *inf, - struct webidl_node *node) -{ - struct webidl_node *ident_node; - const char *ident; - struct webidl_node *type_node; - const char *type = NULL; - int ret; - enum genbind_type_modifier shared_mod; - - ident_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - ident = webidl_node_gettext(ident_node); - if (ident == NULL) { - /* properties must have an operator - * http://www.w3.org/TR/WebIDL/#idl-attributes - */ - return -1; - } - - /* get type name */ - type_node = webidl_node_find_type(webidl_node_getnode(node), - NULL, - WEBIDL_NODE_TYPE_TYPE); - ident_node = webidl_node_find_type(webidl_node_getnode(type_node), - NULL, - WEBIDL_NODE_TYPE_IDENT); - type = webidl_node_gettext(ident_node); - - /* find shared modifiers */ - shared_mod = get_binding_shared_modifier(binding, type, ident); - - /* only generate individual getters/setters if there is not a - * type handler - */ - if ((shared_mod & GENBIND_TYPE_TYPE) == 0) { - ret = output_property_setter(binding, inf, node, ident); - if (ret == 0) { - /* property getter */ - ret = output_property_getter(binding, inf, node, ident); - } - } - return ret; - -} - - - -/* setter for type handler */ -static int -output_property_type_setter(struct binding *binding, - struct binding_interface *inf, - struct genbind_node *node, - const char *type) -{ - struct genbind_node *property_node; - node = node;/* currently unused */ - - fprintf(binding->outfile, - "static JSBool\n" - "JSAPI_STRICTPROP(%s_set, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n", - type); - - /* property name vars */ - output_property_tinyid_get_vars(binding, "tinyid"); - /* context data */ - output_private_get(binding, inf, "private"); - /* property name */ - output_property_tinyid_get(binding, "tinyid"); - - /* output binding code block */ - property_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_SETTER, - type); - - if (property_node != NULL) { - /* binding source block */ - output_code_block(binding, genbind_node_getnode(property_node)); - } - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - return 0; - -} - - -/* getter for type handlers */ -static int output_property_type_getter(struct binding *binding, - struct binding_interface *inf, - struct genbind_node *node, - const char *type) -{ - struct genbind_node *property_node; - node = node;/* currently unused */ - - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(%s_get, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n", - type); - - /* property tinyid vars */ - output_property_tinyid_get_vars(binding, "tinyid"); - /* context data */ - output_private_get(binding, inf, "private"); - /* property tinyid */ - output_property_tinyid_get(binding, "tinyid"); - - /* output binding code block */ - property_node = genbind_node_find_type_ident(binding->gb_ast, - NULL, - GENBIND_NODE_TYPE_GETTER, - type); - - if (property_node != NULL) { - /* binding source block */ - output_code_block(binding, genbind_node_getnode(property_node)); - } - - fprintf(binding->outfile, - " return JS_TRUE;\n" - "}\n\n"); - return 0; - -} - -/* callback to emit property handlers for whole types */ -static int typehandler_property_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct genbind_node *ident_node; - const char *type; - struct genbind_node *mod_node; - enum genbind_type_modifier *share_mod; - int ret = 0; - struct binding_interface *inf; - - mod_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_MODIFIER); - share_mod = (enum genbind_type_modifier *)genbind_node_getint(mod_node); - - if ((share_mod != NULL) && - ((*share_mod & GENBIND_TYPE_TYPE) == GENBIND_TYPE_TYPE)) { - /* type handler */ - - ident_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_IDENT); - type = genbind_node_gettext(ident_node); - if (type != NULL) { - ret = output_property_type_setter(binding, - inf, - node, - type); - if (ret == 0) { - /* property getter */ - ret = output_property_type_getter(binding, - inf, - node, - type); - } - } - } - return ret; -} - - -/** - * generate atribute (property) type body. - * - * Output property handler for an entire type of property - */ -static int webidl_attribute_typehandler_body(struct binding *binding, - struct binding_interface *inf) -{ - int res; - - /* check if the interface has any properties with type handlers */ - if (!inf->has_type_properties) { - return 0; - } - - res = genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_PROPERTY, - typehandler_property_cb, - binding); - - - return res; - -} - -/* exported interface documented in jsapi-libdom.h */ -int -output_property_body(struct binding *binding) -{ - int inf; - int res; - struct webidl_node *list_node; - struct webidl_node *op_node; /* operation on list node */ - - /* for each interface in the map */ - for (inf = 0; inf < binding->interfacec; inf++) { - if (binding->interfaces[inf].own_properties == 0) { - /* if the interface has no properties then - * there is nothing to generate. - */ - continue; - } - - /* generate property bodies */ - - /* iterate each list within an interface */ - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - NULL, - WEBIDL_NODE_TYPE_LIST); - - while (list_node != NULL) { - /* iterate through operations in a list */ - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - NULL, - WEBIDL_NODE_TYPE_ATTRIBUTE); - - while (op_node != NULL) { - res = webidl_property_body( - binding, - &binding->interfaces[inf], - op_node); - if (res != 0) { - return res; - } - - op_node = webidl_node_find_type( - webidl_node_getnode(list_node), - op_node, - WEBIDL_NODE_TYPE_ATTRIBUTE); - } - - - list_node = webidl_node_find_type( - webidl_node_getnode(binding->interfaces[inf].widl_node), - list_node, - WEBIDL_NODE_TYPE_LIST); - } - - /* generate type handler bodies */ - res = webidl_attribute_typehandler_body(binding, - &binding->interfaces[inf]); - - if (res != 0) { - return res; - } - - } - return 0; -} diff --git a/src/jsapi-libdom.c b/src/jsapi-libdom.c deleted file mode 100644 index 5e994b9..0000000 --- a/src/jsapi-libdom.c +++ /dev/null @@ -1,904 +0,0 @@ -/* binding output generator for jsapi(spidermonkey) to libdom - * - * This file is part of nsgenbind. - * Published under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> - */ - -#include <stdbool.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <ctype.h> - -#include "options.h" -#include "nsgenbind-ast.h" -#include "webidl-ast.h" -#include "jsapi-libdom.h" - -#define HDR_COMMENT_SEP "\n * \n * " -#define HDR_COMMENT_PREAMBLE "/* Generated by nsgenbind from %s\n" \ - " *\n" \ - " * nsgenbind is published under the MIT Licence.\n" \ - " * nsgenbind is similar to a compiler is a purely transformative tool which\n" \ - " * explicitly makes no copyright claim on this generated output" - - - -static int webidl_file_cb(struct genbind_node *node, void *ctx) -{ - struct webidl_node **webidl_ast = ctx; - char *filename; - - filename = genbind_node_gettext(node); - - return webidl_parsefile(filename, webidl_ast); -} - -static int -read_webidl(struct genbind_node *genbind_ast, struct webidl_node **webidl_ast) -{ - int res; - - res = genbind_node_foreach_type(genbind_ast, - GENBIND_NODE_TYPE_WEBIDLFILE, - webidl_file_cb, - webidl_ast); - - if (res == 0) { - res = webidl_intercalate_implements(*webidl_ast); - } - - /* debug dump of web idl AST */ - if (options->verbose) { - webidl_ast_dump(*webidl_ast, 0); - } - return res; -} - - -static int webidl_preamble_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - - fprintf(binding->outfile, "%s", genbind_node_gettext(node)); - - return 0; -} - -static int webidl_prologue_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - - fprintf(binding->outfile, "%s", genbind_node_gettext(node)); - - return 0; -} - -static int webidl_epilogue_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - - fprintf(binding->outfile, "%s", genbind_node_gettext(node)); - - return 0; -} - - -static int webidl_hdrcomments_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - - fprintf(binding->outfile, - HDR_COMMENT_SEP"%s", - genbind_node_gettext(node)); - - return 0; -} - -static int webidl_hdrcomment_cb(struct genbind_node *node, void *ctx) -{ - genbind_node_foreach_type(genbind_node_getnode(node), - GENBIND_NODE_TYPE_STRING, - webidl_hdrcomments_cb, - ctx); - return 0; -} - -static int webidl_private_cb(struct genbind_node *node, void *ctx) -{ - struct binding *binding = ctx; - struct genbind_node *ident_node; - struct genbind_node *type_node; - - - ident_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_IDENT); - if (ident_node == NULL) - return -1; /* bad AST */ - - type_node = genbind_node_find_type(genbind_node_getnode(node), - NULL, - GENBIND_NODE_TYPE_STRING); - if (type_node == NULL) - return -1; /* bad AST */ - - fprintf(binding->outfile, - " %s%s;\n", - genbind_node_gettext(type_node), - genbind_node_gettext(ident_node)); - - return 0; -} - - - -/* section output generators */ - -/** Output the epilogue right at the end of the generated program */ -static int -output_epilogue(struct binding *binding) -{ - genbind_node_foreach_type(binding->gb_ast, - GENBIND_NODE_TYPE_EPILOGUE, - webidl_epilogue_cb, - binding); - - fprintf(binding->outfile,"\n\n"); - - if (binding->hdrfile) { - binding->outfile = binding->hdrfile; - - fprintf(binding->outfile, - "\n\n#endif /* _%s_ */\n", - binding->hdrguard); - - binding->outfile = binding->srcfile; - } - - return 0; -} - -/** Output the prologue right before the generated function bodies */ -static int -output_prologue(struct binding *binding) -{ - /* forward declare property list */ - fprintf(binding->outfile, - "static JSPropertySpec jsclass_properties[];\n\n"); - - genbind_node_foreach_type(binding->gb_ast, - GENBIND_NODE_TYPE_PROLOGUE, - webidl_prologue_cb, - binding); - - fprintf(binding->outfile,"\n\n"); - - return 0; -} - - -static int -output_api_operations(struct binding *binding) -{ - int res = 0; - - /* finalise */ - if (binding->has_private) { - /* finalizer with private to free */ - fprintf(binding->outfile, - "static void jsclass_finalize(JSContext *cx, JSObject *obj)\n" - "{\n" - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - - if (binding->finalise != NULL) { - output_code_block(binding, - genbind_node_getnode(binding->finalise)); - } - - fprintf(binding->outfile, - "\tif (private != NULL) {\n" - "\t\tfree(private);\n" - "\t}\n" - "}\n\n"); - } else if (binding->finalise != NULL) { - /* finaliser without private data */ - fprintf(binding->outfile, - "static void jsclass_finalize(JSContext *cx, JSObject *obj)\n" - "{\n"); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - output_code_block(binding, - genbind_node_getnode(binding->finalise)); - - fprintf(binding->outfile, - "}\n\n"); - - } - - /* generate class default property add implementation */ - if (binding->addproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(add, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n"); - - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - - output_code_block(binding, - genbind_node_getnode(binding->addproperty)); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - } - - /* generate class default property delete implementation */ - if (binding->delproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(del, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n"); - - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - - output_code_block(binding, - genbind_node_getnode(binding->delproperty)); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - } - - /* generate class default property get implementation */ - if (binding->getproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(get, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n"); - - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - - output_code_block(binding, - genbind_node_getnode(binding->getproperty)); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - } - - /* generate class default property set implementation */ - if (binding->setproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_STRICTPROP(set, JSContext *cx, JSObject *obj, jsval *vp)\n" - "{\n"); - - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - - output_code_block(binding, - genbind_node_getnode(binding->setproperty)); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - } - - /* generate class enumerate implementation */ - if (binding->enumerate != NULL) { - fprintf(binding->outfile, - "static JSBool jsclass_enumerate(JSContext *cx, JSObject *obj)\n" - "{\n"); - - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - output_code_block(binding, genbind_node_getnode(binding->enumerate)); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - } - - /* generate class resolver implementation */ - if (binding->resolve != NULL) { - fprintf(binding->outfile, - "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp)\n" - "{\n"); - - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n", - binding->interface); - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", cx, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", cx, obj);\n"); - } - - } - - - output_code_block(binding, genbind_node_getnode(binding->resolve)); - - fprintf(binding->outfile, - "\treturn JS_TRUE;\n" - "}\n\n"); - } - - /* generate trace/mark entry */ - if (binding->mark != NULL) { - fprintf(binding->outfile, - "static JSAPI_MARKOP(jsclass_mark)\n" - "{\n"); - if (binding->has_private) { - - fprintf(binding->outfile, - "\tstruct jsclass_private *private;\n" - "\n" - "\tprivate = JS_GetInstancePrivate(JSAPI_MARKCX, obj, &JSClass_%s, NULL);\n", - binding->interface); - - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p private:%%p\", JSAPI_MARKCX, obj, private);\n"); - } - } else { - if (options->dbglog) { - fprintf(binding->outfile, - "\tJSLOG(\"jscontext:%%p jsobject:%%p\", JSAPI_MARKCX, obj);\n"); - } - - } - - output_code_block(binding, genbind_node_getnode(binding->mark)); - - fprintf(binding->outfile, - "\tJSAPI_MARKOP_RETURN(JS_TRUE);\n" - "}\n\n"); - } - return res; -} - -void -output_code_block(struct binding *binding, struct genbind_node *codelist) -{ - struct genbind_node *code_node; - - code_node = genbind_node_find_type(codelist, - NULL, - GENBIND_NODE_TYPE_CBLOCK); - if (code_node != NULL) { - fprintf(binding->outfile, - "%s\n", - genbind_node_gettext(code_node)); - } -} - - - -static int -output_forward_declarations(struct binding *binding) -{ - /* forward declare add property */ - if (binding->addproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(add, JSContext *cx, JSObject *obj, jsval *vp);\n\n"); - } - - /* forward declare del property */ - if (binding->delproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(del, JSContext *cx, JSObject *obj, jsval *vp);\n\n"); - } - - /* forward declare get property */ - if (binding->getproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_PROP(get, JSContext *cx, JSObject *obj, jsval *vp);\n\n"); - } - - /* forward declare set property */ - if (binding->setproperty != NULL) { - fprintf(binding->outfile, - "static JSBool JSAPI_STRICTPROP(set, JSContext *cx, JSObject *obj, jsval *vp);\n\n"); - } - - /* forward declare the enumerate */ - if (binding->enumerate != NULL) { - fprintf(binding->outfile, - "static JSBool jsclass_enumerate(JSContext *cx, JSObject *obj);\n\n"); - } - - /* forward declare the resolver */ - if (binding->resolve != NULL) { - fprintf(binding->outfile, - "static JSBool jsclass_resolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, JSObject **objp);\n\n"); - } - - /* forward declare the GC mark operation */ - if (binding->mark != NULL) { - fprintf(binding->outfile, - "static JSAPI_MARKOP(jsclass_mark);\n\n"); - } - - /* forward declare the finalizer */ - if (binding->has_private || (binding->finalise != NULL)) { - fprintf(binding->outfile, - "static void jsclass_finalize(JSContext *cx, JSObject *obj);\n\n"); - } - - return 0; -} - - - -/** generate structure definition for internal class data - * - * Every javascript object instance has an internal context to keep - * track of its state in object terms this would be considered the - * "this" pointer giving access to the classes members. - * - * Member access can be considered protected as all interfaces - * (classes) and subclasses generated within this binding have access - * to members. - * - * @param binding the binding to generate the structure for. - * @return 0 on success with output written and -1 on error. - */ -static int -output_private_declaration(struct binding *binding) -{ - - if (!binding->has_private) { - return 0; - } - - fprintf(binding->outfile, "struct jsclass_private {\n"); - - genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_PRIVATE, - webidl_private_cb, - binding); - - genbind_node_foreach_type(binding->binding_list, - GENBIND_NODE_TYPE_BINDING_INTERNAL, - webidl_private_cb, - binding); - - fprintf(binding->outfile, "};\n\n"); - - - return 0; -} - -static int -output_preamble(struct binding *binding) -{ - genbind_node_foreach_type(binding->gb_ast, - GENBIND_NODE_TYPE_PREAMBLE, - webidl_preamble_cb, - binding); - - fprintf(binding->outfile,"\n\n"); - - if (binding->hdrfile) { - binding->outfile = binding->hdrfile; - - fprintf(binding->outfile, - "#ifndef _%s_\n" - "#define _%s_\n\n", - binding->hdrguard, - binding->hdrguard); - - binding->outfile = binding->srcfile; - } - - - return 0; -} - - -static int -output_header_comments(struct binding *binding) -{ - const char *preamble = HDR_COMMENT_PREAMBLE; - fprintf(binding->outfile, preamble, options->infilename); - - genbind_node_foreach_type(binding->gb_ast, - GENBIND_NODE_TYPE_HDRCOMMENT, - webidl_hdrcomment_cb, - binding); - - fprintf(binding->outfile,"\n */\n\n"); - - if (binding->hdrfile != NULL) { - binding->outfile = binding->hdrfile; - - fprintf(binding->outfile, preamble, options->infilename); - - genbind_node_foreach_type(binding->gb_ast, - GENBIND_NODE_TYPE_HDRCOMMENT, - webidl_hdrcomment_cb, - binding); - - fprintf(binding->outfile,"\n */\n\n"); - - binding->outfile = binding->srcfile; - } - return 0; -} - -static bool -binding_has_private(struct genbind_node *binding_list) -{ - struct genbind_node *node; - - node = genbind_node_find_type(binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_PRIVATE); - - if (node != NULL) { - return true; - } - - node = genbind_node_find_type(binding_list, - NULL, - GENBIND_NODE_TYPE_BINDING_INTERNAL); - if (node != NULL) { - return true; - } - return false; -} - - - -/** 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, - struct genbind_node *binding_node) -{ - struct binding *nb; - - int interfacec; /* numer of interfaces in the interface map */ - struct binding_interface *interfaces; /* binding interface map */ - - struct genbind_node *binding_list; - char *hdrguard = NULL; - struct webidl_node *webidl_ast = NULL; - int res; - - /* walk AST and load any web IDL files required */ - res = read_webidl(genbind_ast, &webidl_ast); - if (res != 0) { - fprintf(stderr, "Error: failed reading Web IDL\n"); - return NULL; - } - - /* build the bindings interface (class) name map */ - 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; - } - - /* header guard */ - if (options->hdrfilename != NULL) { - int guardlen; - int pos; - - guardlen = strlen(options->hdrfilename); - hdrguard = calloc(1, guardlen + 1); - for (pos = 0; pos < guardlen; pos++) { - if (isalpha(options->hdrfilename[pos])) { - hdrguard[pos] = toupper(options->hdrfilename[pos]); - } else { - hdrguard[pos] = '_'; - } - } - } - - binding_list = genbind_node_getnode(binding_node); - if (binding_list == NULL) { - return NULL; - } - - nb = calloc(1, sizeof(struct binding)); - - nb->gb_ast = genbind_ast; - nb->wi_ast = webidl_ast; - - /* keep the binding list node */ - nb->binding_list = binding_list; - - /* store the interface mapping */ - nb->interfaces = interfaces; - nb->interfacec = interfacec; - - /* @todo get rid of the interface element out of the binding - * struct and use the interface map instead. - */ - nb->name = nb->interface = get_binding_name(binding_node); - nb->outfile = options->outfilehandle; - nb->srcfile = options->outfilehandle; - nb->hdrfile = options->hdrfilehandle; - nb->hdrguard = hdrguard; - nb->has_private = binding_has_private(binding_list); - - /* class API */ - nb->addproperty = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "addproperty"); - - nb->delproperty = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "delproperty"); - - nb->getproperty = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "getproperty"); - - nb->setproperty = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "setproperty"); - - nb->enumerate = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "enumerate"); - - nb->resolve = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "resolve"); - - nb->finalise = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "finalise"); - - nb->mark = genbind_node_find_type_ident(genbind_ast, - NULL, - GENBIND_NODE_TYPE_API, - "mark"); - return nb; -} - - -int -jsapi_libdom_output(struct options *options, - struct genbind_node *genbind_ast, - struct genbind_node *binding_node) -{ - int res; - struct binding *binding; - - /* get general binding information used in output */ - binding = binding_new(options, genbind_ast, binding_node); - if (binding == NULL) { - return 40; - } - - /* start with comment block */ - res = output_header_comments(binding); - if (res) { - return 50; - } - - res = output_preamble(binding); - if (res) { - return 60; - } - - res = output_private_declaration(binding); - if (res) { - return 70; - } - - res = output_forward_declarations(binding); - if (res) { - return 75; - } - - res = output_jsclasses(binding); - if (res) { - return 80; - } - - res = output_property_tinyid(binding); - if (res) { - return 85; - } - - /* user code output just before interface code bodies emitted */ - res = output_prologue(binding); - if (res) { - return 89; - } - - /* method (function) and property body generation */ - - res = output_function_bodies(binding); - if (res) { - return 90; - } - - res = output_property_body(binding); - if (res) { - return 100; - } - - /* method (function) and property specifier generation */ - - res = output_function_spec(binding); - if (res) { - return 110; - } - - res = output_property_spec(binding); - if (res) { - return 120; - } - - /* binding specific operations (destructors etc.) */ - - res = output_api_operations(binding); - if (res) { - return 130; - } - - res = output_class_init(binding); - if (res) { - return 140; - } - - res = output_class_new(binding); - if (res) { - return 150; - } - - res = output_epilogue(binding); - if (res) { - return 160; - } - - fclose(binding->outfile); - - return 0; -} |