6 int compare_lists(const void *_v1, const void *_v2)
8 classinfo_t**v1 = *(classinfo_t***)_v1;
9 classinfo_t**v2 = *(classinfo_t***)_v2;
10 parsedclass_t*p1 = **(parsedclass_t***)_v1;
11 parsedclass_t*p2 = **(parsedclass_t***)_v2;
12 if((p1->cls->flags^p2->cls->flags)&FLAG_INTERFACE) {
13 return (int)(p2->cls->flags&FLAG_INTERFACE) - (int)(p1->cls->flags&FLAG_INTERFACE);
17 if(*v1<*v2) return -1;
18 else if(*v1>*v2) return 1;
23 /* sort classes so that
24 (a) interfaces appear before classes
25 (b) base classes always appear before their subclasses
26 (c) neighboring elements have similar scope stacks
28 Notice: we don't yet handle multiple inheritance (in interfaces) correctly.
30 parsedclass_t** initcode_sort_classlist(parsedclass_list_t*classes)
35 for(l=classes;l;l=l->next) {
38 void***list = malloc(sizeof(void**)*count);
40 /* build an array for each class */
42 for(l=classes;l;l=l->next) {
43 classinfo_t*cls = l->parsedclass->cls;
48 c = c->flags&FLAG_INTERFACE?c->interfaces[0]:c->superclass;
50 void**a = (void**)malloc(sizeof(void*)*(len+2));
51 a[0] = l->parsedclass;
58 c = c->flags&FLAG_INTERFACE?c->interfaces[0]:c->superclass;
63 /* sort and flatten */
64 qsort(list, count, sizeof(void**), compare_lists);
66 parsedclass_t**list2 = malloc(sizeof(parsedclass_t*)*(count+1));
67 for(i=0;i<count;i++) {
68 list2[i] = (parsedclass_t*)list[i][0];
76 void initcode_add_classlist(abc_script_t*init, parsedclass_list_t*_classes)
80 c = abc_getlocal_0(c);
83 parsedclass_t**classes = initcode_sort_classlist(_classes);
86 for(t=0;classes[t];t++) {
87 abc_class_t*abc = classes[t]->abc;
88 classinfo_t*cls = classes[t]->cls;
90 array_append(init->file->classes, "", abc);
92 /* write the construction code for this class to the global init
94 MULTINAME(classname2,cls);
95 trait_t*trait = abc_initscript_addClassTrait(init, &classname2, abc);
97 c = abc_getglobalscope(c);
98 classinfo_t*s = cls->superclass;
103 //TODO: take a look at the current scope stack, maybe
104 // we can re-use something
109 multiname_t*s2 = sig2mname(s);
110 c = abc_getlex2(c, s2);
111 multiname_destroy(s2);
113 c = abc_pushscope(c); count++;
114 c = c->prev->prev; // invert
116 /* continue appending after last op end */
117 while(c && c->next) c = c->next;
119 multiname_t*extends2 = sig2mname(cls->superclass);
120 /* TODO: if this is one of *our* classes, we can also
121 do a getglobalscope/getslot <nr> (which references
122 the init function's slots) */
124 c = abc_getlex2(c, extends2);
126 /* notice: we get a Verify Error #1107 if the top elemnt on the scope
127 stack is not the superclass */
128 c = abc_pushscope(c);count++;
131 /* notice: we get a verify error #1107 if the top element on the scope
132 stack is not the global object */
133 c = abc_getlocal_0(c);
134 c = abc_pushscope(c);count++;
136 c = abc_newclass(c,abc);
140 c = abc_setslot(c, trait->slot_id);
141 multiname_destroy(extends2);
143 c = abc_returnvoid(c);
147 init->method->body->code = c;