nsgenbind
Loading...
Searching...
No Matches
duk-libdom-interface.c
Go to the documentation of this file.
1/* duktape binding generation implementation
2 *
3 * This file is part of nsgenbind.
4 * Licensed under the MIT License,
5 * http://www.opensource.org/licenses/mit-license.php
6 * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org>
7 */
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <stdbool.h>
12#include <string.h>
13#include <unistd.h>
14#include <getopt.h>
15#include <errno.h>
16#include <ctype.h>
17
18#include "options.h"
19#include "utils.h"
20#include "nsgenbind-ast.h"
21#include "webidl-ast.h"
22#include "ir.h"
23#include "output.h"
24#include "duk-libdom.h"
25
27#define DLPFX "dukky"
28
29#define MAGICPFX "\\xFF\\xFFNETSURF_DUKTAPE_"
30
31
35static char *get_prototype_name(const char *interface_name)
36{
37 char *proto_name;
38 int pnamelen;
39 int pfxlen;
40
41 /* duplicate the interface name in upper case */
42 pfxlen = SLEN(MAGICPFX) + SLEN("PROTOTYPE_");
43 pnamelen = strlen(interface_name) + 1;
44
45 proto_name = malloc(pnamelen + pfxlen);
46 snprintf(proto_name, pnamelen + pfxlen,
47 "%sPROTOTYPE_%s", MAGICPFX, interface_name);
48 for (pnamelen-- ; pnamelen >= 0; pnamelen--) {
49 proto_name[pnamelen + pfxlen] = toupper(interface_name[pnamelen]);
50 }
51 return proto_name;
52}
53
54
58static bool compare_ctypes(struct genbind_node *a, struct genbind_node *b)
59{
60 struct genbind_node *ta;
61 struct genbind_node *tb;
62
67
68 while ((ta != NULL) && (tb != NULL)) {
69 char *txt_a;
70 char *txt_b;
71
72 txt_a = genbind_node_gettext(ta);
73 txt_b = genbind_node_gettext(tb);
74
75 if (strcmp(txt_a, txt_b) != 0) {
76 return false; /* missmatch */
77 }
78
83 }
84 if (ta != tb) {
85 return false;
86 }
87
88 return true;
89}
90
91
98static int
99output_create_private(struct opctx *outc, char *class_name)
100{
101 outputf(outc,
102 "\t/* create private data and attach to instance */\n");
103 outputf(outc,
104 "\t%s_private_t *priv = calloc(1, sizeof(*priv));\n",
105 class_name);
106 outputf(outc,
107 "\tif (priv == NULL) return 0;\n");
108 outputf(outc,
109 "\tduk_push_pointer(ctx, priv);\n");
110 outputf(outc,
111 "\tduk_put_prop_string(ctx, 0, %s_magic_string_private);\n\n",
112 DLPFX);
113
114 return 0;
115}
116
117
121static int
122output_safe_get_private(struct opctx *outc, char *class_name, int idx)
123{
124 outputf(outc,
125 "\t%s_private_t *priv;\n", class_name);
126 outputf(outc,
127 "\tduk_get_prop_string(ctx, %d, %s_magic_string_private);\n",
128 idx, DLPFX);
129 outputf(outc,
130 "\tpriv = duk_get_pointer(ctx, -1);\n");
131 outputf(outc,
132 "\tduk_pop(ctx);\n");
133 outputf(outc,
134 "\tif (priv == NULL) return 0;\n\n");
135
136 return 0;
137}
138
139
143static int output_get_prototype(struct opctx *outc, const char *interface_name)
144{
145 char *proto_name;
146
147 proto_name = get_prototype_name(interface_name);
148
149 outputf(outc,
150 "\t/* get prototype */\n");
151 outputf(outc,
152 "\tduk_get_global_string(ctx, %s_magic_string_prototypes);\n",
153 DLPFX);
154 outputf(outc,
155 "\tduk_get_prop_string(ctx, -1, \"%s\");\n",
156 proto_name);
157 outputf(outc,
158 "\tduk_replace(ctx, -2);\n");
159
160 free(proto_name);
161
162 return 0;
163}
164
168static int output_set_destructor(struct opctx *outc, char *class_name, int idx)
169{
170 outputf(outc,
171 "\t/* Set the destructor */\n");
172 outputf(outc,
173 "\tduk_dup(ctx, %d);\n", idx);
174 outputf(outc,
175 "\tduk_push_c_function(ctx, %s_%s___destructor, 1);\n",
176 DLPFX, class_name);
177 outputf(outc,
178 "\tduk_set_finalizer(ctx, -2);\n");
179 outputf(outc,
180 "\tduk_pop(ctx);\n\n");
181
182 return 0;
183}
184
188static int
189output_set_constructor(struct opctx *outc, char *class_name, int idx, int argc)
190{
191 outputf(outc,
192 "\t/* Set the constructor */\n");
193 outputf(outc,
194 "\tduk_dup(ctx, %d);\n", idx);
195 outputf(outc,
196 "\tduk_push_c_function(ctx, %s_%s___constructor, %d);\n",
197 DLPFX, class_name, 1 + argc);
198 outputf(outc,
199 "\tduk_put_prop_string(ctx, -2, \"%sINIT\");\n",
200 MAGICPFX);
201 outputf(outc,
202 "\tduk_pop(ctx);\n\n");
203
204 return 0;
205}
206
207
211static int
212output_dump_stack(struct opctx *outc)
213{
214 if (options->dbglog) {
215 /* dump stack */
216 outputf(outc,
217 "\tduk_push_context_dump(ctx);\n");
218 outputf(outc,
219 "\tNSLOG(dukky, DEEPDEBUG, \"Stack: %%s\", duk_to_string(ctx, -1));\n");
220 outputf(outc,
221 "\tduk_pop(ctx);\n");
222 }
223 return 0;
224}
225
226
230static int
231output_add_method(struct opctx *outc,
232 const char *class_name,
233 const char *method)
234{
235 outputf(outc,
236 "\t/* Add a method */\n");
237 outputf(outc,
238 "\tduk_dup(ctx, 0);\n");
239 outputf(outc,
240 "\tduk_push_string(ctx, \"%s\");\n", method);
241 outputf(outc,
242 "\tduk_push_c_function(ctx, %s_%s_%s, DUK_VARARGS);\n",
243 DLPFX, class_name, method);
244 output_dump_stack(outc);
245 outputf(outc,
246 "\tduk_def_prop(ctx, -3,\n");
247 outputf(outc,
248 "\t\t DUK_DEFPROP_HAVE_VALUE |\n");
249 outputf(outc,
250 "\t\t DUK_DEFPROP_HAVE_WRITABLE |\n");
251 outputf(outc,
252 "\t\t DUK_DEFPROP_HAVE_ENUMERABLE |\n");
253 outputf(outc,
254 "\t\t DUK_DEFPROP_ENUMERABLE |\n");
255 outputf(outc,
256 "\t\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
257 outputf(outc,
258 "\tduk_pop(ctx);\n\n");
259
260 return 0;
261}
262
266static int
267output_populate_rw_property(struct opctx *outc,
268 const char *class_name,
269 const char *property)
270{
271 outputf(outc,
272 "\t/* Add read/write property */\n");
273 outputf(outc,
274 "\tduk_dup(ctx, 0);\n");
275 outputf(outc,
276 "\tduk_push_string(ctx, \"%s\");\n", property);
277 outputf(outc,
278 "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
279 DLPFX, class_name, property);
280 outputf(outc,
281 "\tduk_push_c_function(ctx, %s_%s_%s_setter, 1);\n",
282 DLPFX, class_name, property);
283 output_dump_stack(outc);
284 outputf(outc,
285 "\tduk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER |\n");
286 outputf(outc,
287 "\t\tDUK_DEFPROP_HAVE_SETTER |\n");
288 outputf(outc,
289 "\t\tDUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
290 outputf(outc,
291 "\t\tDUK_DEFPROP_HAVE_CONFIGURABLE);\n");
292 outputf(outc,
293 "\tduk_pop(ctx);\n\n");
294
295 return 0;
296}
297
298
302static int
303output_populate_ro_property(struct opctx *outc,
304 const char *class_name,
305 const char *property)
306{
307 outputf(outc,
308 "\t/* Add readonly property */\n");
309 outputf(outc,
310 "\tduk_dup(ctx, 0);\n");
311 outputf(outc,
312 "\tduk_push_string(ctx, \"%s\");\n", property);
313 outputf(outc,
314 "\tduk_push_c_function(ctx, %s_%s_%s_getter, 0);\n",
315 DLPFX, class_name, property);
316 output_dump_stack(outc);
317 outputf(outc,
318 "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER |\n");
319 outputf(outc,
320 "\t\tDUK_DEFPROP_HAVE_ENUMERABLE | DUK_DEFPROP_ENUMERABLE |\n");
321 outputf(outc,
322 "\t\tDUK_DEFPROP_HAVE_CONFIGURABLE);\n");
323 outputf(outc,
324 "\tduk_pop(ctx);\n\n");
325
326 return 0;
327}
328
329
333static int
334output_prototype_constant_int(struct opctx *outc,
335 const char *constant_name,
336 int value)
337{
338 outputf(outc,
339 "\tduk_dup(ctx, 0);\n");
340 outputf(outc,
341 "\tduk_push_string(ctx, \"%s\");\n", constant_name);
342 outputf(outc,
343 "\tduk_push_int(ctx, %d);\n", value);
344 outputf(outc,
345 "\tduk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_VALUE |\n");
346 outputf(outc,
347 "\t\t DUK_DEFPROP_HAVE_WRITABLE |\n");
348 outputf(outc,
349 "\t\t DUK_DEFPROP_HAVE_ENUMERABLE |\n");
350 outputf(outc,
351 "\t\t DUK_DEFPROP_ENUMERABLE |\n");
352 outputf(outc,
353 "\t\t DUK_DEFPROP_HAVE_CONFIGURABLE);\n");
354 outputf(outc,
355 "\tduk_pop(ctx);\n\n");
356 return 0;
357}
358
359
363static int
364output_get_method_private(struct opctx *outc, char *class_name, bool is_global)
365{
366 outputf(outc,
367 "\t/* Get private data for method */\n");
368 outputf(outc,
369 "\t%s_private_t *priv = NULL;\n", class_name);
370 if (is_global) {
371 outputf(outc,
372 "\tduk_push_global_object(ctx);\n");
373 } else {
374 outputf(outc,
375 "\tduk_push_this(ctx);\n");
376 }
377 outputf(outc,
378 "\tduk_get_prop_string(ctx, -1, %s_magic_string_private);\n",
379 DLPFX);
380 outputf(outc,
381 "\tpriv = duk_get_pointer(ctx, -1);\n");
382 outputf(outc,
383 "\tduk_pop_2(ctx);\n");
384 outputf(outc,
385 "\tif (priv == NULL) {\n");
386 if (options->dbglog) {
387 outputf(outc,
388 "\t\tNSLOG(dukky, INFO, \"priv failed\");\n");
389 }
390 outputf(outc,
391 "\t\treturn 0; /* can do? No can do. */\n");
392 outputf(outc,
393 "\t}\n\n");
394
395 return 0;
396}
397
398
402static int
403output_interface_constructor(struct opctx *outc, struct ir_entry *interfacee)
404{
405 int init_argc;
406
407 /* constructor definition */
408 outputf(outc,
409 "static duk_ret_t %s_%s___constructor(duk_context *ctx)\n",
410 DLPFX, interfacee->class_name);
411 outputf(outc,
412 "{\n");
413
414 output_create_private(outc, interfacee->class_name);
415
416 /* generate call to initialisor */
417 outputf(outc,
418 "\t%s_%s___init(ctx, priv",
419 DLPFX, interfacee->class_name);
420
421 for (init_argc = 1;
422 init_argc <= interfacee->class_init_argc;
423 init_argc++) {
424 switch (interfacee->class_init_argt[init_argc-1]) {
425 case IR_INIT_ARG_BOOL:
426 outputf(outc,
427 ", duk_get_bool(ctx, %d)",
428 init_argc);
429 break;
431 case IR_INIT_ARG_INT:
432 outputf(outc,
433 ", duk_get_int(ctx, %d)",
434 init_argc);
435 break;
437 outputf(outc,
438 ", duk_get_pointer(ctx, %d)",
439 init_argc);
440 break;
441 }
442 }
443 outputf(outc,
444 ");\n");
445
446 outputf(outc,
447 "\tduk_set_top(ctx, 1);\n");
448 outputf(outc,
449 "\treturn 1;\n");
450 outputf(outc,
451 "}\n\n");
452
453 return 0;
454}
455
456
460static int
461output_interface_destructor(struct opctx *outc, struct ir_entry *interfacee)
462{
463 /* destructor definition */
464 outputf(outc,
465 "static duk_ret_t %s_%s___destructor(duk_context *ctx)\n",
466 DLPFX, interfacee->class_name);
467 outputf(outc,
468 "{\n");
469
470 output_safe_get_private(outc, interfacee->class_name, 0);
471
472 /* generate call to finaliser */
473 outputf(outc,
474 "\t%s_%s___fini(ctx, priv);\n",
475 DLPFX, interfacee->class_name);
476
477 outputf(outc,
478 "\tfree(priv);\n");
479 outputf(outc,
480 "\treturn 0;\n");
481
482 outputf(outc,
483 "}\n\n");
484
485 return 0;
486}
487
488
492static int
493output_interface_inherit_init(struct opctx *outc,
494 struct ir_entry *interfacee,
495 struct ir_entry *inherite)
496{
497 struct genbind_node *init_node;
498 struct genbind_node *inh_init_node;
499 struct genbind_node *param_node;
500 struct genbind_node *inh_param_node;
501
502 /* only need to call parent initialisor if there is one */
503 if (inherite == NULL) {
504 return 0;
505 }
506
507 /* find the initialisor method on the class (if any) */
508 init_node = genbind_node_find_method(interfacee->class,
509 NULL,
511
512
513 inh_init_node = genbind_node_find_method(inherite->class,
514 NULL,
516
517
518 outputf(outc,
519 "\t%s_%s___init(ctx, &priv->parent",
520 DLPFX, inherite->class_name);
521
522 /* for each parameter in the parent find a matching named
523 * parameter to pass and cast if necessary
524 */
525
526 inh_param_node = genbind_node_find_type(
527 genbind_node_getnode(inh_init_node),
529 while (inh_param_node != NULL) {
530 char *param_name;
531 param_name = genbind_node_gettext(
533 genbind_node_getnode(inh_param_node),
534 NULL,
536
537 param_node = genbind_node_find_type_ident(
538 genbind_node_getnode(init_node),
539 NULL,
541 param_name);
542 if (param_node == NULL) {
543 fprintf(stderr,
544 "class \"%s\" (interface %s) parent class \"%s\" (interface %s) initialisor requires a parameter \"%s\" with compatible identifier\n",
545 interfacee->class_name,
546 interfacee->name,
547 inherite->class_name,
548 inherite->name,
549 param_name);
550 return -1;
551 } else {
552 outputf(outc, ", ");
553
554 /* cast the parameter if required */
555 if (compare_ctypes(param_node,
556 inh_param_node) == false) {
557 outputc(outc, '(');
558 output_ctype(outc, inh_param_node, false);
559 outputc(outc, ')');
560 }
561
562 /* output the parameter identifier */
563 output_cdata(outc, param_node, GENBIND_NODE_TYPE_IDENT);
564 }
565
566 inh_param_node = genbind_node_find_type(
567 genbind_node_getnode(inh_init_node),
568 inh_param_node, GENBIND_NODE_TYPE_METHOD);
569 }
570
571 outputf(outc, ");\n");
572
573 return 0;
574}
575
576static enum ir_init_argtype
577guess_argtype_from(struct genbind_node *param_node)
578{
579 const char *type_cdata = NULL;
580 struct genbind_node *typename_node;
581 bool unsigned_ = false;
582 bool int_ = false;
583 bool bool_ = false;
584
585 typename_node = genbind_node_find_type(genbind_node_getnode(param_node),
586 NULL,
588 while (typename_node != NULL) {
589 type_cdata = genbind_node_gettext(typename_node);
590 if (strcmp(type_cdata, "unsigned") == 0) {
591 unsigned_ = true;
592 } else if (strcmp(type_cdata, "int") == 0) {
593 int_ = true;
594 } else if (strcmp(type_cdata, "bool") == 0) {
595 bool_ = true;
596 }
597 typename_node = genbind_node_find_type(
598 genbind_node_getnode(param_node),
599 typename_node,
601 }
602
603 if (type_cdata[0] == '*') {
604 return IR_INIT_ARG_POINTER;
605 } else if (unsigned_) {
607 } else if (int_) {
608 return IR_INIT_ARG_INT;
609 } else if (bool_) {
610 return IR_INIT_ARG_BOOL;
611 }
612
613 /* If we have no better idea do this */
614 return IR_INIT_ARG_POINTER;
615}
616
617static int
618output_interface_init_declaration(struct opctx *outc,
619 struct ir_entry *interfacee,
620 struct genbind_node *init_node)
621{
622 struct genbind_node *param_node;
623
624 if (interfacee->refcount == 0) {
625 outputf(outc, "static ");
626 }
627
628 outputf(outc,
629 "void %s_%s___init(duk_context *ctx, %s_private_t *priv",
630 DLPFX, interfacee->class_name, interfacee->class_name);
631
632 /* count the number of arguments on the initializer */
633 interfacee->class_init_argc = 0;
634 interfacee->class_init_argt = NULL;
635
636 /* output the paramters on the method (if any) */
637 param_node = genbind_node_find_type(
638 genbind_node_getnode(init_node),
640 while (param_node != NULL) {
641 interfacee->class_init_argc++;
642 interfacee->class_init_argt = realloc(interfacee->class_init_argt,
643 interfacee->class_init_argc * sizeof(enum ir_init_argtype));
644 interfacee->class_init_argt[interfacee->class_init_argc - 1] =
645 guess_argtype_from(param_node);
646 outputf(outc, ", ");
647
648 output_ctype(outc, param_node, true);
649
650 param_node = genbind_node_find_type(
651 genbind_node_getnode(init_node),
652 param_node, GENBIND_NODE_TYPE_PARAMETER);
653 }
654
655 outputc(outc, ')');
656
657 return 0;
658}
659
660
664static int
665output_interface_init(struct opctx *outc,
666 struct ir_entry *interfacee,
667 struct ir_entry *inherite)
668{
669 struct genbind_node *init_node;
670 int res;
671
672 /* find the initialisor method on the class (if any) */
673 init_node = genbind_node_find_method(interfacee->class,
674 NULL,
676
677 /* initialisor definition */
678 output_interface_init_declaration(outc, interfacee, init_node);
679
680 outputf(outc, "\n{\n");
681
682 /* if this interface inherits ensure we call its initialisor */
683 res = output_interface_inherit_init(outc, interfacee, inherite);
684 if (res != 0) {
685 return res;
686 }
687
688 /* generate log statement */
689 if (options->dbglog) {
690 outputf(outc,
691 "\tNSLOG(dukky, INFO, \"Initialise %%p (priv=%%p)\", duk_get_heapptr(ctx, 0), priv);\n" );
692 }
693
694 /* output the initaliser code from the binding */
695 output_ccode(outc, init_node);
696
697 outputf(outc, "}\n\n");
698
699 return 0;
700
701}
702
703
707static int
708output_interface_fini(struct opctx *outc,
709 struct ir_entry *interfacee,
710 struct ir_entry *inherite)
711{
712 struct genbind_node *fini_node;
713
714 /* find the finaliser method on the class (if any) */
715 fini_node = genbind_node_find_method(interfacee->class,
716 NULL,
718
719 /* finaliser definition */
720 if (interfacee->refcount == 0) {
721 outputf(outc, "static ");
722 }
723 outputf(outc,
724 "void %s_%s___fini(duk_context *ctx, %s_private_t *priv)\n",
725 DLPFX, interfacee->class_name, interfacee->class_name);
726 outputf(outc, "{\n");
727
728 /* generate log statement */
729 if (options->dbglog) {
730 outputf(outc,
731 "\tNSLOG(dukky, INFO, \"Finalise %%p\", duk_get_heapptr(ctx, 0));\n" );
732 }
733
734 /* output the finialisor code from the binding */
735 output_cdata(outc, fini_node, GENBIND_NODE_TYPE_CDATA);
736
737 /* if this interface inherits ensure we call its finaliser */
738 if (inherite != NULL) {
739 outputf(outc,
740 "\t%s_%s___fini(ctx, &priv->parent);\n",
741 DLPFX, inherite->class_name);
742 }
743 outputf(outc, "}\n\n");
744
745 return 0;
746}
747
748
752static int
753output_prototype_method(struct opctx *outc,
754 struct ir_entry *interfacee,
755 struct ir_operation_entry *operatione)
756{
757
758 if (operatione->name != NULL) {
759 /* normal method on prototype */
760 output_add_method(outc,
761 interfacee->class_name,
762 operatione->name);
763 } else {
764 /* special method on prototype */
765 outputf(outc,
766 "\t/* Special method on prototype - UNIMPLEMENTED */\n\n");
767 }
768
769 return 0;
770}
771
772
776static int
777output_prototype_methods(struct opctx *outc, struct ir_entry *entry)
778{
779 int opc;
780 int res = 0;
781
782 for (opc = 0; opc < entry->u.interface.operationc; opc++) {
783 res = output_prototype_method(
784 outc,
785 entry,
786 entry->u.interface.operationv + opc);
787 if (res != 0) {
788 break;
789 }
790 }
791
792 return res;
793}
794
795
796static int
797output_prototype_attribute(struct opctx *outc,
798 struct ir_entry *interfacee,
799 struct ir_attribute_entry *attributee)
800{
801 if ((attributee->putforwards == NULL) &&
802 (attributee->modifier == WEBIDL_TYPE_MODIFIER_READONLY)) {
803 return output_populate_ro_property(outc,
804 interfacee->class_name,
805 attributee->name);
806 }
807 return output_populate_rw_property(outc,
808 interfacee->class_name,
809 attributee->name);
810}
811
812
816static int
817output_prototype_attributes(struct opctx *outc, struct ir_entry *entry)
818{
819 int attrc;
820 int res = 0;
821
822 for (attrc = 0; attrc < entry->u.interface.attributec; attrc++) {
823 res = output_prototype_attribute(
824 outc,
825 entry,
826 entry->u.interface.attributev + attrc);
827 if (res != 0) {
828 break;
829 }
830 }
831
832 return res;
833}
834
835
842static int
843output_prototype_constant(struct opctx *outc,
844 struct ir_constant_entry *constante)
845{
846 int *value;
847
850 webidl_node_getnode(constante->node),
851 NULL,
853
854 output_prototype_constant_int(outc, constante->name, *value);
855
856 return 0;
857}
858
859
863static int
864output_prototype_constants(struct opctx *outc, struct ir_entry *entry)
865{
866 int attrc;
867 int res = 0;
868
869 for (attrc = 0; attrc < entry->u.interface.constantc; attrc++) {
870 res = output_prototype_constant(
871 outc,
872 entry->u.interface.constantv + attrc);
873 if (res != 0) {
874 break;
875 }
876 }
877
878 return res;
879}
880
881
882static int
883output_global_create_prototype(struct opctx *outc,
884 struct ir *ir,
885 struct ir_entry *interfacee)
886{
887 int idx;
888
889 outputf(outc,
890 "\t/* Create interface objects */\n");
891 for (idx = 0; idx < ir->entryc; idx++) {
892 struct ir_entry *entry;
893
894 entry = ir->entries + idx;
895
896 if (entry->type == IR_ENTRY_TYPE_INTERFACE) {
897
898 if (entry->u.interface.noobject) {
899 continue;
900 }
901
902 if (entry == interfacee) {
903 outputf(outc,
904 "\tduk_dup(ctx, 0);\n");
905 } else {
906 output_get_prototype(outc, entry->name);
907 }
908
909 outputf(outc,
910 "\tdukky_inject_not_ctr(ctx, 0, \"%s\");\n",
911 entry->name);
912 }
913 }
914 return 0;
915}
916
917
921static int
922output_interface_prototype(struct opctx *outc,
923 struct ir *ir,
924 struct ir_entry *interfacee,
925 struct ir_entry *inherite)
926{
927 struct genbind_node *proto_node;
928
929 /* find the prototype method on the class */
930 proto_node = genbind_node_find_method(interfacee->class,
931 NULL,
933
934 /* prototype definition */
935 outputf(outc,
936 "duk_ret_t %s_%s___proto(duk_context *ctx, void *udata)\n",
937 DLPFX, interfacee->class_name);
938 outputf(outc, "{\n");
939
940 /* Output any binding data first */
941 if (output_cdata(outc, proto_node, GENBIND_NODE_TYPE_CDATA) != 0) {
942 outputf(outc,
943 "\n");
944 }
945
946 /* generate prototype chaining if interface has a parent */
947 if (inherite != NULL) {
948 outputf(outc,
949 "\t/* Set this prototype's prototype (left-parent) */\n");
950 output_get_prototype(outc, inherite->name);
951 outputf(outc,
952 "\tduk_set_prototype(ctx, 0);\n\n");
953 }
954
955 /* generate setting of methods */
956 output_prototype_methods(outc, interfacee);
957
958 /* generate setting of attributes */
959 output_prototype_attributes(outc, interfacee);
960
961 /* generate setting of constants */
962 output_prototype_constants(outc, interfacee);
963
964 /* if this is the global object, output all interfaces which do not
965 * prevent us from doing so
966 */
967 if (interfacee->u.interface.primary_global) {
968 output_global_create_prototype(outc, ir, interfacee);
969 }
970
971 /* generate setting of destructor */
972 output_set_destructor(outc, interfacee->class_name, 0);
973
974 /* generate setting of constructor */
975 output_set_constructor(outc,
976 interfacee->class_name,
977 0,
978 interfacee->class_init_argc);
979
980 outputf(outc,
981 "\treturn 1; /* The prototype object */\n");
982
983 outputf(outc,
984 "}\n\n");
985
986 return 0;
987}
988
989
993static int
994output_interface_elipsis_operation(struct opctx *outc,
995 struct ir_entry *interfacee,
996 struct ir_operation_entry *operatione)
997{
998 int cdatac; /* cdata blocks output */
999
1000 /* overloaded method definition */
1001 outputf(outc,
1002 "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
1003 DLPFX, interfacee->class_name, operatione->name);
1004 outputf(outc,
1005 "{\n");
1006
1012 "Elipsis parameters not checked: method %s::%s();",
1013 interfacee->name, operatione->name);
1014
1015 output_get_method_private(outc, interfacee->class_name,
1016 interfacee->u.interface.primary_global);
1017
1018 cdatac = output_ccode(outc, operatione->method);
1019 if (cdatac == 0) {
1020 /* no implementation so generate default */
1022 "Unimplemented: method %s::%s();",
1023 interfacee->name, operatione->name);
1024 outputf(outc,
1025 "\treturn 0;\n");
1026 }
1027
1028 outputf(outc,
1029 "}\n\n");
1030
1031 return 0;
1032}
1033
1034
1038static int
1039output_interface_overloaded_operation(struct opctx *outc,
1040 struct ir_entry *interfacee,
1041 struct ir_operation_entry *operatione)
1042{
1043 int cdatac; /* cdata blocks output */
1044
1045 /* overloaded method definition */
1046 outputf(outc,
1047 "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
1048 DLPFX, interfacee->class_name, operatione->name);
1049 outputf(outc,
1050 "{\n");
1051
1056 output_get_method_private(outc, interfacee->class_name,
1057 interfacee->u.interface.primary_global);
1058
1059 cdatac = output_ccode(outc,
1060 operatione->method);
1061
1062 if (cdatac == 0) {
1063 /* no implementation so generate default */
1065 "Unimplemented: method %s::%s();",
1066 interfacee->name, operatione->name);
1067 outputf(outc,
1068 "\treturn 0;\n");
1069 }
1070
1071 outputf(outc,
1072 "}\n\n");
1073
1074 return 0;
1075}
1076
1077
1081static int
1082output_interface_special_operation(struct opctx *outc,
1083 struct ir_entry *interfacee,
1084 struct ir_operation_entry *operatione)
1085{
1086 /* special method definition */
1087 outputf(outc,
1088 "/* Special method definition - UNIMPLEMENTED */\n\n");
1089
1091 "Special operation on interface %s (operation entry %p)",
1092 interfacee->name,
1093 operatione);
1094
1095 return 0;
1096}
1097
1098
1102static int
1103output_operation_optional_defaults(
1104 struct opctx *outc,
1105 struct ir_operation_argument_entry *argumentv,
1106 int argumentc)
1107{
1108 int argc;
1109 for (argc = 0; argc < argumentc; argc++) {
1110 struct ir_operation_argument_entry *cure;
1111 struct webidl_node *lit_node; /* literal node */
1112 enum webidl_node_type lit_type;
1113 int *lit_int;
1114 char *lit_str;
1115
1116 cure = argumentv + argc;
1117
1118 lit_node = webidl_node_getnode(
1121 NULL,
1123
1124 if (lit_node != NULL) {
1125
1126 lit_type = webidl_node_gettype(lit_node);
1127
1128 switch (lit_type) {
1130 outputf(outc,
1131 "\t\tduk_push_null(ctx);\n");
1132 break;
1133
1135 lit_int = webidl_node_getint(lit_node);
1136 outputf(outc,
1137 "\t\tduk_push_int(ctx, %d);\n",
1138 *lit_int);
1139 break;
1140
1142 lit_int = webidl_node_getint(lit_node);
1143 outputf(outc,
1144 "\t\tduk_push_boolean(ctx, %d);\n",
1145 *lit_int);
1146 break;
1147
1149 lit_str = webidl_node_gettext(lit_node);
1150 outputf(outc,
1151 "\t\tduk_push_string(ctx, \"%s\");\n",
1152 lit_str);
1153 break;
1154
1156 default:
1157 outputf(outc,
1158 "\t\tduk_push_undefined(ctx);\n");
1159 break;
1160 }
1161 } else {
1162 outputf(outc,
1163 "\t\tduk_push_undefined(ctx);\n");
1164 }
1165 }
1166 return 0;
1167}
1168
1169
1170static int
1171output_operation_argument_type_check(
1172 struct opctx *outc,
1173 struct ir_entry *interfacee,
1174 struct ir_operation_entry *operatione,
1175 struct ir_operation_overload_entry *overloade,
1176 int argidx)
1177{
1178 struct ir_operation_argument_entry *argumente;
1179 struct webidl_node *type_node;
1180 enum webidl_type *argument_type;
1181
1182 argumente = overloade->argumentv + argidx;
1183
1184 type_node = webidl_node_find_type(
1185 webidl_node_getnode(argumente->node),
1186 NULL,
1188
1189 if (type_node == NULL) {
1190 fprintf(stderr, "%s:%s %dth argument %s has no type\n",
1191 interfacee->name,
1192 operatione->name,
1193 argidx,
1194 argumente->name);
1195 return -1;
1196 }
1197
1198 argument_type = (enum webidl_type *)webidl_node_getint(
1200 webidl_node_getnode(type_node),
1201 NULL,
1203
1204 if (argument_type == NULL) {
1205 fprintf(stderr,
1206 "%s:%s %dth argument %s has no type base\n",
1207 interfacee->name,
1208 operatione->name,
1209 argidx,
1210 argumente->name);
1211 return -1;
1212 }
1213
1214 if (*argument_type == WEBIDL_TYPE_ANY) {
1215 /* allowing any type needs no check */
1216 return 0;
1217 }
1218
1219 outputf(outc,
1220 "\tif (%s_argc > %d) {\n", DLPFX, argidx);
1221
1222 switch (*argument_type) {
1223 case WEBIDL_TYPE_STRING:
1224 /* coerce values to string */
1225 outputf(outc,
1226 "\t\tif (!duk_is_string(ctx, %d)) {\n"
1227 "\t\t\tduk_to_string(ctx, %d);\n"
1228 "\t\t}\n", argidx, argidx);
1229 break;
1230
1231 case WEBIDL_TYPE_BOOL:
1232 outputf(outc,
1233 "\t\tif (!duk_is_boolean(ctx, %d)) {\n"
1234 "\t\t\tif (duk_is_number(ctx, %d)) {\n"
1235 "\t\t\t\tduk_to_boolean(ctx, %d);\n"
1236 "\t\t\t} else {\n"
1237 "\t\t\t\treturn duk_error(ctx, DUK_ERR_ERROR, %s_error_fmt_bool_type, %d, \"%s\");\n"
1238 "\t\t\t}\n"
1239 "\t\t}\n", argidx, argidx, argidx, DLPFX, argidx, argumente->name);
1240 break;
1241
1242 case WEBIDL_TYPE_FLOAT:
1243 case WEBIDL_TYPE_DOUBLE:
1244 case WEBIDL_TYPE_SHORT:
1245 case WEBIDL_TYPE_LONG:
1247 outputf(outc,
1248 "\t\tif (!duk_is_number(ctx, %d)) {\n"
1249 "\t\t\treturn duk_error(ctx, DUK_ERR_ERROR, %s_error_fmt_number_type, %d, \"%s\");\n"
1250 "\t\t}\n",
1251 argidx, DLPFX, argidx, argumente->name);
1252 break;
1253
1254
1255 default:
1256 outputf(outc,
1257 "\t\t/* unhandled type check */\n");
1258 }
1259
1260 outputf(outc,
1261 "\t}\n");
1262
1263 return 0;
1264}
1265
1266
1270static int
1271output_interface_operation(struct opctx *outc,
1272 struct ir_entry *interfacee,
1273 struct ir_operation_entry *operatione)
1274{
1275 int cdatac; /* cdata blocks output */
1276 struct ir_operation_overload_entry *overloade;
1277 int fixedargc; /* number of non optional arguments */
1278 int argidx; /* loop counter for arguments */
1279 int optargc; /* loop counter for optional arguments */
1280
1281 if (operatione->name == NULL) {
1282 return output_interface_special_operation(outc,
1283 interfacee,
1284 operatione);
1285 }
1286
1287 if (operatione->overloadc != 1) {
1288 return output_interface_overloaded_operation(outc,
1289 interfacee,
1290 operatione);
1291 }
1292
1293 if (operatione->overloadv->elipsisc != 0) {
1294 return output_interface_elipsis_operation(outc,
1295 interfacee,
1296 operatione);
1297 }
1298
1299 /* normal method definition */
1300 overloade = operatione->overloadv;
1301
1302 outputf(outc,
1303 "static duk_ret_t %s_%s_%s(duk_context *ctx)\n",
1304 DLPFX, interfacee->class_name, operatione->name);
1305 outputf(outc,
1306 "{\n");
1307
1308 /* check arguments */
1309
1310 /* generate check for minimum number of parameters */
1311
1312 fixedargc = overloade->argumentc - overloade->optionalc;
1313
1314 outputf(outc,
1315 "\t/* ensure the parameters are present */\n"
1316 "\tduk_idx_t %s_argc = duk_get_top(ctx);\n\t", DLPFX);
1317
1318 if (fixedargc > 0) {
1319 outputf(outc,
1320 "if (%s_argc < %d) {\n",
1321 DLPFX, fixedargc);
1322 outputf(outc,
1323 "\t\t/* not enough arguments */\n");
1324 outputf(outc,
1325 "\t\treturn duk_error(ctx, DUK_RET_TYPE_ERROR, %s_error_fmt_argument, %d, %s_argc);\n",
1326 DLPFX, fixedargc, DLPFX);
1327 outputf(outc,
1328 "\t} else ");
1329 }
1330
1331 for (optargc = fixedargc;
1332 optargc < overloade->argumentc;
1333 optargc++) {
1334 outputf(outc,
1335 "if (%s_argc == %d) {\n"
1336 "\t\t/* %d optional arguments need adding */\n",
1337 DLPFX,
1338 optargc,
1339 overloade->argumentc - optargc);
1340 output_operation_optional_defaults(outc,
1341 overloade->argumentv + optargc,
1342 overloade->argumentc - optargc);
1343 outputf(outc,
1344 "\t} else ");
1345 }
1346
1347 outputf(outc,
1348 "if (%s_argc > %d) {\n"
1349 "\t\t/* remove extraneous parameters */\n"
1350 "\t\tduk_set_top(ctx, %d);\n"
1351 "\t}\n",
1352 DLPFX,
1353 overloade->argumentc,
1354 overloade->argumentc);
1355 outputf(outc,
1356 "\n");
1357
1358 /* generate argument type checks */
1359
1360 outputf(outc,
1361 "\t/* check types of passed arguments are correct */\n");
1362
1363 for (argidx = 0; argidx < overloade->argumentc; argidx++) {
1364 output_operation_argument_type_check(outc,
1365 interfacee,
1366 operatione,
1367 overloade,
1368 argidx);
1369 }
1370
1371 output_get_method_private(outc, interfacee->class_name,
1372 interfacee->u.interface.primary_global);
1373
1374 cdatac = output_ccode(outc, operatione->method);
1375 if (cdatac == 0) {
1376 /* no implementation so generate default */
1378 "Unimplemented: method %s::%s();",
1379 interfacee->name, operatione->name);
1380
1381 if (options->dbglog) {
1382 outputf(outc,
1383 "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n");
1384 }
1385
1386 outputf(outc,
1387 "\treturn 0;\n");
1388 }
1389
1390 outputf(outc,
1391 "}\n\n");
1392
1393 return 0;
1394}
1395
1399static int
1400output_interface_operations(struct opctx *outc, struct ir_entry *ife)
1401{
1402 int opc;
1403 int res = 0;
1404
1405 for (opc = 0; opc < ife->u.interface.operationc; opc++) {
1406 res = output_interface_operation(
1407 outc,
1408 ife,
1409 ife->u.interface.operationv + opc);
1410 if (res != 0) {
1411 break;
1412 }
1413 }
1414
1415 return res;
1416}
1417
1418
1419
1423static int
1424output_attribute_getter(struct opctx *outc,
1425 struct ir_entry *interfacee,
1426 struct ir_attribute_entry *atributee)
1427{
1428 /* getter definition */
1429 outputf(outc,
1430 "static duk_ret_t %s_%s_%s_getter(duk_context *ctx)\n",
1431 DLPFX, interfacee->class_name, atributee->name);
1432 outputf(outc,
1433 "{\n");
1434
1435 output_get_method_private(outc,
1436 interfacee->class_name,
1437 interfacee->u.interface.primary_global);
1438
1439 /* if binding available for this attribute getter process it */
1440 if (atributee->getter != NULL) {
1441 int res;
1442 res = output_ccode(outc, atributee->getter);
1443 if (res == 0) {
1444 /* no code provided for this getter so generate */
1446 interfacee,
1447 atributee);
1448 }
1449 if (res >= 0) {
1450 outputf(outc,
1451 "}\n\n");
1452 return res;
1453 }
1454 }
1455
1456 /* no implementation so generate default and warnings if required */
1457 const char *type_str;
1458 if (atributee->typec == 0) {
1459 type_str = "";
1460 } else if (atributee->typec == 1) {
1461 type_str = webidl_type_to_str(atributee->typev[0].modifier,
1462 atributee->typev[0].base);
1463 } else {
1464 type_str = "multiple";
1465 }
1466
1468 "Unimplemented: getter %s::%s(%s);",
1469 interfacee->name,
1470 atributee->name,
1471 type_str);
1472
1473 if (options->dbglog) {
1474 outputf(outc,
1475 "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n" );
1476 }
1477
1478 outputf(outc,
1479 "\treturn 0;\n"
1480 "}\n\n");
1481
1482 return 0;
1483}
1484
1485
1489static int
1490output_putforwards_setter(struct opctx *outc,
1491 struct ir_entry *interfacee,
1492 struct ir_attribute_entry *atributee)
1493{
1494 /* generate autogenerated putforwards */
1495
1496 outputf(outc,
1497 "\tduk_ret_t get_ret;\n\n");
1498
1499 outputf(outc,
1500 "\tget_ret = %s_%s_%s_getter(ctx);\n",
1501 DLPFX, interfacee->class_name, atributee->name);
1502
1503 outputf(outc,
1504 "\tif (get_ret != 1) {\n"
1505 "\t\treturn 0;\n"
1506 "\t}\n\n"
1507 "\t/* parameter ... attribute */\n\n"
1508 "\tduk_dup(ctx, 0);\n"
1509 "\t/* ... attribute parameter */\n\n"
1510 "\t/* call the putforward */\n");
1511
1512 outputf(outc,
1513 "\tduk_put_prop_string(ctx, -2, \"%s\");\n\n",
1514 atributee->putforwards);
1515
1516 outputf(outc,
1517 "\treturn 0;\n");
1518
1519 return 0;
1520}
1521
1522
1526static int
1527output_attribute_setter(struct opctx *outc,
1528 struct ir_entry *interfacee,
1529 struct ir_attribute_entry *atributee)
1530{
1531 int res = -1;
1532
1533 /* setter definition */
1534 outputf(outc,
1535 "static duk_ret_t %s_%s_%s_setter(duk_context *ctx)\n",
1536 DLPFX, interfacee->class_name, atributee->name);
1537 outputf(outc,
1538 "{\n");
1539
1540 output_get_method_private(outc,
1541 interfacee->class_name,
1542 interfacee->u.interface.primary_global);
1543
1544 /* if binding available for this attribute getter process it */
1545 if (atributee->setter != NULL) {
1546 res = output_ccode(outc, atributee->setter);
1547 if (res == 0) {
1548 /* no code provided for this setter so generate */
1550 interfacee,
1551 atributee);
1552 }
1553 } else if (atributee->putforwards != NULL) {
1554 res = output_putforwards_setter(outc,
1555 interfacee,
1556 atributee);
1557 }
1558
1559 /* implementation not generated from any other source */
1560 if (res < 0) {
1561 const char *type_str;
1562 if (atributee->typec == 0) {
1563 type_str = "";
1564 } else if (atributee->typec == 1) {
1565 type_str = webidl_type_to_str(
1566 atributee->typev[0].modifier,
1567 atributee->typev[0].base);
1568 } else {
1569 type_str = "multiple";
1570 }
1572 "Unimplemented: setter %s::%s(%s);",
1573 interfacee->name,
1574 atributee->name,
1575 type_str);
1576 if (options->dbglog) {
1577 outputf(outc,
1578 "\tNSLOG(dukky, WARNING, \"Unimplemented\");\n");
1579 }
1580
1581 /* no implementation so generate default */
1582 outputf(outc,
1583 "\treturn 0;\n");
1584 }
1585
1586 outputf(outc,
1587 "}\n\n");
1588
1589 return res;
1590}
1591
1592
1596static int
1597output_interface_attribute(struct opctx *outc,
1598 struct ir_entry *interfacee,
1599 struct ir_attribute_entry *atributee)
1600{
1601 int res;
1602
1603 if (atributee->property_name == NULL) {
1604 atributee->property_name = gen_idl2c_name(atributee->name);
1605 }
1606
1607 res = output_attribute_getter(outc, interfacee, atributee);
1608
1609 /* only read/write and putforward attributes have a setter */
1610 if ((atributee->modifier != WEBIDL_TYPE_MODIFIER_READONLY) ||
1611 (atributee->putforwards != NULL)) {
1612 res = output_attribute_setter(outc, interfacee, atributee);
1613 }
1614
1615 return res;
1616}
1617
1618
1622static int
1623output_interface_attributes(struct opctx *outc, struct ir_entry *ife)
1624{
1625 int attrc;
1626
1627 for (attrc = 0; attrc < ife->u.interface.attributec; attrc++) {
1628 output_interface_attribute(
1629 outc,
1630 ife,
1631 ife->u.interface.attributev + attrc);
1632 }
1633
1634 return 0;
1635}
1636
1637
1638/*
1639 * generate a source file to implement an interface using duk and libdom.
1640 *
1641 * exported interface documented in duk-libdom.h
1642 */
1643int output_interface(struct ir *ir, struct ir_entry *interfacee)
1644{
1645 struct opctx *ifop;
1646 struct ir_entry *inherite;
1647 int res = 0;
1648
1649 /* open the output */
1650 res = output_open(interfacee->filename, &ifop);
1651 if (res !=0 ) {
1652 return res;
1653 }
1654
1655 /* find parent interface entry */
1656 inherite = ir_inherit_entry(ir, interfacee);
1657
1658 /* tool preface */
1659 output_tool_preface(ifop);
1660
1661 /* binding preface */
1665
1666 /* class preface */
1668 interfacee->class,
1670
1671 /* tool prologue */
1673
1674 /* binding prologue */
1678
1679 /* class prologue */
1681 interfacee->class,
1683
1684 outputf(ifop,
1685 "\n");
1686
1687 /* initialisor */
1688 res = output_interface_init(ifop, interfacee, inherite);
1689 if (res != 0) {
1690 goto op_error;
1691 }
1692
1693 /* finaliser */
1694 output_interface_fini(ifop, interfacee, inherite);
1695
1696 /* constructor */
1697 output_interface_constructor(ifop, interfacee);
1698
1699 /* destructor */
1700 output_interface_destructor(ifop, interfacee);
1701
1702 /* operations */
1703 output_interface_operations(ifop, interfacee);
1704
1705 /* attributes */
1706 output_interface_attributes(ifop, interfacee);
1707
1708 /* prototype */
1709 output_interface_prototype(ifop, ir, interfacee, inherite);
1710
1711 outputf(ifop, "\n");
1712
1713 /* class epilogue */
1715 interfacee->class,
1717
1718 /* binding epilogue */
1722
1723 /* class postface */
1725 interfacee->class,
1727
1728 /* binding postface */
1732
1733op_error:
1734 output_close(ifop);
1735
1736 return res;
1737}
1738
1739
1740/* exported function documented in duk-libdom.h */
1741int
1742output_interface_declaration(struct opctx *outc, struct ir_entry *interfacee)
1743{
1744 struct genbind_node *init_node;
1745
1746 /* do not generate prototype declarations for interfaces marked no
1747 * output
1748 */
1749 if (interfacee->u.interface.noobject) {
1750 return 0;
1751 }
1752
1753 /* prototype declaration */
1754 outputf(outc,
1755 "duk_ret_t %s_%s___proto(duk_context *ctx, void *udata);\n",
1756 DLPFX, interfacee->class_name);
1757
1758 /* if the interface has no references (no other interface inherits from
1759 * it) there is no reason to export the initalisor/finaliser as no
1760 * other class constructor/destructor should call them.
1761 */
1762 if (interfacee->refcount < 1) {
1763 outputf(outc,
1764 "\n");
1765 return 0;
1766 }
1767
1768 /* finaliser declaration */
1769 outputf(outc,
1770 "void %s_%s___fini(duk_context *ctx, %s_private_t *priv);\n",
1771 DLPFX, interfacee->class_name, interfacee->class_name);
1772
1773 /* find the initialisor method on the class (if any) */
1774 init_node = genbind_node_find_method(interfacee->class,
1775 NULL,
1777
1778 /* initialisor definition */
1779 output_interface_init_declaration(outc, interfacee, init_node);
1780
1781 outputf(outc,
1782 ";\n\n");
1783
1784 return 0;
1785}
int output_method_cdata(struct opctx *outc, struct genbind_node *node, enum genbind_method_type sel_method_type)
int output_cdata(struct opctx *outc, struct genbind_node *node, enum genbind_node_type nodetype)
int output_tool_prologue(struct opctx *outc)
int output_ccode(struct opctx *outc, struct genbind_node *node)
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_generated_attribute_setter(struct opctx *outc, struct ir_entry *interfacee, struct ir_attribute_entry *atributee)
int output_generated_attribute_getter(struct opctx *outc, struct ir_entry *interfacee, struct ir_attribute_entry *atributee)
int output_interface_declaration(struct opctx *outc, struct ir_entry *interfacee)
#define DLPFX
int output_interface(struct ir *ir, struct ir_entry *interfacee)
#define MAGICPFX
struct ir_entry * ir_inherit_entry(struct ir *map, struct ir_entry *entry)
Definition ir.c:1227
ir_init_argtype
Definition ir.h:126
@ IR_INIT_ARG_INT
Definition ir.h:129
@ IR_INIT_ARG_UNSIGNED
Definition ir.h:128
@ IR_INIT_ARG_POINTER
Definition ir.h:127
@ IR_INIT_ARG_BOOL
Definition ir.h:130
@ IR_ENTRY_TYPE_INTERFACE
Definition ir.h:122
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_find_type_ident(struct genbind_node *node, struct genbind_node *prev, enum genbind_node_type type, const char *ident)
struct genbind_node * genbind_node_find_method(struct genbind_node *node, struct genbind_node *prev, enum genbind_method_type methodtype)
struct genbind_node * genbind_node_getnode(struct genbind_node *node)
char * genbind_node_gettext(struct genbind_node *node)
@ GENBIND_METHOD_TYPE_INIT
@ GENBIND_METHOD_TYPE_PREFACE
@ GENBIND_METHOD_TYPE_PROLOGUE
@ GENBIND_METHOD_TYPE_POSTFACE
@ GENBIND_METHOD_TYPE_PROTOTYPE
@ GENBIND_METHOD_TYPE_EPILOGUE
@ GENBIND_METHOD_TYPE_FINI
@ GENBIND_NODE_TYPE_PARAMETER
@ GENBIND_NODE_TYPE_NAME
@ GENBIND_NODE_TYPE_METHOD
@ GENBIND_NODE_TYPE_IDENT
@ GENBIND_NODE_TYPE_CDATA
void * malloc(YYSIZE_T)
void free(void *)
@ WARNING_UNIMPLEMENTED
Definition options.h:29
#define WARN(flags, msg, args...)
Definition options.h:37
int outputc(struct opctx *opctx, int c)
Definition output.c:88
int outputf(struct opctx *opctx, const char *fmt,...)
Definition output.c:66
int output_close(struct opctx *opctx)
Definition output.c:52
int output_open(const char *filename, struct opctx **opctx_out)
Definition output.c:23
Definition ir.h:63
enum webidl_type_modifier modifier
Definition ir.h:70
struct ir_type_entry * typev
Definition ir.h:68
int typec
Definition ir.h:67
struct genbind_node * setter
Definition ir.h:75
const char * putforwards
Definition ir.h:71
char * property_name
Definition ir.h:77
const char * name
Definition ir.h:64
struct genbind_node * getter
Definition ir.h:74
Definition ir.h:87
const char * name
Definition ir.h:88
struct webidl_node * node
Definition ir.h:89
Definition ir.h:134
char * filename
Definition ir.h:158
enum ir_init_argtype * class_init_argt
Definition ir.h:168
char * class_name
Definition ir.h:160
int class_init_argc
Definition ir.h:165
struct genbind_node * class
Definition ir.h:138
int refcount
Definition ir.h:149
enum ir_entry_type type
Definition ir.h:140
const char * name
Definition ir.h:135
struct ir_interface_entry interface
Definition ir.h:143
union ir_entry::@2 u
struct ir_attribute_entry * attributev
Definition ir.h:107
struct ir_operation_entry * operationv
Definition ir.h:104
int attributec
Definition ir.h:106
int constantc
Definition ir.h:109
bool noobject
Definition ir.h:95
struct ir_constant_entry * constantv
Definition ir.h:110
int operationc
Definition ir.h:103
bool primary_global
Definition ir.h:99
Definition ir.h:18
struct webidl_node * node
Definition ir.h:24
const char * name
Definition ir.h:19
Definition ir.h:41
const char * name
Definition ir.h:42
struct ir_operation_overload_entry * overloadv
Definition ir.h:47
int overloadc
Definition ir.h:46
struct genbind_node * method
Definition ir.h:44
Definition ir.h:30
int elipsisc
Definition ir.h:34
int optionalc
Definition ir.h:33
struct ir_operation_argument_entry * argumentv
Definition ir.h:37
int argumentc
Definition ir.h:36
enum webidl_type_modifier modifier
Definition ir.h:55
enum webidl_type base
Definition ir.h:54
Definition ir.h:172
struct genbind_node * binding_node
Definition ir.h:177
int entryc
Definition ir.h:173
struct ir_entry * entries
Definition ir.h:174
Definition output.c:17
bool dbglog
Definition options.h:20
#define SLEN(s)
Definition utils.h:46
struct webidl_node * webidl_node_getnode(struct webidl_node *node)
Definition webidl-ast.c:335
char * webidl_node_gettext(struct webidl_node *node)
Definition webidl-ast.c:273
const char * webidl_type_to_str(enum webidl_type_modifier m, enum webidl_type t)
Definition webidl-ast.c:788
int * webidl_node_getint(struct webidl_node *node)
Definition webidl-ast.c:293
enum webidl_node_type webidl_node_gettype(struct webidl_node *node)
Definition webidl-ast.c:328
struct webidl_node * webidl_node_find_type(struct webidl_node *node, struct webidl_node *prev, enum webidl_node_type type)
Definition webidl-ast.c:233
webidl_type
Definition webidl-ast.h:51
@ WEBIDL_TYPE_DOUBLE
Definition webidl-ast.h:58
@ WEBIDL_TYPE_SHORT
Definition webidl-ast.h:59
@ WEBIDL_TYPE_STRING
Definition webidl-ast.h:62
@ WEBIDL_TYPE_ANY
Definition webidl-ast.h:52
@ WEBIDL_TYPE_BOOL
Definition webidl-ast.h:54
@ WEBIDL_TYPE_LONGLONG
Definition webidl-ast.h:61
@ WEBIDL_TYPE_LONG
Definition webidl-ast.h:60
@ WEBIDL_TYPE_FLOAT
Definition webidl-ast.h:57
webidl_node_type
Definition webidl-ast.h:12
@ WEBIDL_NODE_TYPE_LITERAL_STRING
Definition webidl-ast.h:45
@ WEBIDL_NODE_TYPE_TYPE_BASE
Definition webidl-ast.h:37
@ WEBIDL_NODE_TYPE_LITERAL_NULL
Definition webidl-ast.h:41
@ WEBIDL_NODE_TYPE_TYPE
Definition webidl-ast.h:36
@ WEBIDL_NODE_TYPE_OPTIONAL
Definition webidl-ast.h:34
@ WEBIDL_NODE_TYPE_LITERAL_BOOL
Definition webidl-ast.h:43
@ WEBIDL_NODE_TYPE_LITERAL_INT
Definition webidl-ast.h:42
@ WEBIDL_NODE_TYPE_LITERAL_FLOAT
Definition webidl-ast.h:44
@ WEBIDL_TYPE_MODIFIER_READONLY
Definition webidl-ast.h:74