+ super AbstractCompiler
+
+ # Cache for classid
+ protected var classids: HashMap[MClassType, String] = new HashMap[MClassType, String]
+
+ # The result of the RTA (used to know live types and methods)
+ var runtime_type_analysis: RapidTypeAnalysis
+
+ private var undead_types: Set[MType] = new HashSet[MType]
+ private var partial_types: Set[MType] = new HashSet[MType]
+
+ private var type_layout_builder: TypeLayoutBuilder
+ private var type_layout: nullable TypeLayout
+ private var type_tables: nullable Map[MType, Array[nullable MType]] = null
+
+ private var live_unanchored_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]]
+
+ private var unanchored_types_colors: nullable Map[MType, Int]
+ private var unanchored_types_tables: nullable Map[MClassType, Array[nullable MType]]
+ private var unanchored_types_masks: nullable Map[MClassType, Int]
+
+ protected var method_colors: Map[MMethod, Int]
+ protected var method_tables: Map[MClass, Array[nullable MMethodDef]]
+
+ protected var attr_colors: Map[MAttribute, Int]
+ protected var attr_tables: Map[MClass, Array[nullable MAttributeDef]]
+
+ protected var vt_colors: Map[MVirtualTypeProp, Int]
+ protected var vt_tables: Map[MClass, Array[nullable MVirtualTypeDef]]
+ protected var vt_masks: nullable Map[MClass, Int]
+
+ private var ft_colors: nullable Map[MParameterType, Int]
+ private var ft_tables: nullable Map[MClass, Array[nullable MParameterType]]
+ private var ft_masks: nullable Map[MClass, Int]
+
+ init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: RapidTypeAnalysis) do
+ super
+ self.header = new_visitor
+ self.init_layout_builders
+ self.runtime_type_analysis = runtime_type_analysis
+ self.do_property_coloring
+ self.compile_box_kinds
+ end
+
+ protected fun init_layout_builders do
+ # Typing Layout
+ if modelbuilder.toolcontext.opt_bm_typing.value then
+ self.type_layout_builder = new BMTypeLayoutBuilder(self.mainmodule)
+ else if modelbuilder.toolcontext.opt_phmod_typing.value then
+ self.type_layout_builder = new PHTypeLayoutBuilder(self.mainmodule, new PHModOperator)
+ self.header.add_decl("#define HASH(mask, id) ((mask)%(id))")
+ else if modelbuilder.toolcontext.opt_phand_typing.value then
+ self.type_layout_builder = new PHTypeLayoutBuilder(self.mainmodule, new PHAndOperator)
+ self.header.add_decl("#define HASH(mask, id) ((mask)&(id))")
+ else
+ self.type_layout_builder = new CLTypeLayoutBuilder(self.mainmodule)
+ end
+ end
+
+ redef fun compile_header_structs do
+ self.header.add_decl("typedef void(*nitmethod_t)(void); /* general C type representing a Nit method. */")
+ self.compile_header_attribute_structs
+ self.header.add_decl("struct class \{ int box_kind; nitmethod_t vft[1]; \}; /* general C type representing a Nit class. */")
+
+ # With unanchored_table, all live type resolution are stored in a big table: unanchored_table
+ self.header.add_decl("struct type \{ int id; const char *name; int color; short int is_nullable; struct types *unanchored_table; int table_size; int type_table[1]; \}; /* general C type representing a Nit type. */")
+
+ if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then
+ self.header.add_decl("struct types \{ int mask; struct type *types[1]; \}; /* a list types (used for vts, fts and unanchored lists). */")
+ else
+ self.header.add_decl("struct types \{ struct type *types[1]; \}; /* a list types (used for vts, fts and unanchored lists). */")
+ end
+
+ self.header.add_decl("typedef struct \{ struct type *type; struct class *class; nitattribute_t attrs[1]; \} val; /* general C type representing a Nit instance. */")
+ end