X-Git-Url: http://nitlanguage.org diff --git a/src/separate_compiler.nit b/src/separate_compiler.nit index fe9000c..4dfbeb0 100644 --- a/src/separate_compiler.nit +++ b/src/separate_compiler.nit @@ -105,7 +105,9 @@ 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 + compiler.compile_finalizer_function # compile methods for m in mainmodule.in_importation.greaters do @@ -263,8 +265,8 @@ class SeparateCompiler var rta = runtime_type_analysis # Layouts - var mclasses = new HashSet[MClass].from(modelbuilder.model.mclasses) var poset = mainmodule.flatten_mclass_hierarchy + var mclasses = new HashSet[MClass].from(poset) var colorer = new POSetColorer[MClass] colorer.colorize(poset) @@ -345,45 +347,12 @@ class SeparateCompiler 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 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 == 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 method_colors.has_key(mproperty) then continue var color = method_colors[mproperty] @@ -392,33 +361,22 @@ class SeparateCompiler 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 + 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 @@ -427,46 +385,22 @@ class SeparateCompiler 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 = 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 == parent then - table[color] = mpropdef - end - end - end - end + tables[mclass] = table - # then override with local properties - for mproperty in self.mainmodule.properties(mclass) do + var mproperties = self.mainmodule.properties(mclass) + var mtype = mclass.intro.bound_mtype + + for mproperty in mproperties do if not mproperty isa MAttribute then continue + 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 @@ -657,8 +591,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*/") @@ -691,12 +624,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 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};") @@ -838,6 +766,7 @@ class SeparateCompiler v.require_declaration("class_{c_name}") v.add("{res}->class = &class_{c_name};") self.generate_init_attr(v, res, mtype) + v.set_finalizer res v.add("return {res};") end v.add("\}") @@ -851,7 +780,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 @@ -938,9 +867,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 @@ -985,19 +922,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 @@ -1019,11 +958,12 @@ class SeparateCompilerVisitor do var rta = compiler.runtime_type_analysis var recv = args.first.mtype - if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null then + var mmethod = callsite.mproperty + # TODO: Inlining of new-style constructors + if compiler.modelbuilder.toolcontext.opt_direct_call_monomorph.value and rta != null and not mmethod.is_root_init then var tgs = rta.live_targets(callsite) if tgs.length == 1 then # DIRECT CALL - var mmethod = callsite.mproperty self.varargize(mmethod.intro, mmethod.intro.msignature.as(not null), args) var res0 = before_send(mmethod, args) var res = call(tgs.first, tgs.first.mclassdef.bound_mtype, args) @@ -1070,7 +1010,7 @@ class SeparateCompilerVisitor do var res: nullable RuntimeVariable = null var recv = arguments.first - var consider_null = not self.compiler.modelbuilder.toolcontext.opt_no_check_other.value or mmethod.name == "==" or mmethod.name == "!=" + var consider_null = not self.compiler.modelbuilder.toolcontext.opt_no_check_null.value or mmethod.name == "==" or mmethod.name == "!=" var maybenull = recv.mcasttype isa MNullableType and consider_null if maybenull then self.add("if ({recv} == NULL) \{") @@ -1388,7 +1328,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 @@ -1401,7 +1341,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 @@ -1488,7 +1428,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 @@ -1642,8 +1582,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*" @@ -1673,7 +1612,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}") @@ -1708,7 +1647,7 @@ class SeparateCompilerVisitor return else if pname == "copy_to" then var recv1 = "((struct instance_{nclass.c_instance_name}*){arguments[1]})->values" - self.add("memcpy({recv1}, {recv}, {arguments[2]}*sizeof({elttype.ctype}));") + self.add("memmove({recv1}, {recv}, {arguments[2]}*sizeof({elttype.ctype}));") return end end