summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2014-05-16 14:38:10 +0100
committerVincent Sanders <vince@kyllikki.org>2014-05-16 14:38:57 +0100
commit94137186a3e2270e9b96f243a82a77a590c17f01 (patch)
tree472bf61c08196f483a3700a8d845c9cd44cdc96c
parent4a75f7ee606deeffd9a89d82983bf6e9edb8f27b (diff)
downloadnsgenbind-94137186a3e2270e9b96f243a82a77a590c17f01.tar.gz
nsgenbind-94137186a3e2270e9b96f243a82a77a590c17f01.tar.bz2
make property generation use map
-rw-r--r--src/jsapi-libdom-function.c5
-rw-r--r--src/jsapi-libdom-property.c412
-rw-r--r--src/jsapi-libdom.h4
-rw-r--r--test/data/bindings/htmlelement.bnd4
4 files changed, 238 insertions, 187 deletions
diff --git a/src/jsapi-libdom-function.c b/src/jsapi-libdom-function.c
index af9c215..4f62bcd 100644
--- a/src/jsapi-libdom-function.c
+++ b/src/jsapi-libdom-function.c
@@ -720,6 +720,11 @@ output_private_get(struct binding *binding, const char *argname)
return ret;
}
+/**
+ * Generate operator (function) body
+ *
+ *
+ */
static int webidl_operator_body(struct binding *binding,
struct binding_interface *inf,
struct webidl_node *node)
diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c
index 93ffcc5..1a6cc33 100644
--- a/src/jsapi-libdom-property.c
+++ b/src/jsapi-libdom-property.c
@@ -19,25 +19,38 @@
static int generate_property_tinyid(struct binding *binding, const char *interface);
static int generate_property_spec(struct binding *binding, const char *interface);
-static int generate_property_body(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, const char *argname)
+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"
- "\t%s = JS_GetInstancePrivate(cx, obj, &JSClass_%s, NULL);\n"
- "\tif (%s == NULL) {\n"
- "\t\treturn JS_FALSE;\n"
- "\t}\n\n",
- argname, argname, binding->interface, argname);
+ "\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,
@@ -321,14 +334,15 @@ static bool property_is_ro(struct webidl_node *node)
return false;
}
-static int webidl_property_spec_cb(struct webidl_node *node, void *ctx)
+static int webidl_property_spec(struct binding *binding,
+ struct binding_interface *inf,
+ struct webidl_node *node)
{
- struct binding *binding = ctx;
-
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,
@@ -356,11 +370,10 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx)
/* if there is a putforwards the property requires a setter */
if ((property_is_ro(node)) &&
(get_keyval_extended_attribute(node, "PutForwards") == NULL)) {
- fprintf(binding->outfile, "\tJSAPI_PS_RO(\"%s\",\n", ident);
- } else {
- fprintf(binding->outfile, "\tJSAPI_PS(\"%s\",\n", ident);
+ ro = true;
}
+
/* generate property shared status */
switch (get_binding_shared_modifier(binding, type, ident)) {
@@ -371,120 +384,110 @@ static int webidl_property_spec_cb(struct webidl_node *node, void *ctx)
* js doesnt provide storage and setter/getter must
* perform all GC management.
*/
- fprintf(binding->outfile,
- "\t\t%s,\n"
- "\t\tJSAPI_PROP_TINYID_%s,\n"
- "\t\tJSPROP_SHARED | ",
- ident,
+ 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,
- "\t\t%s,\n"
- "\t\tJSAPI_PROP_TINYID_%s,\n"
- "\t\tJSPROP_SHARED | ",
- type,
- ident);
+ 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,
- "\t\t%s,\n"
- "\t\tJSAPI_PROP_TINYID_%s,\n"
- "\t\t",
- ident, ident);
+ 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,
- "\t\t%s,\n"
- "\t\tJSAPI_PROP_TINYID_%s,\n"
- "\t\t",
- type, ident);
+ fprintf(binding->outfile,
+ "\tJSAPI_PS_ID_%s(%s, %s, 0, %s),\n",
+ ro?"RO":"RW",
+ inf->name,
+ ident,
+ type);
break;
}
- fprintf(binding->outfile, "JSPROP_ENUMERATE),\n");
return 0;
}
-
-static int
-generate_property_spec(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_spec_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_spec(binding,
- webidl_node_gettext(inherit_node));
- }
-
- return res;
-}
-
-
-
/* 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;
+ }
- fprintf(binding->outfile,
- "static JSPropertySpec jsclass_properties[] = {\n");
+ /* generate property specifier */
+ fprintf(binding->outfile,
+ "static JSPropertySpec JSClass_%s_properties[] = {\n",
+ binding->interfaces[inf].name);
- res = generate_property_spec(binding, binding->interface);
+ /* 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);
- fprintf(binding->outfile, "\tJSAPI_PS_END\n};\n\n");
+ 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);
+ }
- return res;
+
+ 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;
}
@@ -734,6 +737,7 @@ static int output_return_declaration(struct binding *binding,
static int
output_property_placeholder(struct binding *binding,
+ struct binding_interface *inf,
struct webidl_node* oplist,
const char *ident)
{
@@ -741,34 +745,36 @@ output_property_placeholder(struct binding *binding,
WARN(WARNING_UNIMPLEMENTED,
"property %s.%s has no implementation\n",
- binding->interface,
+ inf->name,
ident);
if (options->dbglog) {
fprintf(binding->outfile,
"\tJSLOG(\"property %s.%s has no implementation\");\n",
- binding->interface,
+ 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(%s_get, JSContext *cx, JSObject *obj, jsval *vp)\n"
+ "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, "private");
+ output_private_get(binding, inf, "private");
property_node = genbind_node_find_type_ident(binding->gb_ast,
NULL,
@@ -801,7 +807,7 @@ static int output_property_getter(struct binding *binding,
"\tjsret = private->%s;\n",
ident);
} else {
- output_property_placeholder(binding, node, ident);
+ output_property_placeholder(binding, inf, node, ident);
}
}
@@ -816,8 +822,9 @@ static int output_property_getter(struct binding *binding,
}
static int output_property_setter(struct binding *binding,
+ struct binding_interface *inf,
struct webidl_node *node,
- const char *ident)
+ const char *property_ident)
{
struct genbind_node *property_node;
char *putforwards;
@@ -827,22 +834,23 @@ static int output_property_setter(struct binding *binding,
/* generate a putforwards setter */
fprintf(binding->outfile,
"/* PutForwards setter */\n"
- "static JSBool JSAPI_STRICTPROP(%s_set, JSContext *cx, JSObject *obj, jsval *vp)\n"
+ "static JSBool JSAPI_PROP_SET(%s, %s, JSContext *cx, JSObject *obj, jsval *vp)\n"
"{\n",
- ident);
+ 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",
- ident, putforwards);
+ property_ident,
+ putforwards);
fprintf(binding->outfile,
"\treturn JS_FALSE; /* disallow the asignment */\n"
"}\n\n");
-
return 0;
}
@@ -854,20 +862,21 @@ static int output_property_setter(struct binding *binding,
property_node = genbind_node_find_type_ident(binding->gb_ast,
NULL,
GENBIND_NODE_TYPE_SETTER,
- ident);
+ property_ident);
fprintf(binding->outfile,
- "static JSBool JSAPI_STRICTPROP(%s_set, JSContext *cx, JSObject *obj, jsval *vp)\n"
+ "static JSBool JSAPI_PROP_SET(%s, %s, JSContext *cx, JSObject *obj, jsval *vp)\n"
"{\n",
- ident);
+ inf->name,
+ property_ident);
- output_private_get(binding, "private");
+ 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, node, ident);
+ output_property_placeholder(binding, inf, node, property_ident);
}
fprintf(binding->outfile,
@@ -878,9 +887,13 @@ static int output_property_setter(struct binding *binding,
return 0;
}
-static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
+/**
+ * generate atribute (property) body.
+ */
+static int webidl_property_body(struct binding *binding,
+ struct binding_interface *inf,
+ struct webidl_node *node)
{
- struct binding *binding = ctx;
struct webidl_node *ident_node;
const char *ident;
struct webidl_node *type_node;
@@ -915,76 +928,22 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
* type handler
*/
if ((shared_mod & GENBIND_TYPE_TYPE) == 0) {
- ret = output_property_setter(binding, node, ident);
+ ret = output_property_setter(binding, inf, node, ident);
if (ret == 0) {
/* property getter */
- ret = output_property_getter(binding, node, ident);
+ ret = output_property_getter(binding, inf, node, ident);
}
}
return ret;
-}
-
-
-static int
-generate_property_body(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 bodies */
- members_node = webidl_node_find_type(
- webidl_node_getnode(interface_node),
- NULL,
- WEBIDL_NODE_TYPE_LIST);
- while (members_node != NULL) {
-
- fprintf(binding->outfile,"/**** %s ****/\n", interface);
-
- /* emit property body */
- webidl_node_for_each_type(webidl_node_getnode(members_node),
- WEBIDL_NODE_TYPE_ATTRIBUTE,
- webidl_property_body_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_type(webidl_node_getnode(interface_node),
- NULL,
- WEBIDL_NODE_TYPE_INTERFACE_INHERITANCE);
-
- if (inherit_node != NULL) {
- res = generate_property_body(binding,
- webidl_node_gettext(inherit_node));
- }
-
- return res;
}
+
/* setter for type handler */
static int
output_property_type_setter(struct binding *binding,
+ struct binding_interface *inf,
struct genbind_node *node,
const char *type)
{
@@ -1000,7 +959,7 @@ output_property_type_setter(struct binding *binding,
/* property name vars */
output_property_tinyid_get_vars(binding, "tinyid");
/* context data */
- output_private_get(binding, "private");
+ output_private_get(binding, inf, "private");
/* property name */
output_property_tinyid_get(binding, "tinyid");
@@ -1024,7 +983,10 @@ output_property_type_setter(struct binding *binding,
/* getter for type handlers */
-static int output_property_type_getter(struct binding *binding, struct genbind_node *node, const char *type)
+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 */
@@ -1037,7 +999,7 @@ static int output_property_type_getter(struct binding *binding, struct genbind_n
/* property tinyid vars */
output_property_tinyid_get_vars(binding, "tinyid");
/* context data */
- output_private_get(binding, "private");
+ output_private_get(binding, inf, "private");
/* property tinyid */
output_property_tinyid_get(binding, "tinyid");
@@ -1068,6 +1030,7 @@ static int typehandler_property_cb(struct genbind_node *node, void *ctx)
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,
@@ -1083,10 +1046,14 @@ static int typehandler_property_cb(struct genbind_node *node, void *ctx)
GENBIND_NODE_TYPE_IDENT);
type = genbind_node_gettext(ident_node);
if (type != NULL) {
- ret = output_property_type_setter(binding, node, type);
+ ret = output_property_type_setter(binding,
+ inf,
+ node,
+ type);
if (ret == 0) {
/* property getter */
ret = output_property_type_getter(binding,
+ inf,
node,
type);
}
@@ -1095,20 +1062,95 @@ static int typehandler_property_cb(struct genbind_node *node, void *ctx)
return ret;
}
-/* exported interface documented in jsapi-libdom.h */
-int
-output_property_body(struct binding *binding)
+
+/**
+ * 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;
- res = generate_property_body(binding, binding->interface);
+ /* check if the interface has any properties with type handlers */
+ if (!inf->has_type_properties) {
+ return 0;
+ }
- if (res == 0) {
- res = genbind_node_foreach_type(binding->binding_list,
+ 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.h b/src/jsapi-libdom.h
index 2925866..e8d57c4 100644
--- a/src/jsapi-libdom.h
+++ b/src/jsapi-libdom.h
@@ -19,6 +19,10 @@ struct binding_interface {
int own_properties; /**< the number of properties the interface has */
int own_functions; /**< the number of functions the interface has */
+ bool has_type_properties; /**< some of the properties on the
+ * interface have a type handler
+ */
+
int inherit_idx; /**< index into binding map of inherited
* interface or -1 for not in map
*/
diff --git a/test/data/bindings/htmlelement.bnd b/test/data/bindings/htmlelement.bnd
index 1457a32..999a16f 100644
--- a/test/data/bindings/htmlelement.bnd
+++ b/test/data/bindings/htmlelement.bnd
@@ -37,8 +37,6 @@ preamble %{
binding jsapi_libdom {
- interface Text;
- interface Comment;
interface HTMLElement;
interface HTMLAnchorElement;
interface HTMLAnchorElement;
@@ -110,6 +108,8 @@ binding jsapi_libdom {
interface HTMLTrackElement;
interface HTMLUListElement;
interface HTMLUnknownElement;
+ interface Text;
+ interface Comment;
private "dom_element *" node;
private "struct html_content *" htmlc;