29#define MAGICPFX "\\xFF\\xFFNETSURF_DUKTAPE_"
44static char *get_prototype_name(
const char *interface_name)
52 pnamelen = strlen(interface_name) + 1;
54 proto_name =
malloc(pnamelen + pfxlen);
55 snprintf(proto_name, pnamelen + pfxlen,
"%sPROTOTYPE_%s",
MAGICPFX, interface_name);
56 for (pnamelen-- ; pnamelen >= 0; pnamelen--) {
57 proto_name[pnamelen + pfxlen] = toupper(interface_name[pnamelen]);
66static struct opctx *open_header(
struct ir *
ir,
const char *name)
73 fnamel = strlen(name) + 4;
75 snprintf(fname, fnamel,
"%s.h", name);
94 "\n#ifndef %s_%s_h\n",
DLPFX, name);
96 "#define %s_%s_h\n\n",
DLPFX, name);
101static int close_header(
struct ir *
ir,
struct opctx *hdrc)
122output_private_header(
struct ir *
ir)
128 privc = open_header(
ir,
"private");
130 for (idx = 0; idx <
ir->
entryc; idx++) {
145 switch (interfacee->
type) {
148 "/* Private data for %s interface */\n",
154 "/* Private data for %s dictionary */\n",
160 "typedef struct {\n");
164 if (inherite != NULL) {
166 "\t%s_private_t parent;\n",
175 while (priv_node != NULL) {
189 "} __attribute__((aligned)) %s_private_t;\n\n",
193 close_header(
ir, privc);
202output_prototype_header(
struct ir *
ir)
205 struct opctx *protoc;
208 protoc = open_header(
ir,
"prototype");
210 for (idx = 0; idx <
ir->
entryc; idx++) {
215 switch (entry->
type) {
226 close_header(
ir, protoc);
235output_makefile(
struct ir *
ir)
246 fprintf(makef,
"# duk libdom makefile fragment\n\n");
248 fprintf(makef,
"NSGENBIND_SOURCES:=binding.c ");
249 for (idx = 0; idx <
ir->
entryc; idx++) {
260 fprintf(makef,
"%s ", interfacee->
filename);
281output_binding_header(
struct ir *
ir)
286 bindc = open_header(
ir,
"binding");
289 "#define _MAGIC(S) (\"%s\" S)\n"
290 "#define MAGIC(S) _MAGIC(#S)\n"
291 "#define PROTO_MAGIC MAGIC(PROTOTYPES)\n"
292 "#define PRIVATE_MAGIC MAGIC(PRIVATE)\n"
293 "#define INIT_MAGIC MAGIC(INIT)\n"
294 "#define NODE_MAGIC MAGIC(NODE_MAP)\n"
295 "#define _PROTO_NAME(K) _MAGIC(\"PROTOTYPE_\" K)\n"
296 "#define PROTO_NAME(K) _PROTO_NAME(#K)\n"
297 "#define _PROP_NAME(K,V) _MAGIC(K \"_PROPERTY_\" V)\n"
298 "#define PROP_NAME(K,V) _PROP_NAME(#K,#V)\n"
304 "/* Constant strings */\n"
305 "extern const char *%s_error_fmt_argument;\n"
306 "extern const char *%s_error_fmt_bool_type;\n"
307 "extern const char *%s_error_fmt_number_type;\n"
308 "extern const char *%s_magic_string_private;\n"
309 "extern const char *%s_magic_string_prototypes;\n"
314 "duk_bool_t %s_instanceof(duk_context *ctx, duk_idx_t index, const char *klass);\n",
318 "duk_ret_t %s_create_prototypes(duk_context *ctx);\n",
DLPFX);
320 close_header(
ir, bindc);
333output_binding_src(
struct ir *
ir)
366 "/* Error format strings */\n"
367 "const char *%s_error_fmt_argument =\"%%d argument required, but ony %%d present.\";\n"
368 "const char *%s_error_fmt_bool_type =\"argument %%d (%%s) requires a bool\";\n"
369 "const char *%s_error_fmt_number_type =\"argument %%d (%%s) requires a number\";\n",
375 "/* Magic identifiers */\n"
376 "const char *%s_magic_string_private =\"%sPRIVATE\";\n"
377 "const char *%s_magic_string_prototypes =\"%sPROTOTYPES\";\n",
386 "%s_instanceof(duk_context *ctx, duk_idx_t _idx, const char *klass)\n"
388 "\tduk_idx_t idx = duk_normalize_index(ctx, _idx);\n"
389 "\t/* ... ??? ... */\n"
390 "\tif (!duk_check_type(ctx, idx, DUK_TYPE_OBJECT)) {\n"
391 "\t\treturn false;\n"
393 "\t/* ... obj ... */\n"
394 "\tduk_get_global_string(ctx, %s_magic_string_prototypes);\n"
395 "\t/* ... obj ... protos */\n"
396 "\tduk_get_prop_string(ctx, -1, klass);\n"
397 "\t/* ... obj ... protos goalproto */\n"
398 "\tduk_get_prototype(ctx, idx);\n"
399 "\t/* ... obj ... protos goalproto proto? */\n"
400 "\twhile (!duk_is_undefined(ctx, -1)) {\n"
401 "\t\tif (duk_strict_equals(ctx, -1, -2)) {\n"
402 "\t\t\tduk_pop_3(ctx);\n"
403 "\t\t\t/* ... obj ... */\n"
404 "\t\t\treturn true;\n"
406 "\t\tduk_get_prototype(ctx, -1);\n"
407 "\t\t/* ... obj ... protos goalproto proto proto? */\n"
408 "\t\tduk_replace(ctx, -2);\n"
409 "\t\t/* ... obj ... protos goalproto proto? */\n"
411 "\tduk_pop_3(ctx);\n"
412 "\t/* ... obj ... */\n"
421 "%s_to_string(duk_context *ctx)\n"
424 "\tduk_push_this(ctx);\n"
426 "\tduk_get_prototype(ctx, -1);\n"
427 "\t/* this proto */\n"
428 "\tduk_get_prop_string(ctx, -1, \"%sklass_name\");\n"
429 "\t/* this proto classname */\n"
430 "\tduk_push_string(ctx, \"[object \");\n"
431 "\t/* this proto classname str */\n"
432 "\tduk_insert(ctx, -2);\n"
433 "\t/* this proto str classname */\n"
434 "\tduk_push_string(ctx, \"]\");\n"
435 "\t/* this proto str classname str */\n"
436 "\tduk_concat(ctx, 3);\n"
437 "\t/* this proto str */\n"
445 "static duk_ret_t %s_create_prototype(duk_context *ctx,\n",
448 "\t\t\t\t\tduk_safe_call_function genproto,\n"
449 "\t\t\t\t\tconst char *proto_name,\n"
450 "\t\t\t\t\tconst char *klass_name)\n"
453 "\tduk_push_object(ctx);\n"
454 "\tif ((ret = duk_safe_call(ctx, genproto, NULL, 1, 1)) != DUK_EXEC_SUCCESS) {\n"
455 "\t\tduk_pop(ctx);\n"
456 "\t\tNSLOG(dukky, WARNING, \"Failed to register prototype for %%s\", proto_name + 2);\n"
459 "\t/* top of stack is the ready prototype, inject it */\n"
460 "\tduk_push_string(ctx, klass_name);\n"
461 "\tduk_put_prop_string(ctx, -2, \"%sklass_name\");\n"
462 "\tduk_push_c_function(ctx, %s_to_string, 0);\n"
463 "\tduk_put_prop_string(ctx, -2, \"toString\");\n"
464 "\tduk_push_string(ctx, \"toString\");\n"
465 "\tduk_def_prop(ctx, -2, DUK_DEFPROP_HAVE_ENUMERABLE);\n"
466 "\tduk_put_global_string(ctx, proto_name);\n"
467 "\treturn DUK_ERR_NONE;\n"
474 "duk_ret_t %s_create_prototypes(duk_context *ctx)\n",
DLPFX);
478 for (idx = 0; idx <
ir->
entryc; idx++) {
496 pglobale = interfacee;
500 proto_name = get_prototype_name(interfacee->
name);
503 "\t%s_create_prototype(ctx, %s_%s___proto, \"%s\", \"%s\");\n",
513 if (pglobale != NULL) {
514 outputf(bindc,
"\n\t/* Global object prototype is last */\n");
516 proto_name = get_prototype_name(pglobale->
name);
518 "\t%s_create_prototype(ctx, %s_%s___proto, \"%s\", \"%s\");\n",
527 outputf(bindc,
"\n\treturn DUK_ERR_NONE;\n");
541static int output_interfaces_dictionaries(
struct ir *
ir)
547 for (idx = 0; idx <
ir->
entryc; idx++) {
552 switch (irentry->
type) {
585 for (idx = 0; idx <
ir->
entryc; idx++) {
597 ifacenamelen = strlen(irentry->
class_name) + 4;
606 res = output_interfaces_dictionaries(
ir);
612 res = output_private_header(
ir);
618 res = output_prototype_header(
ir);
624 res = output_binding_header(
ir);
630 res = output_binding_src(
ir);
636 res = output_makefile(
ir);
int output_method_cdata(struct opctx *outc, struct genbind_node *node, enum genbind_method_type sel_method_type)
int output_tool_prologue(struct opctx *outc)
int output_tool_preface(struct opctx *outc)
int output_ctype(struct opctx *outc, struct genbind_node *node, bool identifier)
char * gen_idl2c_name(const char *idlname)
int output_dictionary(struct ir *ir, struct ir_entry *dictionarye)
int output_dictionary_declaration(struct opctx *outc, struct ir_entry *dictionarye)
int output_interface_declaration(struct opctx *outc, struct ir_entry *interfacee)
int output_interface(struct ir *ir, struct ir_entry *interfacee)
int duk_libdom_output(struct ir *ir)
struct ir_entry * ir_inherit_entry(struct ir *map, struct ir_entry *entry)
@ IR_ENTRY_TYPE_DICTIONARY
@ IR_ENTRY_TYPE_INTERFACE
struct genbind_node * genbind_node_find_type(struct genbind_node *node, struct genbind_node *prev, enum genbind_node_type type)
struct genbind_node * genbind_node_getnode(struct genbind_node *node)
@ GENBIND_METHOD_TYPE_PREFACE
@ GENBIND_METHOD_TYPE_PROLOGUE
@ GENBIND_METHOD_TYPE_POSTFACE
@ GENBIND_NODE_TYPE_PRIVATE
int outputc(struct opctx *opctx, int c)
int outputf(struct opctx *opctx, const char *fmt,...)
int output_close(struct opctx *opctx)
int output_open(const char *filename, struct opctx **opctx_out)
struct genbind_node * class
struct ir_interface_entry interface
struct genbind_node * binding_node
struct ir_entry * entries
FILE * genb_fopen_tmp(const char *fname)
int genb_fclose_tmp(FILE *filef_tmp, const char *fname)