diff options
Diffstat (limited to 'src/jsapi-libdom-property.c')
-rw-r--r-- | src/jsapi-libdom-property.c | 1156 |
1 files changed, 0 insertions, 1156 deletions
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; -} |