+ # colorize live types of the program
+ private fun do_global_type_coloring: Set[MClassType] do
+ var mtypes = new HashSet[MClassType]
+ #print "undead types:"
+ #for t in self.undead_types do
+ # print t
+ #end
+ #print "live types:"
+ #for t in runtime_type_analysis.live_types do
+ # print t
+ #end
+ #print "cast types:"
+ #for t in runtime_type_analysis.live_cast_types do
+ # print t
+ #end
+ #print "--"
+ mtypes.add_all(self.runtime_type_analysis.live_types)
+ mtypes.add_all(self.runtime_type_analysis.live_cast_types)
+ mtypes.add_all(self.undead_types)
+
+ # add formal types arguments to mtypes
+ for mtype in mtypes do
+ if mtype isa MGenericType then
+ #TODO do it recursive
+ for ft in mtype.arguments do
+ if ft isa MNullableType then ft = ft.mtype
+ mtypes.add(ft.as(MClassType))
+ end
+ end
+ end
+
+ # set type unique id
+ for mtype in mtypes do
+ self.typeids[mtype] = self.typeids.length
+ end
+
+ # build livetypes tables
+ self.livetypes_tables = new HashMap[MClass, Array[nullable Object]]
+ self.livetypes_tables_sizes = new HashMap[MClass, Array[Int]]
+ for mtype in mtypes do
+ if mtype isa MGenericType then
+ var table: Array[nullable Object]
+ var sizes: Array[Int]
+ if livetypes_tables.has_key(mtype.mclass) then
+ table = livetypes_tables[mtype.mclass]
+ else
+ table = new Array[nullable Object]
+ self.livetypes_tables[mtype.mclass] = table
+ end
+ if livetypes_tables_sizes.has_key(mtype.mclass) then
+ sizes = livetypes_tables_sizes[mtype.mclass]
+ else
+ sizes = new Array[Int]
+ self.livetypes_tables_sizes[mtype.mclass] = sizes
+ end
+ build_livetype_table(mtype, 0, table, sizes)
+ end
+ end
+
+ # colorize
+ var type_coloring = new TypeColoring(self.mainmodule, self.runtime_type_analysis)
+ self.type_colors = type_coloring.colorize(mtypes)
+ self.type_tables = type_coloring.build_type_tables(mtypes, type_colors)
+
+ return mtypes
+ end
+
+ # build live gentype table recursively
+ private fun build_livetype_table(mtype: MGenericType, current_rank: Int, table: Array[nullable Object], sizes: Array[Int]) do
+ var ft = mtype.arguments[current_rank]
+ if ft isa MNullableType then ft = ft.mtype
+ var id = self.typeids[ft.as(MClassType)]
+
+ if current_rank >= sizes.length then
+ sizes[current_rank] = id + 1
+ else if id >= sizes[current_rank] then
+ sizes[current_rank] = id + 1
+ end
+
+ if id > table.length then
+ for i in [table.length .. id[ do table[i] = null
+ end
+
+ if current_rank == mtype.arguments.length - 1 then
+ table[id] = mtype
+ else
+ var ft_table = new Array[nullable Object]
+ table[id] = ft_table
+ build_livetype_table(mtype, current_rank + 1, ft_table, sizes)
+ end
+ end
+
+ private fun add_to_livetypes_table(table: Array[nullable Object], ft: MClassType) do
+ var id = self.typeids[ft]
+ for i in [table.length .. id[ do
+ table[i] = null
+ end
+ table[id] = ft
+ end
+
+ private fun compile_livetype_table(table: Array[nullable Object], buffer: Buffer, depth: Int, max: Int) do
+ for obj in table do
+ if obj == null then
+ if depth == max then
+ buffer.append("NULL,\n")
+ else
+ buffer.append("\{\},\n")
+ end
+ else if obj isa MClassType then
+ buffer.append("(struct type*) &type_{obj.c_name}, /* {obj} */\n")
+ else if obj isa Array[nullable Object] then
+ buffer.append("\{\n")
+ compile_livetype_table(obj, buffer, depth + 1, max)
+ buffer.append("\},\n")
+ end
+ end
+ end
+
+ # declare live generic types tables selection
+ private fun compile_live_gentype_to_c(mclass: MClass) do
+ if mclass.arity > 0 then
+ if self.livetypes_tables.has_key(mclass) then
+ var table = self.livetypes_tables[mclass]
+ var sign = self.livetypes_tables_sizes[mclass]
+ var table_buffer = new Buffer.from("const struct type *livetypes_{mclass.c_name}[{sign.join("][")}] = \{\n")
+ compile_livetype_table(table, table_buffer, 1, mclass.arity)
+ table_buffer.append("\};")
+
+ var v = new SeparateCompilerVisitor(self)
+ self.header.add_decl("extern const struct type *livetypes_{mclass.c_name}[{sign.join("][")}];")
+ v.add_decl(table_buffer.to_s)
+ else
+ var sign = new Array[Int].filled_with(0, mclass.arity)
+ var v = new SeparateCompilerVisitor(self)
+ self.header.add_decl("extern const struct type *livetypes_{mclass.c_name}[{sign.join("][")}];")
+ v.add_decl("const struct type *livetypes_{mclass.c_name}[{sign.join("][")}];")
+ end
+ end
+ end
+