X-Git-Url: http://nitlanguage.org diff --git a/src/separate_compiler.nit b/src/separate_compiler.nit index 071b706..273451f 100644 --- a/src/separate_compiler.nit +++ b/src/separate_compiler.nit @@ -16,7 +16,7 @@ module separate_compiler import abstract_compiler -import layout_builders +import coloring import rapid_type_analysis # Add separate compiler specific options @@ -40,13 +40,7 @@ redef class ToolContext # --semi-global var opt_semi_global = new OptionBool("Enable all semi-global optimizations", "--semi-global") # --no-colo-dead-methods - var opt_no_colo_dead_methods = new OptionBool("Do not colorize dead methods", "--no-colo-dead-methods") - # --use-naive-coloring - var opt_bm_typing: OptionBool = new OptionBool("Colorize items incrementaly, used to simulate binary matrix typing", "--bm-typing") - # --use-mod-perfect-hashing - var opt_phmod_typing: OptionBool = new OptionBool("Replace coloration by perfect hashing (with mod operator)", "--phmod-typing") - # --use-and-perfect-hashing - var opt_phand_typing: OptionBool = new OptionBool("Replace coloration by perfect hashing (with and operator)", "--phand-typing") + var opt_colo_dead_methods = new OptionBool("Force colorization of dead methods", "--colo-dead-methods") # --tables-metrics var opt_tables_metrics: OptionBool = new OptionBool("Enable static size measuring of tables used for vft, typing and resolution", "--tables-metrics") @@ -58,10 +52,7 @@ redef class ToolContext self.option_context.add_option(self.opt_no_union_attribute) self.option_context.add_option(self.opt_no_shortcut_equate) self.option_context.add_option(self.opt_inline_coloring_numbers, opt_inline_some_methods, opt_direct_call_monomorph, opt_skip_dead_methods, opt_semi_global) - self.option_context.add_option(self.opt_no_colo_dead_methods) - self.option_context.add_option(self.opt_bm_typing) - self.option_context.add_option(self.opt_phmod_typing) - self.option_context.add_option(self.opt_phand_typing) + self.option_context.add_option(self.opt_colo_dead_methods) self.option_context.add_option(self.opt_tables_metrics) end @@ -77,6 +68,19 @@ redef class ToolContext tc.opt_skip_dead_methods.value = true end end + + var separate_compiler_phase = new SeparateCompilerPhase(self, null) +end + +class SeparateCompilerPhase + super Phase + redef fun process_mainmodule(mainmodule, given_mmodules) do + if not toolcontext.opt_separate.value then return + + var modelbuilder = toolcontext.modelbuilder + var analysis = modelbuilder.do_rapid_type_analysis(mainmodule) + modelbuilder.run_separate_compiler(mainmodule, analysis) + end end redef class ModelBuilder @@ -101,6 +105,7 @@ redef class ModelBuilder # The main function of the C compiler.new_file("{mainmodule.name}.main") + compiler.compile_nitni_global_ref_functions compiler.compile_main_function # compile methods @@ -150,10 +155,11 @@ class SeparateCompiler private var undead_types: Set[MType] = new HashSet[MType] private var live_unresolved_types: Map[MClassDef, Set[MType]] = new HashMap[MClassDef, HashSet[MType]] - private var type_layout: nullable Layout[MType] - private var resolution_layout: nullable Layout[MType] - protected var method_layout: nullable Layout[PropertyLayoutElement] - protected var attr_layout: nullable Layout[MAttribute] + private var type_ids: Map[MType, Int] + private var type_colors: Map[MType, Int] + private var opentype_colors: Map[MType, Int] + protected var method_colors: Map[PropertyLayoutElement, Int] + protected var attr_colors: Map[MAttribute, Int] init(mainmodule: MModule, mmbuilder: ModelBuilder, runtime_type_analysis: nullable RapidTypeAnalysis) do super(mainmodule, mmbuilder) @@ -171,19 +177,7 @@ class SeparateCompiler # With resolution_table_table, all live type resolution are stored in a big table: resolution_table self.header.add_decl("struct type \{ int id; const char *name; int color; short int is_nullable; const struct types *resolution_table; int table_size; int type_table[]; \}; /* general C type representing a Nit type. */") self.header.add_decl("struct instance \{ const struct type *type; const struct class *class; nitattribute_t attrs[]; \}; /* general C type representing a Nit instance. */") - - if modelbuilder.toolcontext.opt_phmod_typing.value or modelbuilder.toolcontext.opt_phand_typing.value then - self.header.add_decl("struct types \{ int mask; const struct type *types[]; \}; /* a list types (used for vts, fts and unresolved lists). */") - else - self.header.add_decl("struct types \{ int dummy; const struct type *types[]; \}; /* a list types (used for vts, fts and unresolved lists). */") - end - - if modelbuilder.toolcontext.opt_phmod_typing.value then - self.header.add_decl("#define HASH(mask, id) ((mask)%(id))") - else if modelbuilder.toolcontext.opt_phand_typing.value then - self.header.add_decl("#define HASH(mask, id) ((mask)&(id))") - end - + self.header.add_decl("struct types \{ int dummy; const struct type *types[]; \}; /* a list types (used for vts, fts and unresolved lists). */") self.header.add_decl("typedef struct instance val; /* general C type representing a Nit instance. */") end @@ -266,30 +260,14 @@ class SeparateCompiler # colorize classe properties fun do_property_coloring do - var mclasses = new HashSet[MClass].from(modelbuilder.model.mclasses) var rta = runtime_type_analysis # Layouts - var method_layout_builder: PropertyLayoutBuilder[PropertyLayoutElement] - var attribute_layout_builder: PropertyLayoutBuilder[MAttribute] - #FIXME PH and BM layouts too slow for large programs - #if modelbuilder.toolcontext.opt_bm_typing.value then - # method_layout_builder = new MMethodBMizer(self.mainmodule) - # attribute_layout_builder = new MAttributeBMizer(self.mainmodule) - #else if modelbuilder.toolcontext.opt_phmod_typing.value then - # method_layout_builder = new MMethodHasher(new PHModOperator, self.mainmodule) - # attribute_layout_builder = new MAttributeHasher(new PHModOperator, self.mainmodule) - #else if modelbuilder.toolcontext.opt_phand_typing.value then - # method_layout_builder = new MMethodHasher(new PHAndOperator, self.mainmodule) - # attribute_layout_builder = new MAttributeHasher(new PHAndOperator, self.mainmodule) - #else - - var class_layout_builder = new MClassColorer(self.mainmodule) - class_layout_builder.build_layout(mclasses) - method_layout_builder = new MPropertyColorer[PropertyLayoutElement](self.mainmodule, class_layout_builder) - attribute_layout_builder = new MPropertyColorer[MAttribute](self.mainmodule, class_layout_builder) - #end + var poset = mainmodule.flatten_mclass_hierarchy + var mclasses = new HashSet[MClass].from(poset) + var colorer = new POSetColorer[MClass] + colorer.colorize(poset) # The dead methods, still need to provide a dead color symbol var dead_methods = new Array[MMethod] @@ -302,7 +280,7 @@ class SeparateCompiler mattributes[mclass] = new HashSet[MAttribute] for mprop in self.mainmodule.properties(mclass) do if mprop isa MMethod then - if modelbuilder.toolcontext.opt_no_colo_dead_methods.value and rta != null and not rta.live_methods.has(mprop) then + if not modelbuilder.toolcontext.opt_colo_dead_methods.value and rta != null and not rta.live_methods.has(mprop) then dead_methods.add(mprop) continue end @@ -343,9 +321,10 @@ class SeparateCompiler end # methods coloration - self.method_layout = method_layout_builder.build_layout(mmethods) - self.method_tables = build_method_tables(mclasses, super_calls) - self.compile_color_consts(method_layout.pos) + var meth_colorer = new POSetBucketsColorer[MClass, PropertyLayoutElement](poset, colorer.conflicts) + method_colors = meth_colorer.colorize(mmethods) + method_tables = build_method_tables(mclasses, super_calls) + compile_color_consts(method_colors) # attribute null color to dead methods and supercalls for mproperty in dead_methods do @@ -357,168 +336,93 @@ class SeparateCompiler end # attributes coloration - self.attr_layout = attribute_layout_builder.build_layout(mattributes) - self.attr_tables = build_attr_tables(mclasses) - self.compile_color_consts(attr_layout.pos) + var attr_colorer = new POSetBucketsColorer[MClass, MAttribute](poset, colorer.conflicts) + attr_colors = attr_colorer.colorize(mattributes) + attr_tables = build_attr_tables(mclasses) + compile_color_consts(attr_colors) end fun build_method_tables(mclasses: Set[MClass], super_calls: Set[MMethodDef]): Map[MClass, Array[nullable MPropDef]] do - var layout = self.method_layout var tables = new HashMap[MClass, Array[nullable MPropDef]] for mclass in mclasses do var table = new Array[nullable MPropDef] - var supercalls = new List[MMethodDef] + tables[mclass] = table - # first, fill table from parents by reverse linearization order - var parents = new Array[MClass] - if mainmodule.flatten_mclass_hierarchy.has(mclass) then - parents = mclass.in_hierarchy(mainmodule).greaters.to_a - self.mainmodule.linearize_mclasses(parents) - end + var mproperties = self.mainmodule.properties(mclass) + var mtype = mclass.intro.bound_mtype - for parent in parents do - if parent == mclass then continue - for mproperty in self.mainmodule.properties(parent) do - if not mproperty isa MMethod then continue - if not layout.pos.has_key(mproperty) then continue - var color = layout.pos[mproperty] - if table.length <= color then - for i in [table.length .. color[ do - table[i] = null - end - end - for mpropdef in mproperty.mpropdefs do - if mpropdef.mclassdef.mclass == parent then - table[color] = mpropdef - end - end - end - - # lookup for super calls in super classes - for mmethoddef in super_calls do - for mclassdef in parent.mclassdefs do - if mclassdef.mpropdefs.has(mmethoddef) then - supercalls.add(mmethoddef) - end - end - end - end - - # then override with local properties - for mproperty in self.mainmodule.properties(mclass) do + for mproperty in mproperties do if not mproperty isa MMethod then continue - if not layout.pos.has_key(mproperty) then continue - var color = layout.pos[mproperty] + if not method_colors.has_key(mproperty) then continue + var color = method_colors[mproperty] if table.length <= color then for i in [table.length .. color[ do table[i] = null end end - for mpropdef in mproperty.mpropdefs do - if mpropdef.mclassdef.mclass == mclass then - table[color] = mpropdef - end - end + table[color] = mproperty.lookup_first_definition(mainmodule, mtype) end - # lookup for super calls in local class - for mmethoddef in super_calls do - for mclassdef in mclass.mclassdefs do - if mclassdef.mpropdefs.has(mmethoddef) then - supercalls.add(mmethoddef) - end - end - end - # insert super calls in table according to receiver - for supercall in supercalls do - var color = layout.pos[supercall] + for supercall in super_calls do + if not mtype.collect_mclassdefs(mainmodule).has(supercall.mclassdef) then continue + + var color = method_colors[supercall] if table.length <= color then for i in [table.length .. color[ do table[i] = null end end - var mmethoddef = supercall.lookup_next_definition(self.mainmodule, mclass.intro.bound_mtype) + var mmethoddef = supercall.lookup_next_definition(mainmodule, mtype) table[color] = mmethoddef end - tables[mclass] = table + end return tables end fun build_attr_tables(mclasses: Set[MClass]): Map[MClass, Array[nullable MPropDef]] do - var layout = self.attr_layout var tables = new HashMap[MClass, Array[nullable MPropDef]] for mclass in mclasses do var table = new Array[nullable MPropDef] - # first, fill table from parents by reverse linearization order - var parents = new Array[MClass] - if mainmodule.flatten_mclass_hierarchy.has(mclass) then - parents = mclass.in_hierarchy(mainmodule).greaters.to_a - self.mainmodule.linearize_mclasses(parents) - end - for parent in parents do - if parent == mclass then continue - for mproperty in self.mainmodule.properties(parent) do - if not mproperty isa MAttribute then continue - var color = layout.pos[mproperty] - if table.length <= color then - for i in [table.length .. color[ do - table[i] = null - end - end - for mpropdef in mproperty.mpropdefs do - if mpropdef.mclassdef.mclass == parent then - table[color] = mpropdef - end - end - end - end + tables[mclass] = table + + var mproperties = self.mainmodule.properties(mclass) + var mtype = mclass.intro.bound_mtype - # then override with local properties - for mproperty in self.mainmodule.properties(mclass) do + for mproperty in mproperties do if not mproperty isa MAttribute then continue - var color = layout.pos[mproperty] + if not attr_colors.has_key(mproperty) then continue + var color = attr_colors[mproperty] if table.length <= color then for i in [table.length .. color[ do table[i] = null end end - for mpropdef in mproperty.mpropdefs do - if mpropdef.mclassdef.mclass == mclass then - table[color] = mpropdef - end - end + table[color] = mproperty.lookup_first_definition(mainmodule, mtype) end - tables[mclass] = table end return tables end # colorize live types of the program private fun do_type_coloring: POSet[MType] do + # Collect types to colorize + var live_types = runtime_type_analysis.live_types + var live_cast_types = runtime_type_analysis.live_cast_types var mtypes = new HashSet[MType] - mtypes.add_all(self.runtime_type_analysis.live_types) - mtypes.add_all(self.runtime_type_analysis.live_cast_types) + mtypes.add_all(live_types) + mtypes.add_all(live_cast_types) for c in self.box_kinds.keys do mtypes.add(c.mclass_type) end - # Typing Layout - var layout_builder: TypingLayoutBuilder[MType] - if modelbuilder.toolcontext.opt_bm_typing.value then - layout_builder = new MTypeBMizer(self.mainmodule) - else if modelbuilder.toolcontext.opt_phmod_typing.value then - layout_builder = new MTypeHasher(new PHModOperator, self.mainmodule) - else if modelbuilder.toolcontext.opt_phand_typing.value then - layout_builder = new MTypeHasher(new PHAndOperator, self.mainmodule) - else - layout_builder = new MTypeColorer(self.mainmodule) - end - - # colorize types - self.type_layout = layout_builder.build_layout(mtypes) - var poset = layout_builder.poset.as(not null) - self.type_tables = self.build_type_tables(poset) + # Compute colors + var poset = poset_from_mtypes(mtypes) + var colorer = new POSetColorer[MType] + colorer.colorize(poset) + type_ids = colorer.ids + type_colors = colorer.colors + type_tables = build_type_tables(poset) # VT and FT are stored with other unresolved types in the big resolution_tables self.compile_resolution_tables(mtypes) @@ -526,19 +430,27 @@ class SeparateCompiler return poset end + private fun poset_from_mtypes(mtypes: Set[MType]): POSet[MType] do + var poset = new POSet[MType] + for e in mtypes do + poset.add_node(e) + for o in mtypes do + if e == o then continue + if e.is_subtype(mainmodule, null, o) then + poset.add_edge(e, o) + end + end + end + return poset + end + # Build type tables fun build_type_tables(mtypes: POSet[MType]): Map[MType, Array[nullable MType]] do var tables = new HashMap[MType, Array[nullable MType]] - var layout = self.type_layout for mtype in mtypes do var table = new Array[nullable MType] for sup in mtypes[mtype].greaters do - var color: Int - if layout isa PHLayout[MType, MType] then - color = layout.hashes[mtype][sup] - else - color = layout.pos[sup] - end + var color = type_colors[sup] if table.length <= color then for i in [table.length .. color[ do table[i] = null @@ -571,18 +483,9 @@ class SeparateCompiler end # Compute the table layout with the prefered method - var resolution_builder: ResolutionLayoutBuilder - if modelbuilder.toolcontext.opt_bm_typing.value then - resolution_builder = new ResolutionBMizer - else if modelbuilder.toolcontext.opt_phmod_typing.value then - resolution_builder = new ResolutionHasher(new PHModOperator) - else if modelbuilder.toolcontext.opt_phand_typing.value then - resolution_builder = new ResolutionHasher(new PHAndOperator) - else - resolution_builder = new ResolutionColorer - end - self.resolution_layout = resolution_builder.build_layout(mtype2unresolved) - self.resolution_tables = self.build_resolution_tables(mtype2unresolved) + var colorer = new BucketsColorer[MType, MType] + opentype_colors = colorer.colorize(mtype2unresolved) + resolution_tables = self.build_resolution_tables(mtype2unresolved) # Compile a C constant for each collected unresolved type. # Either to a color, or to -1 if the unresolved type is dead (no live receiver can require it) @@ -592,8 +495,8 @@ class SeparateCompiler end var all_unresolved_types_colors = new HashMap[MType, Int] for t in all_unresolved do - if self.resolution_layout.pos.has_key(t) then - all_unresolved_types_colors[t] = self.resolution_layout.pos[t] + if opentype_colors.has_key(t) then + all_unresolved_types_colors[t] = opentype_colors[t] else all_unresolved_types_colors[t] = -1 end @@ -609,16 +512,10 @@ class SeparateCompiler fun build_resolution_tables(elements: Map[MClassType, Set[MType]]): Map[MClassType, Array[nullable MType]] do var tables = new HashMap[MClassType, Array[nullable MType]] - var layout = self.resolution_layout for mclasstype, mtypes in elements do var table = new Array[nullable MType] for mtype in mtypes do - var color: Int - if layout isa PHLayout[MClassType, MType] then - color = layout.hashes[mclasstype][mtype] - else - color = layout.pos[mtype] - end + var color = opentype_colors[mtype] if table.length <= color then for i in [table.length .. color[ do table[i] = null @@ -655,7 +552,6 @@ class SeparateCompiler fun compile_type_to_c(mtype: MType) do assert not mtype.need_anchor - var layout = self.type_layout var is_live = mtype isa MClassType and runtime_type_analysis.live_types.has(mtype) var is_cast_live = runtime_type_analysis.live_cast_types.has(mtype) var c_name = mtype.c_name @@ -670,7 +566,7 @@ class SeparateCompiler # type id (for cast target) if is_cast_live then - v.add_decl("{layout.ids[mtype]},") + v.add_decl("{type_ids[mtype]},") else v.add_decl("-1, /*CAST DEAD*/") end @@ -680,11 +576,7 @@ class SeparateCompiler # type color (for cast target) if is_cast_live then - if layout isa PHLayout[MType, MType] then - v.add_decl("{layout.masks[mtype]},") - else - v.add_decl("{layout.pos[mtype]},") - end + v.add_decl("{type_colors[mtype]},") else v.add_decl("-1, /*CAST DEAD*/") end @@ -698,8 +590,7 @@ class SeparateCompiler # resolution table (for receiver) if is_live then - var mclass_type = mtype - if mclass_type isa MNullableType then mclass_type = mclass_type.mtype + var mclass_type = mtype.as_notnullable assert mclass_type isa MClassType if resolution_tables[mclass_type].is_empty then v.add_decl("NULL, /*NO RESOLUTIONS*/") @@ -720,7 +611,7 @@ class SeparateCompiler if stype == null then v.add_decl("-1, /* empty */") else - v.add_decl("{layout.ids[stype]}, /* {stype} */") + v.add_decl("{type_ids[stype]}, /* {stype} */") end end v.add_decl("\},") @@ -732,14 +623,7 @@ class SeparateCompiler fun compile_type_resolution_table(mtype: MType) do - var mclass_type: MClassType - if mtype isa MNullableType then - mclass_type = mtype.mtype.as(MClassType) - else - mclass_type = mtype.as(MClassType) - end - - var layout = self.resolution_layout + var mclass_type = mtype.as_notnullable.as(MClassType) # extern const struct resolution_table_X resolution_table_X self.provide_declaration("resolution_table_{mtype.c_name}", "extern const struct types resolution_table_{mtype.c_name};") @@ -747,11 +631,7 @@ class SeparateCompiler # const struct fts_table_X fts_table_X var v = new_visitor v.add_decl("const struct types resolution_table_{mtype.c_name} = \{") - if layout isa PHLayout[MClassType, MType] then - v.add_decl("{layout.masks[mclass_type]},") - else - v.add_decl("0, /* dummy */") - end + v.add_decl("0, /* dummy */") v.add_decl("\{") for t in self.resolution_tables[mclass_type] do if t == null then @@ -762,7 +642,7 @@ class SeparateCompiler # the value stored is tv. var tv = t.resolve_for(mclass_type, mclass_type, self.mainmodule, true) # FIXME: What typeids means here? How can a tv not be live? - if self.type_layout.ids.has_key(tv) then + if type_ids.has_key(tv) then v.require_declaration("type_{tv.c_name}") v.add_decl("&type_{tv.c_name}, /* {t}: {tv} */") else @@ -898,7 +778,7 @@ class SeparateCompiler v.add_abort("type null") v.add("\}") v.add("if({t}->table_size == 0) \{") - v.add("fprintf(stderr, \"Insantiation of a dead type: %s\\n\", {t}->name);") + v.add("PRINT_ERROR(\"Insantiation of a dead type: %s\\n\", {t}->name);") v.add_abort("type dead") v.add("\}") end @@ -985,9 +865,17 @@ class SeparateCompiler redef fun compile_nitni_structs do - self.header.add_decl("struct nitni_instance \{struct instance *value;\};") + self.header.add_decl """ +struct nitni_instance \{ + struct nitni_instance *next, + *prev; /* adjacent global references in global list */ + int count; /* number of time this global reference has been marked */ + struct instance *value; +\}; +""" + super end - + redef fun finalize_ffi_for_module(mmodule) do var old_module = self.mainmodule @@ -1032,19 +920,21 @@ class SeparateCompilerVisitor var res = self.new_var(mtype) if compiler.runtime_type_analysis != null and not compiler.runtime_type_analysis.live_types.has(valtype) then self.add("/*no autobox from {value.mtype} to {mtype}: {value.mtype} is not live! */") - self.add("printf(\"Dead code executed!\\n\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);") return res end self.require_declaration("BOX_{valtype.c_name}") self.add("{res} = BOX_{valtype.c_name}({value}); /* autobox from {value.mtype} to {mtype} */") return res - else if value.mtype.ctype == "void*" and mtype.ctype == "void*" then + else if (value.mtype.ctype == "void*" and mtype.ctype == "void*") or + (value.mtype.ctype == "char*" and mtype.ctype == "void*") or + (value.mtype.ctype == "void*" and mtype.ctype == "char*") then return value else # Bad things will appen! var res = self.new_var(mtype) self.add("/* {res} left unintialized (cannot convert {value.mtype} to {mtype}) */") - self.add("printf(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"Cast error: Cannot cast %s to %s.\\n\", \"{value.mtype}\", \"{mtype}\"); show_backtrace(1);") return res end end @@ -1435,7 +1325,7 @@ class SeparateCompilerVisitor self.require_declaration(mtype.const_color) var col = mtype.const_color self.add("if({col} == -1) \{") - self.add("fprintf(stderr, \"Resolution of a dead open type: %s\\n\", \"{mtype.to_s.escape_to_c}\");") + self.add("PRINT_ERROR(\"Resolution of a dead open type: %s\\n\", \"{mtype.to_s.escape_to_c}\");") self.add_abort("open type dead") self.add("\}") end @@ -1448,7 +1338,7 @@ class SeparateCompilerVisitor add_abort("cast type null") add("\}") add("if({t}->id == -1 || {t}->color == -1) \{") - add("fprintf(stderr, \"Try to cast on a dead cast type: %s\\n\", {t}->name);") + add("PRINT_ERROR(\"Try to cast on a dead cast type: %s\\n\", {t}->name);") add_abort("cast type dead") add("\}") end @@ -1463,11 +1353,7 @@ class SeparateCompilerVisitor var recv = self.frame.arguments.first var recv_type_info = self.type_info(recv) self.require_declaration(mtype.const_color) - if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - return self.new_expr("NEW_{mtype.mclass.c_name}({recv_type_info}->resolution_table->types[HASH({recv_type_info}->resolution_table->mask, {mtype.const_color})])", mtype) - else - return self.new_expr("NEW_{mtype.mclass.c_name}({recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype) - end + return self.new_expr("NEW_{mtype.mclass.c_name}({recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype) end compiler.undead_types.add(mtype) self.require_declaration("type_{mtype.c_name}") @@ -1514,11 +1400,7 @@ class SeparateCompilerVisitor hardening_live_open_type(mtype) link_unresolved_type(self.frame.mpropdef.mclassdef, mtype) self.require_declaration(mtype.const_color) - if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - self.add("{type_struct} = {recv_type_info}->resolution_table->types[HASH({recv_type_info}->resolution_table->mask, {mtype.const_color})];") - else - self.add("{type_struct} = {recv_type_info}->resolution_table->types[{mtype.const_color}];") - end + self.add("{type_struct} = {recv_type_info}->resolution_table->types[{mtype.const_color}];") if compiler.modelbuilder.toolcontext.opt_typing_test_metrics.value then self.compiler.count_type_test_unresolved[tag] += 1 self.add("count_type_test_unresolved_{tag}++;") @@ -1543,7 +1425,7 @@ class SeparateCompilerVisitor self.add("count_type_test_resolved_{tag}++;") end else - self.add("printf(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); show_backtrace(1);") + self.add("PRINT_ERROR(\"NOT YET IMPLEMENTED: type_test(%s, {mtype}).\\n\", \"{value.inspect}\"); show_backtrace(1);") end # check color is in table @@ -1553,9 +1435,6 @@ class SeparateCompilerVisitor self.add("\} else \{") end var value_type_info = self.type_info(value) - if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - self.add("{cltype} = HASH({value_type_info}->color, {idtype});") - end self.add("if({cltype} >= {value_type_info}->table_size) \{") self.add("{res} = 0;") self.add("\} else \{") @@ -1700,8 +1579,7 @@ class SeparateCompilerVisitor fun can_be_primitive(value: RuntimeVariable): Bool do - var t = value.mcasttype - if t isa MNullableType then t = t.mtype + var t = value.mcasttype.as_notnullable if not t isa MClassType then return false var k = t.mclass.kind return k == interface_kind or t.ctype != "val*" @@ -1731,7 +1609,7 @@ class SeparateCompilerVisitor return res end - fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable + redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable do var mtype = self.get_class("NativeArray").get_mtype([elttype]) self.require_declaration("NEW_{mtype.mclass.c_name}") @@ -1743,11 +1621,7 @@ class SeparateCompilerVisitor var recv = self.frame.arguments.first var recv_type_info = self.type_info(recv) self.require_declaration(mtype.const_color) - if compiler.modelbuilder.toolcontext.opt_phmod_typing.value or compiler.modelbuilder.toolcontext.opt_phand_typing.value then - return self.new_expr("NEW_{mtype.mclass.c_name}({length}, {recv_type_info}->resolution_table->types[HASH({recv_type_info}->resolution_table->mask, {mtype.const_color})])", mtype) - else - return self.new_expr("NEW_{mtype.mclass.c_name}({length}, {recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype) - end + return self.new_expr("NEW_{mtype.mclass.c_name}({length}, {recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype) end compiler.undead_types.add(mtype) self.require_declaration("type_{mtype.c_name}") @@ -1993,10 +1867,14 @@ redef class MClass end end +interface PropertyLayoutElement end + redef class MProperty + super PropertyLayoutElement fun const_color: String do return "COLOR_{c_name}" end redef class MPropDef + super PropertyLayoutElement fun const_color: String do return "COLOR_{c_name}" end