X-Git-Url: http://nitlanguage.org diff --git a/src/rapid_type_analysis.nit b/src/rapid_type_analysis.nit index d1fbbed..e383656 100644 --- a/src/rapid_type_analysis.nit +++ b/src/rapid_type_analysis.nit @@ -47,6 +47,9 @@ import auto_super_init redef class ModelBuilder fun do_rapid_type_analysis(mainmodule: MModule): RapidTypeAnalysis do + var time0 = get_time + self.toolcontext.info("*** RAPID TYPE ANALYSIS ***", 1) + var model = self.model var analysis = new RapidTypeAnalysis(self, mainmodule) var nmodule = self.nmodules.first @@ -62,6 +65,10 @@ redef class ModelBuilder analysis.add_monomorphic_send(maintype, mainprop) end analysis.run_analysis + + var time1 = get_time + self.toolcontext.info("*** END RAPID TYPE ANALYSIS: {time1-time0} ***", 2) + return analysis end end @@ -102,6 +109,18 @@ class RapidTypeAnalysis # The customized method definitions that remain to visit private var todo: List[CustomizedMethodDef] = new List[CustomizedMethodDef] + # Adapt and remove nullable + # return null if we got the null type + fun cleanup_type(mtype: MType, recvtype: MClassType): nullable MClassType + do + mtype = mtype.anchor_to(self.mainmodule, recvtype) + if mtype isa MNullType then return null + if mtype isa MNullableType then mtype = mtype.mtype + assert mtype isa MClassType + assert not mtype.need_anchor + return mtype + end + # Add a live type to the pool # # If the types is already live, then do nothing. @@ -113,6 +132,7 @@ class RapidTypeAnalysis assert not mtype.need_anchor self.live_types.add(mtype) + self.check_depth(mtype) # Collect default attributes for cd in mtype.collect_mclassdefs(self.mainmodule) @@ -160,10 +180,9 @@ class RapidTypeAnalysis fun add_monomorphic_send(mtype: MClassType, mmethod: MMethod) do assert self.live_types.has(mtype) - var defs = mmethod.lookup_definitions(self.mainmodule, mtype) - if defs.is_empty then return - assert defs.length == 1 else print "conflict on {mtype} for {mmethod}: {defs.join(" ")}" - self.add_static_call(mtype, defs.first) + if not mtype.has_mproperty(self.mainmodule, mmethod) then return + var def = mmethod.lookup_first_definition(self.mainmodule, mtype) + self.add_static_call(mtype, def) end # Add a customized_methoddefs to the pool @@ -185,6 +204,15 @@ class RapidTypeAnalysis assert not mtype.need_anchor self.live_cast_types.add(mtype) + self.check_depth(mtype) + end + + fun check_depth(mtype: MClassType) + do + var d = mtype.depth + if d > 255 then + self.modelbuilder.toolcontext.fatal_error(null, "Fatal error: limitation in the rapidtype analysis engine: a type depth of {d} is too important, the problematic type is {mtype}.") + end end # Run the analysis until all visitable method definitions are visited. @@ -199,15 +227,24 @@ class RapidTypeAnalysis var vararg_rank = mr.mmethoddef.msignature.vararg_rank if vararg_rank > -1 then + var node = self.modelbuilder.mpropdef2npropdef[mr.mmethoddef] var elttype = mr.mmethoddef.msignature.mparameters[vararg_rank].mtype elttype = elttype.anchor_to(self.mainmodule, mr.receiver) var vararg = self.mainmodule.get_primitive_class("Array").get_mtype([elttype]) self.add_type(vararg) - self.add_monomorphic_send(vararg, self.mainmodule.force_get_primitive_method("with_native", vararg)) + self.add_monomorphic_send(vararg, self.modelbuilder.force_get_primitive_method(node, "with_native", vararg, self.mainmodule)) var native = self.mainmodule.get_primitive_class("NativeArray").get_mtype([elttype]) self.add_type(native) end + for i in [0..mr.mmethoddef.msignature.arity[ do + var origtype = mr.mmethoddef.mproperty.intro.msignature.mparameters[i].mtype + if not origtype.need_anchor then continue # skip non covariant stuff + var paramtype = mr.mmethoddef.msignature.mparameters[i].mtype + paramtype = self.cleanup_type(paramtype, mr.receiver).as(not null) + self.add_cast_type(paramtype) + end + if not self.modelbuilder.mpropdef2npropdef.has_key(mr.mmethoddef) then # It is an init for a class? if mr.mmethoddef.mproperty.name == "init" then @@ -367,7 +404,14 @@ private class RapidTypeVisitor do if node == null then return node.accept_rapid_type_vistor(self) - node.visit_all(self) + if node isa AExpr then + var implicit_cast_to = node.implicit_cast_to + if implicit_cast_to != null then self.add_cast_type(implicit_cast_to) + end + # RTA does not enter in AAnnotations + if not node isa AAnnotations then + node.visit_all(self) + end end # Force to get the primitive class named `name' or abort @@ -382,7 +426,7 @@ private class RapidTypeVisitor var rapidtype = cleanup_type(recv) if rapidtype == null then abort - return self.analysis.mainmodule.force_get_primitive_method(name, rapidtype) + return self.analysis.modelbuilder.force_get_primitive_method(self.current_node.as(not null), name, rapidtype, self.analysis.mainmodule) end end @@ -418,9 +462,9 @@ end redef class AArrayExpr redef fun accept_rapid_type_vistor(v) do - var mtype = self.mtype.as(not null) + var mtype = self.mtype.as(MClassType) v.add_type(mtype) - var native = v.get_class("NativeArray").get_mtype([mtype.as(MGenericType).arguments.first]) + var native = v.get_class("NativeArray").get_mtype([mtype.arguments.first]) v.add_type(native) var prop = v.get_method(mtype, "with_native") v.add_monomorphic_send(mtype, prop) @@ -447,6 +491,8 @@ redef class ASuperstringExpr v.add_type(v.get_class("NativeArray").get_mtype([v.get_class("Object").mclass_type])) var prop = v.get_method(arraytype, "join") v.add_monomorphic_send(arraytype, prop) + var prop2 = v.get_method(arraytype, "with_native") + v.add_monomorphic_send(arraytype, prop2) end end @@ -553,15 +599,9 @@ redef class ASuperExpr return end - #FIXME: we do not want an ugly static call! - var mpropdef = v.mpropdef - var mpropdefs = mpropdef.mproperty.lookup_super_definitions(mpropdef.mclassdef.mmodule, mpropdef.mclassdef.bound_mtype) - if mpropdefs.length != 1 then - debug("MPRODFEFS for super {mpropdef} for {v.receiver}: {mpropdefs.join(", ")}") - end - var msuperpropdef = mpropdefs.first - assert msuperpropdef isa MMethodDef - v.analysis.add_static_call(v.receiver, msuperpropdef) + var mpropdef = v.mpropdef.lookup_next_definition(v.analysis.mainmodule, v.receiver) + assert mpropdef isa MMethodDef + v.analysis.add_static_call(v.receiver, mpropdef) end end @@ -572,7 +612,7 @@ redef class AForExpr var colltype = self.coltype.as(not null) var itmeth = v.get_method(colltype, "iterator") v.add_send(recvtype, itmeth) - var iteratortype = itmeth.intro.msignature.return_mtype.as(MClassType).mclass.mclassdefs.first.bound_mtype + var iteratortype = itmeth.intro.msignature.return_mtype.as(MClassType).mclass.intro.bound_mtype var objtype = v.get_class("Object").mclass_type v.add_send(objtype, v.get_method(iteratortype, "is_ok")) if self.variables.length == 1 then