Remove the now useless MMConcreteProperty class
[nit.git] / src / compiling / compiling_global.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2008 Jean Privat <jean@pryen.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Compute and generate tables for classes and modules.
18 package compiling_global
19
20 #import compiling_base
21 private import compiling_methods
22 private import syntax
23
24 # Something that store color of table elements
25 class ColorContext
26 attr _colors: HashMap[TableElt, Int]
27
28 # The color of a table element.
29 meth color(e: TableElt): Int
30 do
31 return _colors[e]
32 end
33
34 # Is a table element already colored?
35 meth has_color(e: TableElt): Bool
36 do
37 return _colors != null and _colors.has_key(e)
38 end
39
40 # Assign a color to a table element.
41 meth color=(e: TableElt, c: Int)
42 do
43 if _colors == null then _colors = new HashMap[TableElt, Int]
44 _colors[e] = c
45 var idx = c
46 for i in [0..e.length[ do
47 _colors[e.item(i)] = idx
48 idx = idx + 1
49 end
50 end
51 end
52
53 # All information and results of the global analysis.
54 class GlobalAnalysis
55 special ColorContext
56 # Associate global classes to compiled classes
57 readable attr _compiled_classes: HashMap[MMGlobalClass, CompiledClass]
58
59 # The main module of the program globally analysed
60 readable attr _module: MMModule
61
62 # FIXME: do something better.
63 readable writable attr _max_class_table_length: Int
64
65 init(module: MMSrcModule)
66 do
67 _compiled_classes = new HashMap[MMGlobalClass, CompiledClass]
68 _module = module
69 end
70 end
71
72 redef class CompilerVisitor
73 # The global analysis result, if any
74 readable writable attr _global_analysis: GlobalAnalysis
75 end
76
77 # A compiled class is a class in a program
78 class CompiledClass
79 special ColorContext
80 # The corresponding local class in the main module of the prgram
81 readable attr _local_class: MMLocalClass
82
83 # The identifier of the class
84 readable writable attr _id: Int
85
86 # The full class table of the class
87 readable writable attr _class_table: Array[TableElt]
88
89 # The full instance table of the class
90 readable writable attr _instance_table: Array[TableElt]
91
92 # The proper class table part (no superclasses but all refinements)
93 readable writable attr _class_layout: TableEltComposite
94
95 # The proper instance table part (no superclasses but all refinements)
96 readable writable attr _instance_layout: TableEltComposite
97
98 init(c: MMLocalClass) do _local_class = c
99 end
100
101 redef class MMGlobalProperty
102 # The position of the property in the local class table part
103 # FIXME: It's ugly. store this somewhere else please
104 readable writable attr _pos_of: Int
105 end
106
107 redef class MMSrcLocalClass
108 # The table element of the attribute position (for accessor simulation)
109 readable attr _base_attr_pos: TableEltBaseAttrPos
110
111 # The table element of the subtype check
112 readable attr _class_color_pos: TableEltClassColorPos
113
114 # The proper local class table part (nor superclasses nor refinments)
115 readable attr _class_layout: Array[LocalTableElt]
116
117 # The proper local instance table part (nor superclasses nor refinments)
118 readable attr _instance_layout: Array[LocalTableElt]
119
120 # Build the local layout of the class and feed the module table
121 meth build_layout_in(tc: ToolContext, module_table: Array[LocalTableElt])
122 do
123 var intro_methods = new Array[MMGlobalProperty] # FIXME: Remove this
124 var intro_attributes = new Array[MMGlobalProperty] # FIXME: Remove this
125 var clt = new Array[LocalTableElt]
126 _class_layout = clt
127 var ilt = new Array[LocalTableElt]
128 _instance_layout = ilt
129
130 if global.intro == self then
131 module_table.add(new TableEltClassIdPos(self))
132 _class_color_pos = new TableEltClassColorPos(self)
133 module_table.add(_class_color_pos)
134 #clt.add(_class_color_pos)
135 clt.add(new TableEltClassInitTablePos(self))
136 end
137 for p in src_local_properties do
138 var pg = p.global
139 if pg.intro == p then
140 if p isa MMSrcAttribute then
141 pg.pos_of = intro_attributes.length
142 intro_attributes.add(pg)
143 ilt.add(new TableEltAttrPos(p))
144 else if p isa MMSrcMethod then
145 pg.pos_of = intro_methods.length
146 intro_methods.add(pg)
147 clt.add(new TableEltMethPos(p))
148 end
149 end
150 if p isa MMSrcMethod and p.need_super then
151 clt.add(new TableEltSuperPos(p))
152 end
153 end
154 if tc.attr_sim and not intro_attributes.is_empty then
155 _base_attr_pos = new TableEltBaseAttrPos(self)
156 clt.add(_base_attr_pos)
157 else
158 module_table.append(ilt)
159 end
160 module_table.append(clt)
161 end
162 end
163
164 redef class MMSrcModule
165 # The local table of the module (refers things introduced in the module)
166 attr _local_table: Array[LocalTableElt]
167
168 # Builds the local tables and local classes layouts
169 meth local_analysis(tc: ToolContext)
170 do
171 var lt = new Array[LocalTableElt]
172 _local_table = lt
173 for c in src_local_classes do
174 c.build_layout_in(tc, lt)
175 end
176 end
177
178 # Do the complete global analysis
179 meth global_analysis(cctx: ToolContext): GlobalAnalysis
180 do
181 #print "Do the complete global analysis"
182 var ga = new GlobalAnalysis(self)
183 var smallest_classes = new Array[MMLocalClass]
184 var global_properties = new HashSet[MMGlobalProperty]
185 var ctab = new Array[TableElt]
186 var itab = new Array[TableElt]
187
188 ctab.add(new TableEltClassSelfId)
189 itab.add(new TableEltVftPointer)
190
191 var pclassid = -1
192 var classid = 3
193
194 # We have to work on ALL the classes of the module
195 var classes = new Array[MMLocalClass]
196 for c in local_classes do
197 c.compute_super_classes
198 classes.add(c)
199 end
200 (new ClassSorter).sort(classes)
201
202 for c in classes do
203 # Finish processing the class (if invisible)
204 c.compute_ancestors
205 c.inherit_global_properties
206
207 # Associate a CompiledClass to the class
208 var cc = new CompiledClass(c)
209 ga.compiled_classes[c.global] = cc
210
211 # Assign a unique class identifier
212 # (negative are for primitive classes)
213 var gc = c.global
214 var bm = gc.module
215 if c.primitive_info != null then
216 cc.id = pclassid
217 pclassid = pclassid - 4
218 else
219 cc.id = classid
220 classid = classid + 4
221 end
222
223 # Register is the class is a leaf
224 if c.cshe.direct_smallers.is_empty then
225 smallest_classes.add(c)
226 end
227
228 # Store the colortableelt in the class table pool
229 var bc = c.global.intro
230 assert bc isa MMSrcLocalClass
231 ctab.add(bc.class_color_pos)
232 end
233
234 # Compute core and crown classes for colorization
235 var crown_classes = new HashSet[MMLocalClass]
236 var core_classes = new HashSet[MMLocalClass]
237 for c in smallest_classes do
238 while c.cshe.direct_greaters.length == 1 do
239 c = c.cshe.direct_greaters.first
240 end
241 crown_classes.add(c)
242 core_classes.add_all(c.cshe.greaters_and_self)
243 end
244 #print("nbclasses: {classes.length} leaves: {smallest_classes.length} crown: {crown_classes.length} core: {core_classes.length}")
245
246 # Colorize core color for typechecks
247 colorize(ga, ctab, crown_classes, 0)
248
249 # Compute tables for typechecks
250 var maxcolor = 0
251 for c in classes do
252 var cc = ga.compiled_classes[c.global]
253 if core_classes.has(c) then
254 # For core classes, just build the table
255 cc.class_table = build_tables(ga, c, ctab)
256 if maxcolor < cc.class_table.length then maxcolor = cc.class_table.length
257 else
258 # For other classes, it's easier: just append to the parent tables
259 var sc = c.cshe.direct_greaters.first
260 var scc = ga.compiled_classes[sc.global]
261 cc.class_table = scc.class_table.to_a
262 var bc = c.global.intro
263 assert bc isa MMSrcLocalClass
264 var colpos = bc.class_color_pos
265 var colposcolor = cc.class_table.length
266 ga.color(colpos) = colposcolor
267 cc.class_table.add(colpos)
268 if maxcolor < colposcolor then maxcolor = colposcolor
269 end
270 end
271 ga.max_class_table_length = maxcolor + 1
272
273 # Fill class table and instance tables pools
274 for c in classes do
275 var cc = ga.compiled_classes[c.global]
276 var cte = new TableEltComposite(cc)
277 var ite = new TableEltComposite(cc)
278 for sc in c.crhe.greaters_and_self do
279 if sc isa MMSrcLocalClass then
280 cte.add(sc, sc.class_layout)
281 ite.add(sc, sc.instance_layout)
282 end
283 cc.class_layout = cte
284 cc.instance_layout = ite
285 end
286
287 if core_classes.has(c) then
288 if cte.length > 0 then
289 ctab.add(cte)
290 end
291 if not cctx.attr_sim and ite.length > 0 then
292 itab.add(ite)
293 end
294 end
295 end
296
297 # Colorize all elements in pools tables
298 colorize(ga, ctab, crown_classes, maxcolor+1)
299 colorize(ga, itab, crown_classes, 0)
300
301 # Build class and instance tables now things are colored
302 ga.max_class_table_length = 0
303 for c in classes do
304 var cc = ga.compiled_classes[c.global]
305 if core_classes.has(c) then
306 # For core classes, just build the table
307 cc.class_table = build_tables(ga, c, ctab)
308 cc.instance_table = build_tables(ga, c, itab)
309 else
310 # For other classes, it's easier: just append to the parent tables
311 var sc = c.cshe.direct_greaters.first
312 var scc = ga.compiled_classes[sc.global]
313 cc.class_table = scc.class_table.to_a
314 var bc = c.global.intro
315 assert bc isa MMSrcLocalClass
316 var colpos = bc.class_color_pos
317 cc.class_table[ga.color(colpos)] = colpos
318 while cc.class_table.length <= maxcolor do
319 cc.class_table.add(null)
320 end
321 append_to_table(ga, cc.class_table, cc.class_layout)
322 cc.instance_table = scc.instance_table.to_a
323 append_to_table(ga, cc.instance_table, cc.instance_layout)
324 end
325
326 if cctx.attr_sim then
327 cc.instance_table = build_tables(ga, c, itab)
328 for sc in c.cshe.greaters_and_self do
329 var scc = ga.compiled_classes[sc.global]
330 append_to_table(cc, cc.instance_table, scc.instance_layout)
331 end
332 end
333 end
334
335 return ga
336 end
337
338 private meth append_to_table(cc: ColorContext, table: Array[TableElt], cmp: TableEltComposite)
339 do
340 for j in [0..cmp.length[ do
341 var e = cmp.item(j)
342 cc.color(e) = table.length
343 table.add(e)
344 end
345 end
346
347 private meth build_tables(ga: GlobalAnalysis, c: MMLocalClass, elts: Array[TableElt]): Array[TableElt]
348 do
349 var tab = new HashMap[Int, TableElt]
350 var len = 0
351 for e in elts do
352 if e.is_related_to(c) then
353 var col = ga.color(e)
354 var l = col + e.length
355 tab[col] = e
356 if len < l then
357 len = l
358 end
359 end
360 end
361 var res = new Array[TableElt]
362 var i = 0
363 while i < len do
364 if tab.has_key(i) then
365 var e = tab[i]
366 for j in [0..e.length[ do
367 res[i] = e.item(j)
368 i = i + 1
369 end
370 else
371 res[i] = null
372 i = i + 1
373 end
374 end
375 return res
376 end
377
378 # Perform coloring
379 meth colorize(ga: GlobalAnalysis, elts: Array[TableElt], classes: Collection[MMLocalClass], startcolor: Int)
380 do
381 var colors = new HashMap[Int, Array[TableElt]]
382 var rel_classes = new Array[MMLocalClass]
383 for e in elts do
384 var color = -1
385 var len = e.length
386 if ga.has_color(e) then
387 color = ga.color(e)
388 else
389 rel_classes.clear
390 for c in classes do
391 if e.is_related_to(c) then
392 rel_classes.add(c)
393 end
394 end
395 var trycolor = startcolor
396 while trycolor != color do
397 color = trycolor
398 for c in rel_classes do
399 var idx = 0
400 while idx < len do
401 if colors.has_key(trycolor + idx) and not free_color(colors[trycolor + idx], c) then
402 trycolor = trycolor + idx + 1
403 idx = 0
404 else
405 idx = idx + 1
406 end
407 end
408 end
409 end
410 ga.color(e) = color
411 end
412 for idx in [0..len[ do
413 if colors.has_key(color + idx) then
414 colors[color + idx].add(e)
415 else
416 colors[color + idx] = [e]
417 end
418 end
419 end
420 end
421
422 private meth free_color(es: Array[TableElt], c: MMLocalClass): Bool
423 do
424 for e2 in es do
425 if e2.is_related_to(c) then
426 return false
427 end
428 end
429 return true
430 end
431
432 # Compile module and class tables
433 meth compile_tables_to_c(v: CompilerVisitor)
434 do
435 for m in mhe.greaters_and_self do
436 assert m isa MMSrcModule
437 m.compile_local_table_to_c(v)
438 end
439
440 for c in local_classes do
441 c.compile_tables_to_c(v)
442 end
443 var s = "classtable_t TAG2VFT[4] = \{NULL"
444 for t in ["Int","Char","Bool"] do
445 if has_global_class_named(t.to_symbol) then
446 s.append(", (const classtable_t)VFT_{t}")
447 else
448 s.append(", NULL")
449 end
450 end
451 s.append("};")
452 v.add_instr(s)
453 end
454
455 # Declare class table (for _sep.h)
456 meth declare_class_tables_to_c(v: CompilerVisitor)
457 do
458 for c in local_classes do
459 if c.global.module == self then
460 c.declare_tables_to_c(v)
461 end
462 end
463 end
464
465 # Compile main part (for _table.c)
466 meth compile_main_part(v: CompilerVisitor)
467 do
468 v.add_instr("int main(int argc, char **argv) \{")
469 v.indent
470 v.add_instr("prepare_signals();")
471 v.add_instr("glob_argc = argc; glob_argv = argv;")
472 var sysname = once "Sys".to_symbol
473 if not has_global_class_named(sysname) then
474 print("No main")
475 else
476 var sys = class_by_name(sysname).get_type
477 # var initm = sys.select_method(once "init".to_symbol)
478 var mainm = sys.select_method(once "main".to_symbol)
479 if mainm == null then
480 print("No main")
481 else
482 #v.add_instr("G_sys = NEW_{initm.cname}();")
483 v.add_instr("G_sys = NEW_Sys();")
484 v.add_instr("{mainm.cname}(G_sys);")
485 end
486 end
487 v.add_instr("return 0;")
488 v.unindent
489 v.add_instr("}")
490 end
491
492 # Compile sep files
493 meth compile_mod_to_c(v: CompilerVisitor)
494 do
495 v.add_decl("#define LOCATE_{name} \"{filename}\"")
496 if not v.tc.global then
497 v.add_decl("extern const int SFT_{name}[];")
498 end
499 var i = 0
500 for e in _local_table do
501 if v.tc.global then
502 v.add_decl("#define {e.symbol} {e.value(v.global_analysis)}")
503 else
504 v.add_decl("#define {e.symbol} SFT_{name}[{i}]")
505 i = i + 1
506 end
507 end
508 for c in src_local_classes do
509 for p in c.src_local_properties do
510 var pg = p.global
511 if pg.intro == p and p isa MMAttribute then
512 if v.tc.attr_sim then
513 var bc = pg.local_class
514 assert bc isa MMSrcLocalClass
515 var s = bc.base_attr_pos.symbol
516 v.add_decl("#define {pg.attr_access}(recv) ATTRS(recv, {s}, {pg.pos_of})")
517 else
518 v.add_decl("#define {pg.attr_access}(recv) ATTR(recv, {pg.color_id})")
519 end
520 end
521 p.compile_property_to_c(v)
522 end
523 end
524 end
525
526 # Compile module file for the current module
527 meth compile_local_table_to_c(v: CompilerVisitor)
528 do
529 if v.tc.global or _local_table.is_empty then
530 return
531 end
532
533 v.add_instr("const int SFT_{name}[{_local_table.length}] = \{")
534 v.indent
535 for e in _local_table do
536 v.add_instr(e.value(v.global_analysis) + ",")
537 end
538 v.unindent
539 v.add_instr("\};")
540 end
541 end
542
543 class TableElt
544 meth is_related_to(c: MMLocalClass): Bool is abstract
545 meth length: Int do return 1
546 meth item(i: Int): TableElt do return self
547 meth compile_to_c(v: CompilerVisitor, c: MMLocalClass): String is abstract
548 end
549
550 class LocalTableElt
551 special TableElt
552 meth symbol: String is abstract
553 meth value(ga: GlobalAnalysis): String is abstract
554 end
555
556 class TableEltPropPos
557 special LocalTableElt
558 attr _property: MMLocalProperty
559 redef meth symbol do return _property.global.color_id
560 redef meth value(ga) do return "{ga.color(self)} /* Property {_property} */"
561
562 init(p: MMLocalProperty)
563 do
564 _property = p
565 end
566 end
567
568 class TableEltMethPos
569 special TableEltPropPos
570 redef meth compile_to_c(v, c)
571 do
572 var p = c[_property.global]
573 return p.cname
574 end
575 init(p) do super
576 end
577
578 class TableEltSuperPos
579 special TableEltPropPos
580 redef meth symbol do return _property.color_id_for_super
581 redef meth compile_to_c(v, c)
582 do
583 var pc = _property.local_class
584 var g = _property.global
585 var lin = c.che.linear_extension
586 var found = false
587 for s in lin do
588 #print "{c.module}::{c} for {pc.module}::{pc}::{_property} try {s.module}:{s}"
589 if s == pc then
590 found = true
591 else if found and c.che < s then
592 var p = s[g]
593 if p != null then
594 #print "found {s.module}::{s}::{p}"
595 return p.cname
596 end
597 end
598 end
599 assert false
600 return null
601 end
602
603 init(p) do super
604 end
605
606 class TableEltAttrPos
607 special TableEltPropPos
608 redef meth compile_to_c(v, c)
609 do
610 var ga = v.global_analysis
611 var p = c[_property.global]
612 return "/* {ga.color(self)}: Attribute {c}::{p} */"
613 end
614
615 init(p) do super
616 end
617
618 class TableEltClassPos
619 special LocalTableElt
620 attr _local_class: MMLocalClass
621 redef meth is_related_to(c)
622 do
623 var bc = c.module[_local_class.global]
624 return c.cshe <= bc
625 end
626
627 init(c: MMLocalClass)
628 do
629 _local_class = c
630 end
631 end
632
633 class TableEltClassIdPos
634 special TableEltClassPos
635 redef meth symbol do return _local_class.global.id_id
636 redef meth value(ga)
637 do
638 return "{ga.compiled_classes[_local_class.global].id} /* Id of {_local_class} */"
639 end
640
641 init(c) do super
642 end
643
644 class TableEltClassInitTablePos
645 special TableEltClassPos
646 redef meth symbol do return _local_class.global.init_table_pos_id
647 redef meth value(ga)
648 do
649 return "{ga.color(self)} /* Color of {_local_class} */"
650 end
651 redef meth compile_to_c(v, c)
652 do
653 var ga = v.global_analysis
654 var cc = ga.compiled_classes[_local_class.global]
655 var linext = c.cshe.reverse_linear_extension
656 var i = 0
657 while linext[i].global != _local_class.global do
658 i += 1
659 end
660 return "{i} /* {ga.color(self)}: {c} < {cc.local_class}: superclass init_table position */"
661 end
662
663 init(c) do super
664 end
665
666 class TableEltClassColorPos
667 special TableEltClassPos
668 redef meth symbol do return _local_class.global.color_id
669 redef meth value(ga)
670 do
671 return "{ga.color(self)} /* Color of {_local_class} */"
672 end
673 redef meth compile_to_c(v, c)
674 do
675 var ga = v.global_analysis
676 var cc = ga.compiled_classes[_local_class.global]
677 return "{cc.id} /* {ga.color(self)}: {c} < {cc.local_class}: superclass typecheck marker */"
678 end
679
680 init(c) do super
681 end
682
683 class TableEltBaseAttrPos
684 special LocalTableElt
685 attr _local_class: MMSrcLocalClass
686 redef meth symbol do return "COLOR_{_local_class.module}_{_local_class.name}_BASEATTR"
687 redef meth value(ga)
688 do
689 return "{ga.color(self)} /* BaseAttrPos of {_local_class} */"
690 end
691
692 redef meth compile_to_c(v, c)
693 do
694 var ga = v.global_analysis
695 var cc = ga.compiled_classes[c.global]
696 return "{cc.color(_local_class.instance_layout.first)} /* {ga.color(self)}: Base attribut offset of {_local_class.module}::{_local_class} in {c} */"
697 end
698
699 init(c: MMSrcLocalClass)
700 do
701 _local_class = c
702 end
703 end
704
705 class TableEltComposite
706 special TableElt
707 attr _table: Array[LocalTableElt]
708 attr _cc: CompiledClass
709 attr _offsets: HashMap[MMLocalClass, Int]
710 redef meth length do return _table.length
711 redef meth is_related_to(c) do return c.cshe <= _cc.local_class
712
713 meth add(c: MMLocalClass, tab: Array[LocalTableElt])
714 do
715 _offsets[c] = _table.length
716 _table.append(tab)
717 end
718
719 redef meth item(i) do return _table[i]
720
721 redef meth compile_to_c(v, c) do abort
722
723 init(cc: CompiledClass)
724 do
725 _cc = cc
726 _table = new Array[LocalTableElt]
727 _offsets = new HashMap[MMLocalClass, Int]
728 end
729 end
730
731 class TableEltClassSelfId
732 special TableElt
733 redef meth is_related_to(c) do return true
734 redef meth compile_to_c(v, c)
735 do
736 var ga = v.global_analysis
737 return "{v.global_analysis.compiled_classes[c.global].id} /* {ga.color(self)}: Identity */"
738 end
739
740 init do end
741 end
742
743 class TableEltVftPointer
744 special TableElt
745 redef meth is_related_to(c) do return true
746 redef meth compile_to_c(v, c)
747 do
748 var ga = v.global_analysis
749 return "/* {ga.color(self)}: Pointer to the classtable */"
750 end
751
752 init do end
753 end
754
755 # Used to sort local class in a deterministic total order
756 # The total order superset the class refinement and the class specialisation relations
757 class ClassSorter
758 special AbstractSorter[MMLocalClass]
759 redef meth compare(a, b) do return a.compare(b)
760 init do end
761 end
762
763 redef class MMLocalClass
764 # Comparaison in a total order that superset the class refinement and the class specialisation relations
765 meth compare(b: MMLocalClass): Int
766 do
767 var a = self
768 if a == b then
769 return 0
770 else if a.module.mhe < b.module then
771 return 1
772 else if b.module.mhe < a.module then
773 return -1
774 end
775 var ar = a.cshe.rank
776 var br = b.cshe.rank
777 if ar > br then
778 return 1
779 else if br > ar then
780 return -1
781 else
782 return b.name.to_s <=> a.name.to_s
783 end
784 end
785
786 # Declaration and macros related to the class table
787 meth declare_tables_to_c(v: CompilerVisitor)
788 do
789 v.add_decl("")
790 var pi = primitive_info
791 v.add_decl("extern const classtable_elt_t VFT_{name}[];")
792 if pi == null then
793 # v.add_decl("val_t NEW_{name}(void);")
794 else if not pi.tagged then
795 var t = pi.cname
796 var tbox = "struct TBOX_{name}"
797 v.add_decl("{tbox} \{ const classtable_elt_t * vft; {t} val;};")
798 v.add_decl("val_t BOX_{name}({t} val);")
799 v.add_decl("#define UNBOX_{name}(x) ((({tbox} *)(VAL2OBJ(x)))->val)")
800 end
801 end
802
803 # Compilation of table and new (or box)
804 meth compile_tables_to_c(v: CompilerVisitor)
805 do
806 var cc = v.global_analysis.compiled_classes[self.global]
807 var ctab = cc.class_table
808 var clen = ctab.length
809 if v.global_analysis.max_class_table_length > ctab.length then
810 clen = v.global_analysis.max_class_table_length
811 end
812
813 v.add_instr("const classtable_elt_t VFT_{name}[{clen}] = \{")
814 v.indent
815 for e in ctab do
816 if e == null then
817 v.add_instr("\{0} /* Class Hole :( */,")
818 else
819 v.add_instr("\{(bigint) {e.compile_to_c(v, self)}},")
820 end
821 end
822 if clen > ctab.length then
823 v.add_instr("\{0},"*(clen-ctab.length))
824 end
825 v.unindent
826 v.add_instr("};")
827 var itab = cc.instance_table
828 for e in itab do
829 if e == null then
830 v.add_instr("/* Instance Hole :( */")
831 else
832 v.add_instr(e.compile_to_c(v, self))
833 end
834 end
835
836 var pi = primitive_info
837 if pi == null then
838 v.clear
839 var s = "val_t NEW_{name}(void)"
840 v.add_instr(s + " \{")
841 v.indent
842 var ctx_old = v.ctx
843 v.ctx = new CContext
844
845 v.method_params = ["OBJ2VAL(obj)"]
846
847 v.add_instr("obj_t obj;")
848 v.add_instr("obj = alloc(sizeof(val_t) * {itab.length});")
849 v.add_instr("obj->vft = (classtable_elt_t*)VFT_{name};")
850 for g in global_properties do
851 var p = self[g]
852 var t = p.signature.return_type
853 if p isa MMAttribute and t != null then
854 # FIXME: Not compatible with sep compilation
855 assert p isa MMSrcAttribute
856 var np = p.node
857 assert np isa AAttrPropdef
858 var ne = np.n_expr
859 if ne != null then
860 var e = ne.compile_expr(v)
861 v.add_instr("{p.global.attr_access}(obj) = {e};")
862 else
863 var pi = t.local_class.primitive_info
864 if pi != null and pi.tagged then
865 var default = t.default_cvalue
866 v.add_instr("{p.global.attr_access}(obj) = {default};")
867 end
868 end
869 end
870 end
871 v.add_instr("return OBJ2VAL(obj);")
872 ctx_old.append(v.ctx)
873 v.ctx = ctx_old
874 v.unindent
875 v.add_instr("}")
876
877 var init_table_size = cshe.greaters.length + 1
878 var init_table_decl = "int init_table[{init_table_size}] = \{0{", 0" * (init_table_size-1)}};"
879
880 for g in global_properties do
881 var p = self[g]
882 if not p.global.is_init or p.global.intro.local_class.global != global then continue
883 v.clear
884 var params = new Array[String]
885 var args = ["self"]
886 for i in [0..p.signature.arity[ do
887 params.add("val_t p{i}")
888 args.add("p{i}")
889 end
890 args.add("init_table")
891 var s = "val_t NEW_{p.global.intro.cname}({params.join(", ")})"
892 v.add_instr(s + " \{")
893 v.indent
894 v.add_instr(init_table_decl)
895 v.add_instr("val_t self = NEW_{name}();")
896 v.add_instr("{p.cname}({args.join(", ")});")
897 v.add_instr("return self;")
898 v.unindent
899 v.add_instr("}")
900 end
901 else if not pi.tagged then
902 var t = pi.cname
903 var tbox = "struct TBOX_{name}"
904 v.add_instr("val_t BOX_{name}({t} val) \{")
905 v.indent
906 v.add_instr("{tbox} *box = ({tbox}*)alloc(sizeof({tbox}));")
907 v.add_instr("box->vft = VFT_{name};")
908 v.add_instr("box->val = val;")
909 v.add_instr("return OBJ2VAL(box);")
910 v.unindent
911 v.add_instr("}")
912 end
913 end
914 end
915