summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2012-11-01 21:10:37 +0000
committerVincent Sanders <vince@kyllikki.org>2012-11-01 21:10:37 +0000
commit8779ca25c44286b956ac604549d55c7d1661619e (patch)
tree413f7628a91d5a481cc65ff02fb539160c658e29
parente35c777cc2d3d551d4f659e95c06b902379992aa (diff)
downloadnsgenbind-8779ca25c44286b956ac604549d55c7d1661619e.tar.gz
nsgenbind-8779ca25c44286b956ac604549d55c7d1661619e.tar.bz2
improve return variable handling
-rw-r--r--src/jsapi-libdom-operator.c231
-rw-r--r--src/jsapi-libdom-property.c282
2 files changed, 467 insertions, 46 deletions
diff --git a/src/jsapi-libdom-operator.c b/src/jsapi-libdom-operator.c
index 748ea4c..a20f377 100644
--- a/src/jsapi-libdom-operator.c
+++ b/src/jsapi-libdom-operator.c
@@ -17,6 +17,9 @@
#include "webidl-ast.h"
#include "jsapi-libdom.h"
+#define WARN(msg, args...) fprintf(stderr, "%s: warning:"msg"\n", __func__, ## args);
+
+
static int webidl_func_spec_cb(struct webidl_node *node, void *ctx)
{
struct binding *binding = ctx;
@@ -125,6 +128,219 @@ int output_function_spec(struct binding *binding)
return res;
}
+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,
+ "\tJS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n",
+ ident);
+
+ break;
+
+ case WEBIDL_TYPE_BOOL:
+ /* JSBool */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(%s));\n",
+ ident);
+
+ break;
+
+ case WEBIDL_TYPE_BYTE:
+ WARN("Unhandled type WEBIDL_TYPE_BYTE");
+ break;
+
+ case WEBIDL_TYPE_OCTET:
+ WARN("Unhandled type WEBIDL_TYPE_OCTET");
+ break;
+
+ case WEBIDL_TYPE_FLOAT:
+ case WEBIDL_TYPE_DOUBLE:
+ /* double */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_SHORT:
+ WARN("Unhandled type WEBIDL_TYPE_SHORT");
+ break;
+
+ case WEBIDL_TYPE_LONGLONG:
+ WARN("Unhandled type WEBIDL_TYPE_LONGLONG");
+ break;
+
+ case WEBIDL_TYPE_LONG:
+ /* int32_t */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, INT_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_STRING:
+ /* JSString * */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, STRING_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_SEQUENCE:
+ WARN("Unhandled type WEBIDL_TYPE_SEQUENCE");
+ break;
+
+ case WEBIDL_TYPE_OBJECT:
+ /* JSObject * */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_DATE:
+ WARN("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_base = NULL;
+ struct webidl_node *type_name = 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 */
+ 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("Unhandled type WEBIDL_TYPE_BYTE");
+ break;
+
+ case WEBIDL_TYPE_OCTET:
+ WARN("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("Unhandled type WEBIDL_TYPE_SHORT");
+ break;
+
+ case WEBIDL_TYPE_LONGLONG:
+ WARN("Unhandled type WEBIDL_TYPE_LONGLONG");
+ break;
+
+ case WEBIDL_TYPE_LONG:
+ /* int32_t */
+ 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("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("Unhandled type WEBIDL_TYPE_DATE");
+ break;
+
+ case WEBIDL_TYPE_VOID:
+ /* specifically requires no value */
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
/** creates all the variable definitions
*
@@ -145,9 +361,6 @@ output_variable_definitions(struct binding *binding,
struct webidl_node *arg_type_ident = NULL;
enum webidl_type webidl_arg_type;
- /* return value */
- fprintf(binding->outfile, "\tjsval jsretval = JSVAL_VOID;\n");
-
/* input variables */
arglist_node = webidl_node_find_type(operation_list,
NULL,
@@ -197,7 +410,7 @@ output_variable_definitions(struct binding *binding,
NULL,
WEBIDL_NODE_TYPE_IDENT);
- fprintf(stderr,
+ fprintf(stderr,
"User type: %s:%s %s\n",
webidl_node_gettext(operation_ident),
webidl_node_gettext(arg_type_ident),
@@ -448,6 +661,9 @@ static int webidl_operator_body_cb(struct webidl_node *node, void *ctx)
fprintf(binding->outfile,
"{\n");
+ /* return value declaration */
+ output_return_declaration(binding, "jsret", webidl_node_getnode(node));
+
output_variable_definitions(binding, webidl_node_getnode(node));
if (binding->has_private) {
@@ -475,15 +691,16 @@ static int webidl_operator_body_cb(struct webidl_node *node, void *ctx)
genbind_node_getnode(operation_node));
} else {
- fprintf(stderr,
- "Warning: function/operation %s.%s has no implementation\n",
+ fprintf(stderr,
+ "warning: operation %s.%s has no implementation\n",
binding->interface,
webidl_node_gettext(ident_node));
}
+ output_return(binding, "jsret", webidl_node_getnode(node));
+
/* set return value an return true */
fprintf(binding->outfile,
- "\tJSAPI_SET_RVAL(cx, vp, jsretval);\n"
"\treturn JS_TRUE;\n"
"}\n\n");
}
diff --git a/src/jsapi-libdom-property.c b/src/jsapi-libdom-property.c
index 6083bb9..b5f30b9 100644
--- a/src/jsapi-libdom-property.c
+++ b/src/jsapi-libdom-property.c
@@ -140,48 +140,217 @@ output_property_spec(struct binding *binding)
return res;
}
-static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
+#define WARN(msg, args...) fprintf(stderr, "%s: warning:"msg"\n", __func__, ## args);
+
+static int output_return(struct binding *binding,
+ const char *ident,
+ struct webidl_node *node)
{
- struct binding *binding = ctx;
- struct webidl_node *ident_node;
- struct webidl_node *modifier_node;
- struct genbind_node *property_node;
+ struct webidl_node *type_node = NULL;
+ struct webidl_node *type_base = NULL;
+ enum webidl_type webidl_arg_type;
- ident_node = webidl_node_find_type(webidl_node_getnode(node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT);
- if (ident_node == NULL) {
- /* properties must have an operator
- * http://www.w3.org/TR/WebIDL/#idl-attributes
- */
- return 1;
- }
+ type_node = webidl_node_find_type(webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_TYPE);
- modifier_node = webidl_node_find_type(webidl_node_getnode(node),
+ type_base = webidl_node_find_type(webidl_node_getnode(type_node),
NULL,
- WEBIDL_NODE_TYPE_MODIFIER);
+ WEBIDL_NODE_TYPE_TYPE_BASE);
+ webidl_arg_type = webidl_node_getint(type_base);
- if (webidl_node_getint(modifier_node) != WEBIDL_TYPE_READONLY) {
- /* no readonly so a set function is required */
+ switch (webidl_arg_type) {
+ case WEBIDL_TYPE_USER:
+ /* User type are represented with jsobject */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_BOOL:
+ /* JSBool */
fprintf(binding->outfile,
- "static JSBool JSAPI_PROPERTYSET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n",
- webidl_node_gettext(ident_node));
+ "\tJS_SET_RVAL(cx, vp, BOOLEAN_TO_JSVAL(%s));\n",
+ ident);
+
+ break;
+
+ case WEBIDL_TYPE_BYTE:
+ WARN("Unhandled type WEBIDL_TYPE_BYTE");
+ break;
+
+ case WEBIDL_TYPE_OCTET:
+ WARN("Unhandled type WEBIDL_TYPE_OCTET");
+ break;
+
+ case WEBIDL_TYPE_FLOAT:
+ case WEBIDL_TYPE_DOUBLE:
+ /* double */
fprintf(binding->outfile,
- "{\n"
- " return JS_FALSE;\n"
- "}\n\n");
+ "\tJS_SET_RVAL(cx, vp, DOUBLE_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_SHORT:
+ WARN("Unhandled type WEBIDL_TYPE_SHORT");
+ break;
+
+ case WEBIDL_TYPE_LONGLONG:
+ WARN("Unhandled type WEBIDL_TYPE_LONGLONG");
+ break;
+
+ case WEBIDL_TYPE_LONG:
+ /* int32_t */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, INT_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_STRING:
+ /* JSString * */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, STRING_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_SEQUENCE:
+ WARN("Unhandled type WEBIDL_TYPE_SEQUENCE");
+ break;
+
+ case WEBIDL_TYPE_OBJECT:
+ /* JSObject * */
+ fprintf(binding->outfile,
+ "\tJS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(%s));\n",
+ ident);
+ break;
+
+ case WEBIDL_TYPE_DATE:
+ WARN("Unhandled type WEBIDL_TYPE_DATE");
+ break;
+
+ case WEBIDL_TYPE_VOID:
+ /* specifically requires no value */
+ break;
+
+ default:
+ break;
}
- /* property getter */
+ 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;
+ 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("Unhandled type WEBIDL_TYPE_BYTE");
+ break;
+
+ case WEBIDL_TYPE_OCTET:
+ WARN("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("Unhandled type WEBIDL_TYPE_SHORT");
+ break;
+
+ case WEBIDL_TYPE_LONGLONG:
+ WARN("Unhandled type WEBIDL_TYPE_LONGLONG");
+ break;
+
+ case WEBIDL_TYPE_LONG:
+ /* int32_t */
+ 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("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("Unhandled type WEBIDL_TYPE_DATE");
+ break;
+
+ case WEBIDL_TYPE_VOID:
+ /* specifically requires no value */
+ break;
+
+ default:
+ break;
+ }
+ return 0;
+}
+
+static int output_property_getter(struct binding *binding,
+ struct webidl_node *node,
+ const char *ident)
+{
+ struct genbind_node *property_node;
+
fprintf(binding->outfile,
"static JSBool JSAPI_PROPERTYGET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n"
"{\n",
- webidl_node_gettext(ident_node));
+ ident);
- /* return value */
- fprintf(binding->outfile, "\tjsval jsretval = JSVAL_NULL;\n");
+ /* return value declaration */
+ output_return_declaration(binding, "jsret", node);
if (binding->has_private) {
/* get context */
@@ -193,14 +362,14 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
"\t\t&JSClass_%s,\n"
"\t\tNULL);\n"
"\tif (private == NULL)\n"
- "\t\treturn JS_FALSE;\n\n",
+ "\t\treturn JS_FALSE;\n\n",
binding->interface);
}
property_node = genbind_node_find_type_ident(binding->gb_ast,
NULL,
GENBIND_NODE_TYPE_GETTER,
- webidl_node_gettext(ident_node));
+ ident);
if (property_node != NULL) {
/* binding source block */
@@ -218,33 +387,68 @@ static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
internal_node = genbind_node_find_type_ident(genbind_node_getnode(binding_node),
NULL,
GENBIND_NODE_TYPE_BINDING_INTERNAL,
- webidl_node_gettext(ident_node));
+ ident);
}
if (internal_node != NULL) {
/** @todo fetching from internal entries ought to be type sensitive */
fprintf(binding->outfile,
- "\tjsretval = OBJECT_TO_JSVAL(private->%s);\n",
- webidl_node_gettext(ident_node));
+ "\tjsret = private->%s;\n",
+ ident);
} else {
- fprintf(stderr,
- "Warning: property/attribute getter %s.%s has no implementation\n",
+ fprintf(stderr,
+ "warning: attribute getter %s.%s has no implementation\n",
binding->interface,
- webidl_node_gettext(ident_node));
+ ident);
}
}
+ output_return(binding, "jsret", node);
fprintf(binding->outfile,
- "\tJS_SET_RVAL(cx, vp, jsretval);\n"
- "\treturn JS_TRUE;\n");
+ "\treturn JS_TRUE;\n"
+ "}\n\n");
+
+ return 0;
+}
+
+static int webidl_property_body_cb(struct webidl_node *node, void *ctx)
+{
+ struct binding *binding = ctx;
+ struct webidl_node *ident_node;
+ struct webidl_node *modifier_node;
- fprintf(binding->outfile, "}\n\n");
+ ident_node = webidl_node_find_type(webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_IDENT);
+ if (ident_node == NULL) {
+ /* properties must have an operator
+ * http://www.w3.org/TR/WebIDL/#idl-attributes
+ */
+ return 1;
+ }
+ modifier_node = webidl_node_find_type(webidl_node_getnode(node),
+ NULL,
+ WEBIDL_NODE_TYPE_MODIFIER);
- return 0;
+
+ if (webidl_node_getint(modifier_node) != WEBIDL_TYPE_READONLY) {
+ /* no readonly so a set function is required */
+
+ fprintf(binding->outfile,
+ "static JSBool JSAPI_PROPERTYSET(%s, JSContext *cx, JSObject *obj, jsval *vp)\n",
+ webidl_node_gettext(ident_node));
+ fprintf(binding->outfile,
+ "{\n"
+ " return JS_FALSE;\n"
+ "}\n\n");
+ }
+
+ /* property getter */
+ return output_property_getter(binding, node, webidl_node_gettext(ident_node));
}
/* callback to emit implements property bodys */