nsgenbind
Loading...
Searching...
No Matches
ir.c
Go to the documentation of this file.
1/* intermediate representation of WebIDL and binding data
2 *
3 * This file is part of nsgenbind.
4 * Published under the MIT License,
5 * http://www.opensource.org/licenses/mit-license.php
6 * Copyright 2015 Vincent Sanders <vince@netsurf-browser.org>
7 */
8
9#include <stdbool.h>
10#include <stdio.h>
11#include <errno.h>
12#include <string.h>
13#include <stdlib.h>
14#include <ctype.h>
15
16#include "options.h"
17#include "utils.h"
18#include "nsgenbind-ast.h"
19#include "webidl-ast.h"
20#include "ir.h"
21
23static int
24enumerate_interface_type(struct webidl_node *interface_node,
25 enum webidl_node_type node_type)
26{
27 int count = 0;
28 struct webidl_node *members_node;
29
30 members_node = webidl_node_find_type(
31 webidl_node_getnode(interface_node),
32 NULL,
34 while (members_node != NULL) {
36 webidl_node_getnode(members_node),
37 node_type);
38
39 members_node = webidl_node_find_type(
40 webidl_node_getnode(interface_node),
41 members_node,
43 }
44
45 return count;
46}
47
48/* find index of inherited node if it is one of those listed in the
49 * binding also maintain refcounts
50 */
51static void
52compute_inherit_refcount(struct ir_entry *entries, int entryc)
53{
54 int idx;
55 int inf;
56
57 for (idx = 0; idx < entryc; idx++ ) {
58 entries[idx].inherit_idx = -1;
59 for (inf = 0; inf < entryc; inf++ ) {
60 /* cannot inherit from self and name must match */
61 if ((inf != idx) &&
62 (entries[idx].inherit_name != NULL ) &&
63 (strcmp(entries[idx].inherit_name,
64 entries[inf].name) == 0)) {
65 entries[idx].inherit_idx = inf;
66 entries[inf].refcount++;
67 break;
68 }
69 }
70 }
71}
72
84static struct ir_entry *
85entry_topoligical_sort(struct ir_entry *srcinf, int infc)
86{
87 struct ir_entry *dstinf;
88 int idx;
89 int inf;
90
91 dstinf = calloc(infc, sizeof(struct ir_entry));
92 if (dstinf == NULL) {
93 return NULL;
94 }
95
96 for (idx = infc - 1; idx >= 0; idx--) {
97 /* walk source map until first valid entry with zero refcount */
98 inf = 0;
99 while ((inf < infc) &&
100 ((srcinf[inf].name == NULL) ||
101 (srcinf[inf].refcount > 0))) {
102 inf++;
103 }
104 if (inf == infc) {
105 free(dstinf);
106 return NULL;
107 }
108
109 /* copy entry to the end of the output map */
110 dstinf[idx].name = srcinf[inf].name;
111 dstinf[idx].node = srcinf[inf].node;
112 dstinf[idx].inherit_name = srcinf[inf].inherit_name;
113 dstinf[idx].class = srcinf[inf].class;
114 dstinf[idx].type = srcinf[inf].type;
115 dstinf[idx].u = srcinf[inf].u;
116
117 /* reduce refcount on inherit index if !=-1 */
118 if (srcinf[inf].inherit_idx != -1) {
119 srcinf[srcinf[inf].inherit_idx].refcount--;
120 }
121
122 /* remove entry from source map */
123 srcinf[inf].name = NULL;
124 }
125
126 return dstinf;
127}
128
129static struct ir_operation_entry *
130find_operation_name(struct ir_operation_entry *operationv,
131 int operationc,
132 const char *name)
133{
134 struct ir_operation_entry *cure;
135 int opc;
136
137 for (opc = 0; opc < operationc; opc++) {
138 cure = operationv + opc;
139
140 if (cure->name == name) {
141 /* check pointers for equivalence */
142 return cure;
143 } else {
144 if ((cure->name != NULL) &&
145 (name != NULL) &&
146 (strcmp(cure->name, name) == 0)) {
147 return cure;
148 }
149 }
150 }
151
152 return NULL;
153}
154
155static int
156argument_map_new(struct webidl_node *arg_list_node,
157 int *argumentc_out,
158 struct ir_operation_argument_entry **argumentv_out)
159{
160 int argumentc;
161 struct webidl_node *argument;
162 struct ir_operation_argument_entry *argumentv;
163 struct ir_operation_argument_entry *cure;
164
165 argumentc = webidl_node_enumerate_type(
166 webidl_node_getnode(arg_list_node),
168 if (argumentc == 0) {
169 *argumentc_out = 0;
170 *argumentv_out = NULL;
171 return 0;
172 }
173
174 argumentv = calloc(argumentc, sizeof(*argumentv));
175 cure = argumentv;
176
177 /* iterate each argument node within the list */
178 argument = webidl_node_find_type(webidl_node_getnode(arg_list_node),
179 NULL,
181
182 while (argument != NULL) {
183
186 webidl_node_getnode(argument),
187 NULL,
189
190 cure->node = argument;
191
193 webidl_node_getnode(argument),
195
197 webidl_node_getnode(argument),
199
200 cure++;
201
202 argument = webidl_node_find_type(
203 webidl_node_getnode(arg_list_node),
204 argument,
206 }
207
208 *argumentc_out = argumentc;
209 *argumentv_out = argumentv;
210
211 return 0;
212}
213
221static int
222overload_map_new(struct webidl_node *op_node,
223 int *overloadc_out,
224 struct ir_operation_overload_entry **overloadv_out)
225{
226 int overloadc = *overloadc_out;
227 struct ir_operation_overload_entry *overloadv;
228 struct ir_operation_overload_entry *cure;
229 struct webidl_node *arg_list_node;
230 int argc;
231
232 /* update allocation */
233 overloadc++;
234 overloadv = realloc(*overloadv_out, overloadc * sizeof(*overloadv));
235 if (overloadv == NULL) {
236 return -1;
237 }
238
239 /* get added entry */
240 cure = overloadv + (overloadc - 1);
241
242 /* clear entry */
243 cure = memset(cure, 0, sizeof(*cure));
244
245 /* return type */
246 cure->type = webidl_node_find_type(webidl_node_getnode(op_node),
247 NULL,
249
250 arg_list_node = webidl_node_find_type(webidl_node_getnode(op_node),
251 NULL,
253 if (arg_list_node != NULL) {
254 argument_map_new(arg_list_node,
255 &cure->argumentc,
256 &cure->argumentv);
257 }
258
259 for (argc = 0; argc < cure->argumentc; argc++) {
260 struct ir_operation_argument_entry *arge;
261 arge = cure->argumentv + argc;
262 cure->optionalc += arge->optionalc;
263 cure->elipsisc += arge->elipsisc;
264 }
265
266 /* return entry list */
267 *overloadc_out = overloadc;
268 *overloadv_out = overloadv;
269
270 return 0;
271}
272
273static int
274operation_map_new(struct webidl_node *interface,
275 struct genbind_node *class,
276 int *operationc_out,
277 struct ir_operation_entry **operationv_out)
278{
279 struct webidl_node *list_node;
280 struct webidl_node *op_node; /* attribute node */
281 struct ir_operation_entry *cure; /* current entry */
282 struct ir_operation_entry *operationv;
283 int operationc;
284
285 /* enumerate operationss including overloaded members */
286 operationc = enumerate_interface_type(interface,
288
289 if (operationc < 1) {
290 /* no operations so empty map */
291 *operationc_out = 0;
292 *operationv_out = NULL;
293 return 0;
294 }
295
296 operationv = calloc(operationc,
297 sizeof(struct ir_operation_entry));
298 if (operationv == NULL) {
299 return -1;
300 };
301 cure = operationv;
302
303 /* iterate each list node within the interface */
304 list_node = webidl_node_find_type(
305 webidl_node_getnode(interface),
306 NULL,
308
309 while (list_node != NULL) {
310 /* iterate through operations on list */
311 op_node = webidl_node_find_type(
312 webidl_node_getnode(list_node),
313 NULL,
315
316 while (op_node != NULL) {
317 const char *operation_name;
318 struct ir_operation_entry *finde;
319
320 /* get operation name */
321 operation_name = webidl_node_gettext(
323 webidl_node_getnode(op_node),
324 NULL,
326 /* if this operation is already an entry in the list
327 * augment that entry else create a new one
328 */
329 finde = find_operation_name(operationv,
330 operationc,
331 operation_name);
332 if (finde == NULL) {
333 /* operation does not already exist in list */
334
335 cure->name = operation_name;
336
337 cure->node = op_node;
338
340 class,
341 NULL,
343 cure->name);
344
345 overload_map_new(op_node,
346 &cure->overloadc,
347 &cure->overloadv);
348
349 cure++; /* advance to next entry */
350 } else {
351 overload_map_new(op_node,
352 &finde->overloadc,
353 &finde->overloadv);
354 /* Overloaded entry does not advance the
355 * current entry but does reduce list
356 * length. Do not bother shortening allocation.
357 */
358 operationc--;
359 }
360
361 /* move to next operation */
362 op_node = webidl_node_find_type(
363 webidl_node_getnode(list_node),
364 op_node,
366 }
367
368 list_node = webidl_node_find_type(
369 webidl_node_getnode(interface),
370 list_node,
372 }
373
374 *operationc_out = operationc;
375 *operationv_out = operationv; /* resulting operations map */
376
377 return 0;
378}
379
383static char *
384get_extended_value(struct webidl_node *node, const char *key)
385{
386 char *ident;
387 struct webidl_node *ext_attr;
388 struct webidl_node *elem;
389
390 /* walk each extended attribute */
391 ext_attr = webidl_node_find_type(
393 NULL,
395 while (ext_attr != NULL) {
396
398 webidl_node_getnode(ext_attr),
399 NULL,
401 ident = webidl_node_gettext(elem);
402
403 if ((ident != NULL) && (strcmp(ident, key) == 0)) {
404 /* first identifier matches */
405
407 webidl_node_getnode(ext_attr),
408 elem,
410 ident = webidl_node_gettext(elem);
411
412 if ((ident != NULL) && (*ident == '=')) {
413 return webidl_node_gettext(
415 webidl_node_getnode(ext_attr),
416 elem,
418 }
419 }
420
421 ext_attr = webidl_node_find_type(
423 ext_attr,
425 }
426
427 return NULL;
428}
429
430
434static int
435type_map_new(struct webidl_node *node,
436 int *typec_out,
437 struct ir_type_entry **typev_out)
438{
439 int typec;
440 struct webidl_node *type_node;
441 struct ir_type_entry *typev;
442 struct ir_type_entry *cure;
443
447 if (typec == 0) {
448 *typec_out = 0;
449 *typev_out = NULL;
450 return 0;
451 }
452
453 typev = calloc(typec, sizeof(*typev));
454 cure = typev;
455
457 NULL,
459
460 while (type_node != NULL) {
461 enum webidl_type *base;
463
464 /* type base */
467 webidl_node_getnode(type_node),
468 NULL,
470 if (base != NULL) {
471 cure->base = *base;
472 }
473
474 /* type modifier */
477 webidl_node_getnode(type_node),
478 NULL,
480 if (modifier != NULL) {
481 cure->modifier = *modifier;
482 } else {
484 }
485
486 /* type nullability */
488 webidl_node_getnode(type_node),
489 NULL,
491
492 /* type name */
495 webidl_node_getnode(type_node),
496 NULL,
498
499 /* next entry */
500 cure++;
501
502 type_node = webidl_node_find_type(
504 type_node,
506 }
507
508 *typec_out = typec;
509 *typev_out = typev;
510
511 return 0;
512}
513
517static int
518attribute_map_new(struct webidl_node *interface,
519 struct genbind_node *class,
520 int *attributec_out,
521 struct ir_attribute_entry **attributev_out)
522{
523 struct webidl_node *list_node;
524 struct webidl_node *at_node; /* attribute node */
525 struct ir_attribute_entry *cure; /* current entry */
526 struct ir_attribute_entry *attributev;
527 int attributec;
528
529 /* enumerate attributes */
530 attributec = enumerate_interface_type(interface,
532 *attributec_out = attributec;
533
534 if (attributec < 1) {
535 *attributev_out = NULL; /* no attributes so empty map */
536 return 0;
537 }
538
539 attributev = calloc(attributec, sizeof(struct ir_attribute_entry));
540 if (attributev == NULL) {
541 return -1;
542 };
543 cure = attributev;
544
545 /* iterate each list node within the interface */
546 list_node = webidl_node_find_type(
547 webidl_node_getnode(interface),
548 NULL,
550
551 while (list_node != NULL) {
552 /* iterate through attributes on list */
553 at_node = webidl_node_find_type(
554 webidl_node_getnode(list_node),
555 NULL,
557
558 while (at_node != NULL) {
559 /* process attribute node into an entry */
560
562
563 cure->node = at_node;
564
567 webidl_node_getnode(at_node),
568 NULL,
570
572 class,
573 NULL,
575 cure->name);
576
577 /* create attribute type vector */
578 type_map_new(at_node, &cure->typec, &cure->typev);
579
580
581 /* get binding node for read/write attributes */
584 webidl_node_getnode(at_node),
585 NULL,
587 if ((modifier != NULL) &&
590 } else {
593 class,
594 NULL,
596 cure->name);
597 }
598
599 /* check for putforwards extended attribute */
600 cure->putforwards = get_extended_value(at_node,
601 "PutForwards");
602
603 if ((cure->putforwards != NULL) &&
606 "putforwards on a writable attribute (%s) is prohibited",
607 cure->name);
608 }
609
610 /* check for treatnullas extended attribute */
611 cure->treatnullas = get_extended_value(at_node,
612 "TreatNullAs");
613
614 /* move to next attribute */
615 cure++;
616
617 at_node = webidl_node_find_type(
618 webidl_node_getnode(list_node),
619 at_node,
621 }
622
623 list_node = webidl_node_find_type(
624 webidl_node_getnode(interface),
625 list_node,
627 }
628
629 *attributev_out = attributev; /* resulting attributes map */
630
631 return 0;
632}
633
634static int
635constant_map_new(struct webidl_node *interface,
636 int *constantc_out,
637 struct ir_constant_entry **constantv_out)
638{
639 struct webidl_node *list_node;
640 struct webidl_node *constant_node; /* constant node */
641 struct ir_constant_entry *cure; /* current entry */
642 struct ir_constant_entry *constantv;
643 int constantc;
644
645 /* enumerate constants */
646 constantc = enumerate_interface_type(interface,
648
649 if (constantc < 1) {
650 *constantc_out = 0;
651 *constantv_out = NULL; /* no constants so empty map */
652 return 0;
653 }
654
655 *constantc_out = constantc;
656
657 constantv = calloc(constantc,
658 sizeof(struct ir_constant_entry));
659 if (constantv == NULL) {
660 return -1;
661 };
662 cure = constantv;
663
664 /* iterate each list node within the interface */
665 list_node = webidl_node_find_type(
666 webidl_node_getnode(interface),
667 NULL,
669
670 while (list_node != NULL) {
671 /* iterate through constants on list */
672 constant_node = webidl_node_find_type(
673 webidl_node_getnode(list_node),
674 NULL,
676
677 while (constant_node != NULL) {
678 cure->node = constant_node;
679
682 webidl_node_getnode(constant_node),
683 NULL,
685
686 cure++;
687
688 /* move to next constant */
689 constant_node = webidl_node_find_type(
690 webidl_node_getnode(list_node),
691 constant_node,
693 }
694
695 list_node = webidl_node_find_type(
696 webidl_node_getnode(interface),
697 list_node,
699 }
700
701 *constantv_out = constantv; /* resulting constants map */
702
703 return 0;
704}
705
706
707static int
708member_map_new(struct webidl_node *dictionary,
709 int *memberc_out,
710 struct ir_operation_argument_entry **memberv_out)
711{
712 struct webidl_node *list_node;
713 struct webidl_node *member_node; /* member node */
714 struct ir_operation_argument_entry *cure; /* current entry */
715 struct ir_operation_argument_entry *memberv;
716 int memberc;
717
718 /* enumerate members */
719 memberc = enumerate_interface_type(dictionary,
721
722 if (memberc < 1) {
723 *memberc_out = 0;
724 *memberv_out = NULL; /* no members so empty map */
725 return 0;
726 }
727
728 memberv = calloc(memberc, sizeof(struct ir_operation_argument_entry));
729 if (memberv == NULL) {
730 return -1;
731 };
732 cure = memberv;
733
734 /* iterate each list node within the dictionary */
735 list_node = webidl_node_find_type(
736 webidl_node_getnode(dictionary),
737 NULL,
739
740 while (list_node != NULL) {
741 /* iterate through members on list */
742 member_node = webidl_node_find_type(
743 webidl_node_getnode(list_node),
744 NULL,
746
747 while (member_node != NULL) {
748 cure->node = member_node;
749
752 webidl_node_getnode(member_node),
753 NULL,
755
757 webidl_node_getnode(member_node),
759
761 webidl_node_getnode(member_node),
763
764 cure++;
765
766 /* move to next member */
767 member_node = webidl_node_find_type(
768 webidl_node_getnode(list_node),
769 member_node,
771 }
772
773 list_node = webidl_node_find_type(
774 webidl_node_getnode(dictionary),
775 list_node,
777 }
778
779 *memberc_out = memberc;
780 *memberv_out = memberv; /* resulting members map */
781
782 return 0;
783
784}
785
786static int
787entry_map_new(struct genbind_node *genbind,
788 struct webidl_node *interface,
789 int *interfacec_out,
790 struct ir_entry **interfacev_out)
791{
792 int interfacec;
793 int dictionaryc;
794 int entryc;
795 struct ir_entry *entries;
796 struct ir_entry *sorted_entries;
797 struct ir_entry *cure;
798 struct webidl_node *node;
799
800 interfacec = webidl_node_enumerate_type(interface,
802 dictionaryc = webidl_node_enumerate_type(interface,
804 if (options->verbose) {
805 printf("Mapping %d interfaces\n", interfacec);
806 printf("Mapping %d dictionaries\n", dictionaryc);
807 }
808
809 entryc = interfacec + dictionaryc;
810
811 entries = calloc(entryc, sizeof(struct ir_entry));
812 if (entries == NULL) {
813 return -1;
814 }
815
816 /* for each interface populate an entry in the map */
817 cure = entries;
818 node = webidl_node_find_type(interface,
819 NULL,
821 while (node != NULL) {
822
823 /* fill map entry */
824 cure->node = node;
825
826 /* name of interface */
830 NULL,
832
833 /* name of the inherited interface (if any) */
837 NULL,
839
840 /* matching class from binding */
842 genbind,
843 NULL,
845 cure->name);
846
847 /* identify this is an interface entry */
849
850 /* is the interface marked as not generating an object */
854 "NoInterfaceObject") != NULL) {
859 cure->u.interface.noobject = true;
860 }
861
862 /* is the interface marked as the primary global */
866 "PrimaryGlobal") != NULL) {
871 cure->u.interface.primary_global = true;
872 }
873
874 /* enumerate and map the interface operations */
875 operation_map_new(node,
876 cure->class,
877 &cure->u.interface.operationc,
878 &cure->u.interface.operationv);
879
880 /* enumerate and map the interface attributes */
881 attribute_map_new(node,
882 cure->class,
883 &cure->u.interface.attributec,
884 &cure->u.interface.attributev);
885
886 /* enumerate and map the interface constants */
887 constant_map_new(node,
888 &cure->u.interface.constantc,
889 &cure->u.interface.constantv);
890
891 /* move to next interface */
892 node = webidl_node_find_type(interface,
893 node,
895 cure++;
896 }
897
898 /* for each dictionary populate an entry in the map */
899 node = webidl_node_find_type(interface,
900 NULL,
902 while (node != NULL) {
903
904 /* fill map entry */
905 cure->node = node;
906
907 /* name of interface */
911 NULL,
913
914 /* name of the inherited interface (if any) */
918 NULL,
920
921 /* matching class from binding */
923 genbind,
924 NULL,
926 cure->name);
927
928 /* identify this is an interface entry */
930
931 /* enumerate and map the dictionary members */
932 member_map_new(node,
933 &cure->u.dictionary.memberc,
934 &cure->u.dictionary.memberv);
935
936 /* move to next interface */
937 node = webidl_node_find_type(interface,
938 node,
940 cure++;
941 }
942
943 /* compute inheritance and refcounts on map */
944 compute_inherit_refcount(entries, entryc);
945
946 /* sort entries to ensure correct ordering */
947 sorted_entries = entry_topoligical_sort(entries, entryc);
948 free(entries);
949 if (sorted_entries == NULL) {
950 return -1;
951 }
952
953 /* compute inheritance and refcounts on sorted map */
954 compute_inherit_refcount(sorted_entries, entryc);
955
956 *interfacec_out = entryc;
957 *interfacev_out = sorted_entries;
958
959 return 0;
960}
961
962
963int ir_new(struct genbind_node *genbind,
964 struct webidl_node *webidl,
965 struct ir **map_out)
966{
967 struct ir *map;
968 int ret;
969
970 map = malloc(sizeof(struct ir));
971 if (map == NULL) {
972 return -1;
973 }
974
975 map->webidl = webidl;
976 map->binding_node = genbind_node_find_type(genbind, NULL,
978
979 /* interfaces */
980 ret = entry_map_new(genbind,
981 webidl,
982 &map->entryc,
983 &map->entries);
984 if (ret != 0) {
985 free(map);
986 return ret;
987 }
988
989 *map_out = map;
990
991 return 0;
992}
993
994static int ir_dump_dictionary(FILE *dumpf, struct ir_entry *ecur)
995{
996 if (ecur->u.dictionary.memberc > 0) {
997 int argc;
998
999 fprintf(dumpf, "\t%d members\n", ecur->u.dictionary.memberc);
1000
1001 for (argc = 0; argc < ecur->u.dictionary.memberc; argc++) {
1002 struct ir_operation_argument_entry *arge;
1003
1004 arge = ecur->u.dictionary.memberv + argc;
1005
1006 fprintf(dumpf, "\t\t%s\n", arge->name);
1007
1008 if (arge->optionalc != 0) {
1009 fprintf(dumpf,
1010 "\t\t\toptional:%d\n",
1011 arge->optionalc);
1012 }
1013
1014 if (arge->elipsisc != 0) {
1015 fprintf(dumpf,
1016 "\t\t\telipsis:%d\n",
1017 arge->elipsisc);
1018 }
1019 }
1020 }
1021 return 0;
1022}
1023
1024static int ir_dump_interface(FILE *dumpf, struct ir_entry *ecur)
1025{
1026 if (ecur->u.interface.operationc > 0) {
1027 int opc;
1028
1029 fprintf(dumpf, "\t%d operations\n",
1030 ecur->u.interface.operationc);
1031
1032 for (opc = 0; opc < ecur->u.interface.operationc; opc++) {
1033 int ovlc;
1034 struct ir_operation_entry *ope;
1035
1036 ope = ecur->u.interface.operationv + opc;
1037
1038 fprintf(dumpf,
1039 "\t\t%s\n",
1040 ope->name);
1041 fprintf(dumpf,
1042 "\t\t\tmethod:%p\n",
1043 ope->method);
1044 for(ovlc = 0; ovlc < ope->overloadc;ovlc++) {
1045 int argc;
1046 struct ir_operation_overload_entry *ovle;
1047 ovle = ope->overloadv + ovlc;
1048
1049 fprintf(dumpf,
1050 "\t\t\toverload:%d\n", ovlc);
1051
1052 fprintf(dumpf,
1053 "\t\t\t\treturn type:%p\n",
1054 ovle->type);
1055
1056 fprintf(dumpf,
1057 "\t\t\t\targuments:%d\n",
1058 ovle->argumentc);
1059
1060 fprintf(dumpf,
1061 "\t\t\t\toptionals:%d\n",
1062 ovle->optionalc);
1063
1064 fprintf(dumpf,
1065 "\t\t\t\telipsis:%d\n",
1066 ovle->elipsisc);
1067
1068 for (argc = 0; argc < ovle->argumentc; argc++) {
1069 struct ir_operation_argument_entry *arge;
1070 arge = ovle->argumentv + argc;
1071
1072 fprintf(dumpf,
1073 "\t\t\t\t\t%s\n",
1074 arge->name);
1075
1076 if (arge->optionalc != 0) {
1077 fprintf(dumpf,
1078 "\t\t\t\t\t\toptional:%d\n",
1079 arge->optionalc);
1080 }
1081
1082 if (arge->elipsisc != 0) {
1083 fprintf(dumpf,
1084 "\t\t\t\t\t\telipsis:%d\n",
1085 arge->elipsisc);
1086 }
1087
1088 }
1089 }
1090 }
1091 }
1092
1093 if (ecur->u.interface.attributec > 0) {
1094 int attrc = ecur->u.interface.attributec;
1095 struct ir_attribute_entry *attre;
1096
1097 fprintf(dumpf, "\t%d attributes\n", attrc);
1098
1099 attre = ecur->u.interface.attributev;
1100 while (attre != NULL) {
1101 fprintf(dumpf, "\t\t%s %p",
1102 attre->name,
1103 attre->getter);
1104 if (attre->modifier == WEBIDL_TYPE_MODIFIER_NONE) {
1105 fprintf(dumpf, " %p\n", attre->setter);
1106 } else {
1107 fprintf(dumpf, "\n");
1108 }
1109 attre++;
1110 attrc--;
1111 if (attrc == 0) {
1112 break;
1113 }
1114 }
1115 }
1116 if (ecur->u.interface.constantc > 0) {
1117 int idx;
1118
1119 fprintf(dumpf, "\t%d constants\n",
1120 ecur->u.interface.constantc);
1121
1122 for (idx = 0; idx < ecur->u.interface.constantc; idx++) {
1123 struct ir_constant_entry *cone;
1124 cone = ecur->u.interface.constantv + idx;
1125 fprintf(dumpf, "\t\t%s\n", cone->name);
1126 }
1127 }
1128 return 0;
1129}
1130
1131int ir_dump(struct ir *ir)
1132{
1133 FILE *dumpf;
1134 int eidx;
1135 struct ir_entry *ecur;
1136
1137 /* only dump AST to file if required */
1138 if (!options->debug) {
1139 return 0;
1140 }
1141
1142 dumpf = genb_fopen("ir-map", "w");
1143 if (dumpf == NULL) {
1144 return 2;
1145 }
1146
1147 ecur = ir->entries;
1148 for (eidx = 0; eidx < ir->entryc; eidx++) {
1149 fprintf(dumpf, "%d %s\n", eidx, ecur->name);
1150 if (ecur->inherit_name != NULL) {
1151 fprintf(dumpf, "\tinherit:%s\n", ecur->inherit_name);
1152 }
1153 if (ecur->class != NULL) {
1154 fprintf(dumpf, "\tclass:%p\n", ecur->class);
1155 }
1156
1157 switch (ecur->type) {
1159 ir_dump_interface(dumpf, ecur);
1160 break;
1161
1163 ir_dump_dictionary(dumpf, ecur);
1164 break;
1165
1166 }
1167 ecur++;
1168 }
1169
1170 fclose(dumpf);
1171
1172 return 0;
1173}
1174
1175int ir_dumpdot(struct ir *index)
1176{
1177 FILE *dumpf;
1178 int eidx;
1179 struct ir_entry *ecur;
1180
1181 /* only dump AST to file if required */
1182 if (!options->debug) {
1183 return 0;
1184 }
1185
1186 dumpf = genb_fopen("ir.dot", "w");
1187 if (dumpf == NULL) {
1188 return 2;
1189 }
1190
1191 fprintf(dumpf, "digraph interfaces {\n");
1192
1193 fprintf(dumpf, "node [shape=box]\n");
1194
1195 ecur = index->entries;
1196 for (eidx = 0; eidx < index->entryc; eidx++) {
1197 fprintf(dumpf, "%04d [label=\"%s\"", eidx, ecur->name);
1198 if ((ecur == IR_ENTRY_TYPE_INTERFACE) &&
1199 (ecur->u.interface.noobject == true)) {
1200 /* noobject interfaces in red */
1201 fprintf(dumpf, "fontcolor=\"red\"");
1202 } else if (ecur->class != NULL) {
1203 /* interfaces bound to a class are shown in blue */
1204 fprintf(dumpf, "fontcolor=\"blue\"");
1205 }
1206
1207 fprintf(dumpf, "];\n");
1208 ecur++;
1209 }
1210
1211 ecur = index->entries;
1212 for (eidx = 0; eidx < index->entryc; eidx++) {
1213 if (index->entries[eidx].inherit_idx != -1) {
1214 fprintf(dumpf, "%04d -> %04d;\n",
1215 eidx, index->entries[eidx].inherit_idx);
1216 }
1217 }
1218
1219 fprintf(dumpf, "}\n");
1220
1221 fclose(dumpf);
1222
1223 return 0;
1224}
1225
1226struct ir_entry *
1228 struct ir_entry *entry)
1229{
1230 struct ir_entry *res = NULL;
1231
1232 if ((entry != NULL) &&
1233 (entry->inherit_idx != -1)) {
1234 res = &map->entries[entry->inherit_idx];
1235 }
1236 return res;
1237}
int ir_new(struct genbind_node *genbind, struct webidl_node *webidl, struct ir **map_out)
Definition ir.c:963
int ir_dump(struct ir *ir)
Definition ir.c:1131
int ir_dumpdot(struct ir *index)
Definition ir.c:1175
struct ir_entry * ir_inherit_entry(struct ir *map, struct ir_entry *entry)
Definition ir.c:1227
@ IR_ENTRY_TYPE_DICTIONARY
Definition ir.h:123
@ 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_method_ident(struct genbind_node *node, struct genbind_node *prev, enum genbind_method_type nodetype, const char *ident)
struct genbind_node * genbind_node_find_type_ident(struct genbind_node *node, struct genbind_node *prev, enum genbind_node_type type, const char *ident)
@ GENBIND_METHOD_TYPE_METHOD
@ GENBIND_METHOD_TYPE_SETTER
@ GENBIND_METHOD_TYPE_GETTER
@ GENBIND_NODE_TYPE_BINDING
@ GENBIND_NODE_TYPE_CLASS
void * malloc(YYSIZE_T)
void free(void *)
@ WARNING_WEBIDL
Definition options.h:31
#define WARN(flags, msg, args...)
Definition options.h:37
Definition ir.h:63
enum webidl_type_modifier modifier
Definition ir.h:70
const char * treatnullas
Definition ir.h:72
struct ir_type_entry * typev
Definition ir.h:68
int typec
Definition ir.h:67
struct genbind_node * setter
Definition ir.h:75
struct webidl_node * node
Definition ir.h:65
const char * putforwards
Definition ir.h:71
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
struct ir_operation_argument_entry * memberv
Definition ir.h:118
int memberc
Definition ir.h:117
Definition ir.h:134
struct webidl_node * node
Definition ir.h:136
struct ir_dictionary_entry dictionary
Definition ir.h:142
struct genbind_node * class
Definition ir.h:138
int refcount
Definition ir.h:149
enum ir_entry_type type
Definition ir.h:140
int inherit_idx
Definition ir.h:146
const char * name
Definition ir.h:135
struct ir_interface_entry interface
Definition ir.h:143
union ir_entry::@2 u
const char * inherit_name
Definition ir.h:137
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
int optionalc
Definition ir.h:21
struct webidl_node * node
Definition ir.h:24
int elipsisc
Definition ir.h:22
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
struct webidl_node * node
Definition ir.h:43
int overloadc
Definition ir.h:46
struct genbind_node * method
Definition ir.h:44
Definition ir.h:30
struct webidl_node * type
Definition ir.h:31
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
Definition ir.h:53
enum webidl_type_modifier modifier
Definition ir.h:55
const char * name
Definition ir.h:57
enum webidl_type base
Definition ir.h:54
bool nullable
Definition ir.h:56
Definition ir.h:172
struct genbind_node * binding_node
Definition ir.h:177
struct webidl_node * webidl
Definition ir.h:180
int entryc
Definition ir.h:173
struct ir_entry * entries
Definition ir.h:174
bool debug
Definition options.h:19
bool verbose
Definition options.h:18
struct webidl_node * node
Definition webidl-ast.c:35
FILE * genb_fopen(const char *fname, const char *mode)
Definition utils.c:46
struct webidl_node * webidl_node_getnode(struct webidl_node *node)
Definition webidl-ast.c:335
int webidl_node_enumerate_type(struct webidl_node *node, enum webidl_node_type type)
Definition webidl-ast.c:192
struct webidl_node * webidl_node_find_type_ident(struct webidl_node *root_node, enum webidl_node_type type, const char *ident)
Definition webidl-ast.c:246
char * webidl_node_gettext(struct webidl_node *node)
Definition webidl-ast.c:273
int * webidl_node_getint(struct webidl_node *node)
Definition webidl-ast.c:293
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_node_type
Definition webidl-ast.h:12
@ WEBIDL_NODE_TYPE_IDENT
Definition webidl-ast.h:15
@ WEBIDL_NODE_TYPE_CONST
Definition webidl-ast.h:27
@ WEBIDL_NODE_TYPE_DICTIONARY
Definition webidl-ast.h:29
@ WEBIDL_NODE_TYPE_LIST
Definition webidl-ast.h:19
@ WEBIDL_NODE_TYPE_TYPE_BASE
Definition webidl-ast.h:37
@ WEBIDL_NODE_TYPE_OPERATION
Definition webidl-ast.h:26
@ WEBIDL_NODE_TYPE_INTERFACE
Definition webidl-ast.h:22
@ WEBIDL_NODE_TYPE_EXTENDED_ATTRIBUTE
Definition webidl-ast.h:47
@ WEBIDL_NODE_TYPE_TYPE
Definition webidl-ast.h:36
@ WEBIDL_NODE_TYPE_TYPE_NULLABLE
Definition webidl-ast.h:38
@ WEBIDL_NODE_TYPE_INHERITANCE
Definition webidl-ast.h:31
@ WEBIDL_NODE_TYPE_ATTRIBUTE
Definition webidl-ast.h:25
@ WEBIDL_NODE_TYPE_MODIFIER
Definition webidl-ast.h:17
@ WEBIDL_NODE_TYPE_OPTIONAL
Definition webidl-ast.h:34
@ WEBIDL_NODE_TYPE_ARGUMENT
Definition webidl-ast.h:33
@ WEBIDL_NODE_TYPE_ELLIPSIS
Definition webidl-ast.h:35
webidl_type_modifier
Definition webidl-ast.h:70
@ WEBIDL_TYPE_MODIFIER_NONE
Definition webidl-ast.h:71
@ WEBIDL_TYPE_MODIFIER_READONLY
Definition webidl-ast.h:74