summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/duk-libdom.c201
-rw-r--r--src/interface-map.c63
-rw-r--r--src/interface-map.h1
-rw-r--r--src/webidl-ast.c9
-rw-r--r--src/webidl-ast.h14
-rw-r--r--src/webidl-parser.y82
-rw-r--r--test/data/bindings/browser-duk.bnd5
7 files changed, 230 insertions, 145 deletions
diff --git a/src/duk-libdom.c b/src/duk-libdom.c
index 4dbc8e2..bc27dfc 100644
--- a/src/duk-libdom.c
+++ b/src/duk-libdom.c
@@ -23,7 +23,7 @@
#include "duk-libdom.h"
/** prefix for all generated functions */
-#define DLPFX "duckky"
+#define DLPFX "dukky"
#define MAGICPFX "\\xFF\\xFFNETSURF_DUKTAPE_"
@@ -46,7 +46,9 @@ static int output_create_private(FILE* outf, char *class_name)
class_name);
fprintf(outf, "\tif (priv == NULL) return 0;\n");
fprintf(outf, "\tduk_push_pointer(ctx, priv);\n");
- fprintf(outf, "\tduk_put_prop_string(ctx, 0, PRIVATE_MAGIC)\n\n");
+ fprintf(outf,
+ "\tduk_put_prop_string(ctx, 0, \"%sPRIVATE\");\n\n",
+ MAGICPFX);
return 0;
}
@@ -57,7 +59,8 @@ static int output_create_private(FILE* outf, char *class_name)
static int output_safe_get_private(FILE* outf, char *class_name, int idx)
{
fprintf(outf, "\t%s_private_t *priv;\n", class_name);
- fprintf(outf, "\tduk_get_prop_string(ctx, %d, PRIVATE_MAGIC);\n",idx);
+ fprintf(outf, "\tduk_get_prop_string(ctx, %d, \"%sPRIVATE\");\n",
+ idx, MAGICPFX);
fprintf(outf, "\tpriv = duk_get_pointer(ctx, -1);\n");
fprintf(outf, "\tduk_pop(ctx);\n");
fprintf(outf, "\tif (priv == NULL) return 0;\n\n");
@@ -154,11 +157,14 @@ output_dump_stack(FILE* outf)
* generate code that adds a method in a prototype
*/
static int
-output_add_method(FILE* outf, char *class_name, char *method, int argc)
+output_add_method(FILE* outf,
+ const char *class_name,
+ const char *method,
+ int argc)
{
fprintf(outf, "\t/* Add a method */\n");
fprintf(outf, "\tduk_dup(ctx, 0);\n");
- fprintf(outf, "\tduk_push_string(ctx, %s);\n", method);
+ fprintf(outf, "\tduk_push_string(ctx, \"%s\");\n", method);
fprintf(outf, "\tduk_push_c_function(ctx, %s_%s_%s, ",
DLPFX, class_name, method);
if (argc == -1) {
@@ -172,7 +178,7 @@ output_add_method(FILE* outf, char *class_name, char *method, int argc)
fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
return 0;
}
@@ -196,7 +202,7 @@ output_populate_rw_property(FILE* outf, const char *class_name, const char *prop
fprintf(outf, "\t DUK_DEFPROP_HAVE_SETTER |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
return 0;
}
@@ -217,7 +223,7 @@ output_populate_ro_property(FILE* outf, const char *class_name, const char *prop
"\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
return 0;
}
@@ -234,7 +240,7 @@ output_prototype_constant_int(FILE *outf, const char *constant_name, int value)
fprintf(outf, "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
fprintf(outf, "\t DUK_DEFPROP_HAVE_WRITABLE | DUK_DEFPROP_HAVE_ENUMERABLE |\n");
fprintf(outf, "\t DUK_DEFPROP_ENUMERABLE | DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
- fprintf(outf, "\tduk_pop(ctx)\n\n");
+ fprintf(outf, "\tduk_pop(ctx);\n\n");
return 0;
}
@@ -259,7 +265,7 @@ output_get_method_private(FILE* outf, char *class_name)
*/
static int output_tool_preface(FILE* outf)
{
- fprintf(outf, "\n%s\n", NSGENBIND_PREAMBLE);
+ fprintf(outf, "%s\n", NSGENBIND_PREAMBLE);
return 0;
}
@@ -704,20 +710,30 @@ static int count_operation_arguments(struct webidl_node *node)
static int
output_prototype_method(FILE* outf,
struct interface_map_entry *interfacee,
- struct webidl_node *op_node)
+ struct interface_map_operation_entry *operatione)
{
- char *op_name;
int op_argc;
- op_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(op_node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
+ if (operatione->overloadc > 1) {
+ /* only generate a method for the first occourance of an
+ * overloaded method
+ */
+ return 0;
+ }
- op_argc = count_operation_arguments(op_node);
+ if (operatione->name != NULL) {
+ /* normal method of prototype */
+ op_argc = count_operation_arguments(operatione->node);
- output_add_method(outf, interfacee->class_name, op_name, op_argc);
+ output_add_method(outf,
+ interfacee->class_name,
+ operatione->name,
+ op_argc);
+ } else {
+ /* special method on prototype */
+ fprintf(outf,
+ "\t/* Special method on prototype - UNIMPLEMENTED */\n\n");
+ }
return 0;
}
@@ -728,43 +744,19 @@ output_prototype_method(FILE* outf,
static int
output_prototype_methods(FILE *outf, struct interface_map_entry *interfacee)
{
- int res;
- struct webidl_node *list_node;
- struct webidl_node *op_node; /* operation on list node */
-
- /* iterate each list node within the interface */
- list_node = webidl_node_find_type(
- webidl_node_getnode(interfacee->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 = output_prototype_method(outf, interfacee, op_node);
- if (res != 0) {
- return res;
- }
+ int opc;
+ int res = 0;
- op_node = webidl_node_find_type(
- webidl_node_getnode(list_node),
- op_node,
- WEBIDL_NODE_TYPE_OPERATION);
+ for (opc = 0; opc < interfacee->operationc; opc++) {
+ res = output_prototype_method(outf,
+ interfacee,
+ interfacee->operationv + opc);
+ if (res != 0) {
+ break;
}
-
-
- list_node = webidl_node_find_type(
- webidl_node_getnode(interfacee->node),
- list_node,
- WEBIDL_NODE_TYPE_LIST);
}
- return 0;
+ return res;
}
@@ -900,35 +892,34 @@ output_interface_prototype(FILE* outf,
static int
output_interface_operation(FILE* outf,
struct interface_map_entry *interfacee,
- struct webidl_node *op_node)
+ struct interface_map_operation_entry *operatione)
{
- char *op_name;
- struct genbind_node *method_node;
-
- op_name = webidl_node_gettext(
- webidl_node_find_type(
- webidl_node_getnode(op_node),
- NULL,
- WEBIDL_NODE_TYPE_IDENT));
-
- method_node = genbind_node_find_method_ident(interfacee->class,
- NULL,
- GENBIND_METHOD_TYPE_METHOD,
- op_name);
+ if (operatione->overloadc > 1) {
+ /* only generate a method for the first occourance of an
+ * overloaded method
+ */
+ return 0;
+ }
- /* method definition */
- fprintf(outf,
- "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
- DLPFX, interfacee->class_name, op_name);
- fprintf(outf,"{\n");
+ if (operatione->name != NULL) {
+ /* normal method definition */
+ fprintf(outf,
+ "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
+ DLPFX, interfacee->class_name, operatione->name);
+ fprintf(outf,"{\n");
- output_get_method_private(outf, interfacee->class_name);
+ output_get_method_private(outf, interfacee->class_name);
- output_cdata(outf, method_node, GENBIND_NODE_TYPE_CDATA);
+ output_cdata(outf, operatione->method, GENBIND_NODE_TYPE_CDATA);
- fprintf(outf,"\treturn 0;\n");
+ fprintf(outf,"\treturn 0;\n");
- fprintf(outf, "}\n\n");
+ fprintf(outf, "}\n\n");
+ } else {
+ /* special method definition */
+ fprintf(outf,
+ "/* Special method definition - UNIMPLEMENTED */\n\n");
+ }
return 0;
}
@@ -939,43 +930,19 @@ output_interface_operation(FILE* outf,
static int
output_interface_operations(FILE* outf, struct interface_map_entry *interfacee)
{
- int res;
- struct webidl_node *list_node;
- struct webidl_node *op_node; /* operation on list node */
-
- /* iterate each list node within the interface */
- list_node = webidl_node_find_type(
- webidl_node_getnode(interfacee->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 = output_interface_operation(outf, interfacee, op_node);
- if (res != 0) {
- return res;
- }
+ int opc;
+ int res = 0;
- op_node = webidl_node_find_type(
- webidl_node_getnode(list_node),
- op_node,
- WEBIDL_NODE_TYPE_OPERATION);
+ for (opc = 0; opc < interfacee->operationc; opc++) {
+ res = output_interface_operation(outf,
+ interfacee,
+ interfacee->operationv + opc);
+ if (res != 0) {
+ break;
}
-
-
- list_node = webidl_node_find_type(
- webidl_node_getnode(interfacee->node),
- list_node,
- WEBIDL_NODE_TYPE_LIST);
}
- return 0;
+ return res;
}
/**
@@ -1097,24 +1064,25 @@ static int output_interface(struct interface_map *interface_map,
/* find parent interface entry */
inherite = interface_map_inherit_entry(interface_map, interfacee);
+ /* tool preface */
+ output_tool_preface(ifacef);
+
/* binding preface */
output_cdata(ifacef,
interface_map->binding_node,
GENBIND_NODE_TYPE_PREFACE);
- /* tool preface */
- output_tool_preface(ifacef);
-
/* class preface */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PREFACE);
+ /* tool prologue */
+ output_tool_prologue(ifacef);
+
/* binding prologue */
output_cdata(ifacef,
interface_map->binding_node,
GENBIND_NODE_TYPE_PROLOGUE);
- output_tool_prologue(ifacef);
-
/* class prologue */
output_cdata(ifacef, interfacee->class, GENBIND_NODE_TYPE_PROLOGUE);
@@ -1389,20 +1357,21 @@ output_binding_src(struct interface_map *interface_map)
return -1;
}
+ /* tool preface */
+ output_tool_preface(bindf);
+
/* binding preface */
output_cdata(bindf,
interface_map->binding_node,
GENBIND_NODE_TYPE_PREFACE);
- /* tool preface */
- output_tool_preface(bindf);
+ output_tool_prologue(bindf);
/* binding prologue */
output_cdata(bindf,
interface_map->binding_node,
GENBIND_NODE_TYPE_PROLOGUE);
- output_tool_prologue(bindf);
fprintf(bindf, "\n");
diff --git a/src/interface-map.c b/src/interface-map.c
index 555156a..29e9ec0 100644
--- a/src/interface-map.c
+++ b/src/interface-map.c
@@ -133,6 +133,33 @@ interface_topoligical_sort(struct interface_map_entry *srcinf, int infc)
}
static int
+count_operation_name(struct interface_map_operation_entry *operationv,
+ int operationc,
+ const char *name)
+{
+ struct interface_map_operation_entry *cure;
+ int opc;
+ int res = 0;
+
+ for (opc = 0; opc < operationc; opc++) {
+ cure = operationv + opc;
+
+ if (cure->name == name) {
+ /* check pointers for equivalence */
+ res++;
+ } else {
+ if ((cure->name != NULL) &&
+ (name != NULL) &&
+ (strcmp(cure->name, name) == 0)) {
+ res++;
+ }
+ }
+ }
+
+ return res;
+}
+
+static int
operation_map_new(struct webidl_node *interface,
struct genbind_node *class,
int *operationc_out,
@@ -143,14 +170,16 @@ operation_map_new(struct webidl_node *interface,
struct interface_map_operation_entry *cure; /* current entry */
struct interface_map_operation_entry *operationv;
int operationc;
+ int opc;
/* enumerate operationss */
operationc = enumerate_interface_type(interface,
WEBIDL_NODE_TYPE_OPERATION);
- *operationc_out = operationc;
if (operationc < 1) {
- *operationv_out = NULL; /* no operations so empty map */
+ /* no operations so empty map */
+ *operationc_out = 0;
+ *operationv_out = NULL;
return 0;
}
@@ -189,6 +218,10 @@ operation_map_new(struct webidl_node *interface,
GENBIND_METHOD_TYPE_METHOD,
cure->name);
+ cure->overloadc = count_operation_name(operationv,
+ operationc,
+ cure->name);
+
cure++;
/* move to next operation */
@@ -204,6 +237,21 @@ operation_map_new(struct webidl_node *interface,
WEBIDL_NODE_TYPE_LIST);
}
+ /* finally take a pass over the table to correct the overload count */
+ for (opc = 0; opc < operationc; opc++) {
+ cure = operationv + opc;
+ if ((cure->overloadc == 1) &&
+ (count_operation_name(operationv,
+ operationc,
+ cure->name) == 1)) {
+ /* if the "overloaded" member is itself it is not
+ * overloaded.
+ */
+ cure->overloadc = 0;
+ }
+ }
+
+ *operationc_out = operationc;
*operationv_out = operationv; /* resulting operations map */
return 0;
@@ -533,8 +581,15 @@ int interface_map_dump(struct interface_map *index)
ope = ecur->operationv;
while (ope != NULL) {
- fprintf(dumpf, " %s %p\n",
- ope->name, ope->method);
+ fprintf(dumpf,
+ " %s\n",
+ ope->name);
+ fprintf(dumpf,
+ " method:%p\n",
+ ope->method);
+ fprintf(dumpf,
+ " overload:%d\n",
+ ope->overloadc);
ope++;
opc--;
if (opc == 0) {
diff --git a/src/interface-map.h b/src/interface-map.h
index c34eb4b..04d9df1 100644
--- a/src/interface-map.h
+++ b/src/interface-map.h
@@ -17,6 +17,7 @@ struct interface_map_operation_entry {
const char *name; /** operation name */
struct webidl_node *node; /**< AST operation node */
struct genbind_node *method; /**< method from binding (if any) */
+ int overloadc; /**< Number of previous overloads of this operation */
};
/** map entry for attributes on an interface */
diff --git a/src/webidl-ast.c b/src/webidl-ast.c
index 75f969b..0e90767 100644
--- a/src/webidl-ast.c
+++ b/src/webidl-ast.c
@@ -285,6 +285,7 @@ webidl_node_getint(struct webidl_node *node)
case WEBIDL_NODE_TYPE_MODIFIER:
case WEBIDL_NODE_TYPE_TYPE_BASE:
case WEBIDL_NODE_TYPE_LITERAL_INT:
+ case WEBIDL_NODE_TYPE_SPECIAL:
return &node->r.number;
default:
@@ -386,6 +387,9 @@ static const char *webidl_node_type_to_str(enum webidl_node_type type)
case WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE:
return "Extended Attribute";
+ case WEBIDL_NODE_TYPE_SPECIAL:
+ return "Special";
+
default:
return "Unknown";
}
@@ -414,10 +418,13 @@ static int webidl_ast_dump(FILE *dumpf, struct webidl_node *node, int indent)
fprintf(dumpf, "\n");
webidl_ast_dump(dumpf, next, indent + 2);
} else {
- /* not txt or node has to be an int */
+ /* not txt or node try an int */
value = webidl_node_getint(node);
if (value != NULL) {
fprintf(dumpf, ": %d\n", *value);
+ } else {
+ /* no value */
+ fprintf(dumpf, "\n");
}
}
} else {
diff --git a/src/webidl-ast.h b/src/webidl-ast.h
index 38968f3..c17a54b 100644
--- a/src/webidl-ast.h
+++ b/src/webidl-ast.h
@@ -27,7 +27,8 @@ enum webidl_node_type {
WEBIDL_NODE_TYPE_OPERATION,
WEBIDL_NODE_TYPE_CONST,
- WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT,
+ WEBIDL_NODE_TYPE_SPECIAL,
+ WEBIDL_NODE_TYPE_OPTIONAL_ARGUMENT,
WEBIDL_NODE_TYPE_ARGUMENT,
WEBIDL_NODE_TYPE_ELLIPSIS,
WEBIDL_NODE_TYPE_TYPE,
@@ -68,6 +69,15 @@ enum webidl_type_modifier {
WEBIDL_TYPE_MODIFIER_READONLY,
};
+/* the type of special node */
+enum webidl_type_special {
+ WEBIDL_TYPE_SPECIAL_GETTER,
+ WEBIDL_TYPE_SPECIAL_SETTER,
+ WEBIDL_TYPE_SPECIAL_CREATOR,
+ WEBIDL_TYPE_SPECIAL_DELETER,
+ WEBIDL_TYPE_SPECIAL_LEGACYCALLER,
+};
+
struct webidl_node;
/** callback for search and iteration routines */
@@ -114,7 +124,7 @@ webidl_node_find(struct webidl_node *node,
struct webidl_node *
webidl_node_find_type(struct webidl_node *node,
- struct webidl_node *prev,
+ struct webidl_node *prev,
enum webidl_node_type type);
struct webidl_node *
diff --git a/src/webidl-parser.y b/src/webidl-parser.y
index a48f3fd..953388e 100644
--- a/src/webidl-parser.y
+++ b/src/webidl-parser.y
@@ -155,6 +155,9 @@ webidl_error(YYLTYPE *locp, struct webidl_node **winbind_ast, const char *str)
%type <node> Const
%type <node> Operation
+%type <node> SpecialOperation
+%type <node> Specials
+%type <node> Special
%type <node> OperationRest
%type <node> OptionalIdentifier
@@ -723,55 +726,94 @@ ReadOnly:
}
;
- /* [35] */
+ /* SE[47] */
Operation:
- Qualifiers OperationRest
+ ReturnType OperationRest
{
- /* @todo fix qualifiers */
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, $2);
+ /* put return type on the operation */
+ $2 = webidl_node_prepend($1, $2);
+
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, $2);
+ }
+ |
+ SpecialOperation
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_OPERATION, NULL, $1);
}
;
- /* [36] */
-Qualifiers:
- TOK_STATIC
- |
- Specials
+ /* SE[48] */
+SpecialOperation:
+ Special Specials ReturnType OperationRest
+ {
+ /* put return type on the operation */
+ $$ = webidl_node_prepend($4, $3);
+
+ /* specials */
+ $$ = webidl_node_prepend($$, $2);
+
+ /* special */
+ $$ = webidl_node_prepend($$, $1);
+ }
;
- /* [37] */
+ /* SE[49] */
Specials:
/* empty */
+ {
+ $$ = NULL;
+ }
|
Special Specials
+ {
+ $$ = webidl_node_prepend($2, $1);
+ }
;
- /* [38] */
+ /* SE[50] */
Special:
TOK_GETTER
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL, (void *)WEBIDL_TYPE_SPECIAL_GETTER);
+ }
|
TOK_SETTER
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL, (void *)WEBIDL_TYPE_SPECIAL_SETTER);
+ }
|
TOK_CREATOR
+ {
+ /* second edition removed this special but teh
+ specifications still use it!
+ */
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL, (void *)WEBIDL_TYPE_SPECIAL_CREATOR);
+ }
|
TOK_DELETER
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL, (void *)WEBIDL_TYPE_SPECIAL_DELETER);
+ }
|
TOK_LEGACYCALLER
+ {
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_SPECIAL,
+ NULL, (void *)WEBIDL_TYPE_SPECIAL_LEGACYCALLER);
+ }
;
- /* [39] */
+ /* SE[51] */
OperationRest:
- ReturnType OptionalIdentifier '(' ArgumentList ')' ';'
+ OptionalIdentifier '(' ArgumentList ')' ';'
{
- struct webidl_node *arglist;
-
- /* put return type in argument list */
- arglist = webidl_node_prepend($4, $1);
-
/* argument list */
- $$ = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, arglist);
+ $$ = webidl_node_new(WEBIDL_NODE_TYPE_LIST, NULL, $3);
- $$ = webidl_node_prepend($$, $2); /* identifier */
+ $$ = webidl_node_prepend($1, $$); /* identifier */
}
;
diff --git a/test/data/bindings/browser-duk.bnd b/test/data/bindings/browser-duk.bnd
index 513ad99..d0c2c41 100644
--- a/test/data/bindings/browser-duk.bnd
+++ b/test/data/bindings/browser-duk.bnd
@@ -14,7 +14,8 @@ binding duk_libdom {
webidl "uievents.idl";
webidl "console.idl";
- preface %{
+ preface
+%{
/* DukTape JavaScript bindings for NetSurf browser
*
* Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
@@ -22,7 +23,7 @@ binding duk_libdom {
* Released under the terms of the MIT License,
* http://www.opensource.org/licenses/mit-license
*/
- %};
+%};
prologue %{
/* binding prologue */