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