From: Jean Privat Date: Fri, 28 Mar 2014 22:13:12 +0000 (-0400) Subject: Merge: CallSite on AFor and ARange X-Git-Tag: v0.6.5~2 X-Git-Url: http://nitlanguage.org?hp=-c Merge: CallSite on AFor and ARange Use CallSite to resolve and type some implicit services. Subsequent phases will like them! Currenlty: all the AFor and ARange services are converted and tools updated. TODO: Array and SuperString Pull-Request: #370 Reviewed-by: Alexandre Terrasa --- 2f12e8bec33810fd7666fe1a06298af357de1da1 diff --combined src/naive_interpreter.nit index db528b8,730ea74..4bd3267 --- a/src/naive_interpreter.nit +++ b/src/naive_interpreter.nit @@@ -249,7 -249,7 +249,7 @@@ private class NaiveInterprete # Return a new native string initialized with `txt` fun native_string_instance(txt: String): Instance do - var val = new Buffer.from(txt) + var val = new FlatBuffer.from(txt) val.add('\0') var ic = self.mainmodule.get_primitive_class("NativeString") return new PrimitiveInstance[Buffer](ic.mclass_type, val) @@@ -264,7 -264,7 +264,7 @@@ # Return a stack stace. One line per function fun stack_trace: String do - var b = new Buffer + var b = new FlatBuffer b.append(",---- Stack trace -- - - -\n") for f in frames do b.append("| {f.mpropdef} ({f.current_node.location})\n") @@@ -771,7 -771,7 +771,7 @@@ redef class AInternMethPropde return null else if pname == "copy_to" then # sig= copy_to(dest: NativeString, length: Int, from: Int, to: Int) - var destval = args[1].val.as(Buffer) + var destval = args[1].val.as(FlatBuffer) var lenval = args[2].to_i var fromval = args[3].to_i var toval = args[4].to_i @@@ -787,7 -787,7 +787,7 @@@ if toval + lenval >= destval.length then debug("Illegal access on {destval} for element {toval}+{lenval}/{destval.length}") end - recvval.copy(fromval, lenval, destval, toval) + recvval.as(FlatBuffer).copy(fromval, lenval, destval, toval) return null else if pname == "atoi" then return v.int_instance(recvval.to_i) @@@ -874,12 -874,12 +874,12 @@@ redef class AExternMethPropde var recvval = args.first.val if pname == "io_write" then var a1 = args[1].val.as(Buffer) - recvval.as(OStream).write(a1.substring(0, args[2].to_i)) + recvval.as(OStream).write(a1.substring(0, args[2].to_i).to_s) return args[2] else if pname == "io_read" then var str = recvval.as(IStream).read(args[2].to_i) var a1 = args[1].val.as(Buffer) - new Buffer.from(str).copy(0, str.length, a1, 0) + new FlatBuffer.from(str).copy(0, str.length, a1.as(FlatBuffer), 0) return v.int_instance(str.length) else if pname == "io_close" then recvval.as(IOS).close @@@ -1261,19 -1261,19 +1261,19 @@@ redef class AForExp if col.mtype isa MNullType then fatal(v, "Receiver is null") #self.debug("col {col}") - var iter = v.send(v.force_get_primitive_method("iterator", col.mtype), [col]).as(not null) + var iter = v.callsite(method_iterator, [col]).as(not null) #self.debug("iter {iter}") loop - var isok = v.send(v.force_get_primitive_method("is_ok", iter.mtype), [iter]).as(not null) + var isok = v.callsite(method_is_ok, [iter]).as(not null) if not isok.is_true then return if self.variables.length == 1 then - var item = v.send(v.force_get_primitive_method("item", iter.mtype), [iter]).as(not null) + var item = v.callsite(method_item, [iter]).as(not null) #self.debug("item {item}") v.frame.map[self.variables.first] = item else if self.variables.length == 2 then - var key = v.send(v.force_get_primitive_method("key", iter.mtype), [iter]).as(not null) + var key = v.callsite(method_key, [iter]).as(not null) v.frame.map[self.variables[0]] = key - var item = v.send(v.force_get_primitive_method("item", iter.mtype), [iter]).as(not null) + var item = v.callsite(method_item, [iter]).as(not null) v.frame.map[self.variables[1]] = item else abort @@@ -1282,7 -1282,7 +1282,7 @@@ if v.is_break(self.escapemark) then return v.is_continue(self.escapemark) # Clear the break if v.is_escaping then return - v.send(v.force_get_primitive_method("next", iter.mtype), [iter]) + v.callsite(method_next, [iter]) end end end @@@ -1427,7 -1427,7 +1427,7 @@@ redef class ACrangeExp var mtype = v.unanchor_type(self.mtype.as(not null)) var res = new MutableInstance(mtype) v.init_instance(res) - v.send(v.force_get_primitive_method("init", mtype), [res, e1, e2]) + v.callsite(init_callsite, [res, e1, e2]) return res end end @@@ -1442,7 -1442,7 +1442,7 @@@ redef class AOrangeExp var mtype = v.unanchor_type(self.mtype.as(not null)) var res = new MutableInstance(mtype) v.init_instance(res) - v.send(v.force_get_primitive_method("without_last", mtype), [res, e1, e2]) + v.callsite(init_callsite, [res, e1, e2]) return res end end diff --combined src/rapid_type_analysis.nit index 978fab4,aad2de0..c68d33a --- a/src/rapid_type_analysis.nit +++ b/src/rapid_type_analysis.nit @@@ -31,8 -31,6 +31,8 @@@ import auto_super_ini import csv # for live_types_to_csv import ordered_tree # for live_methods_to_tree +private import more_collections + redef class ModelBuilder fun do_rapid_type_analysis(mainmodule: MModule): RapidTypeAnalysis do @@@ -77,36 -75,6 +77,36 @@@ class RapidTypeAnalysi # Live methods. var live_methods = new HashSet[MMethod] + # Live callsites. + var live_callsites = new HashSet[CallSite] + + private var live_targets_cache = new HashMap2[MType, MProperty, Set[MMethodDef]] + + # The live targets of a specific callsite. + fun live_targets(callsite: CallSite): Set[MMethodDef] + do + var mtype = callsite.recv + var anchor = callsite.anchor + if anchor != null then mtype = mtype.anchor_to(callsite.mmodule, anchor) + if mtype isa MNullableType then mtype = mtype.mtype + assert mtype isa MClassType + mtype = mtype.mclass.intro.bound_mtype + var mproperty = callsite.mproperty + var res = live_targets_cache[mtype, mproperty] + if res != null then return res + res = new ArraySet[MMethodDef] + live_targets_cache[mtype, mproperty] = res + + for c in live_classes do + var tc = c.intro.bound_mtype + if not tc.is_subtype(mainmodule, null, mtype) then continue + var d = mproperty.lookup_first_definition(mainmodule, tc) + res.add d + end + + return res + end + # Live call-to-super. var live_super_sends = new HashSet[MMethodDef] @@@ -474,10 -442,7 +474,10 @@@ class RapidTypeVisito fun add_cast_type(mtype: MType) do analysis.add_cast(mtype) - fun add_callsite(callsite: nullable CallSite) do if callsite != null then analysis.add_send(callsite.recv, callsite.mproperty) + fun add_callsite(callsite: nullable CallSite) do if callsite != null then + analysis.add_send(callsite.recv, callsite.mproperty) + analysis.live_callsites.add(callsite) + end end ### @@@ -550,8 -515,7 +550,7 @@@ redef class ACrangeExp do var mtype = self.mtype.as(MClassType) v.add_type(mtype) - var prop = v.get_method(mtype, "init") - v.add_monomorphic_send(mtype, prop) + v.add_callsite(init_callsite) end end @@@ -560,8 -524,7 +559,7 @@@ redef class AOrangeExp do var mtype = self.mtype.as(MClassType) v.add_type(mtype) - var prop = v.get_method(mtype, "without_last") - v.add_monomorphic_send(mtype, prop) + v.add_callsite(init_callsite) end end @@@ -640,22 -603,17 +638,17 @@@ en redef class AForExpr redef fun accept_rapid_type_visitor(v) do - var recvtype = self.n_expr.mtype.as(not null) - 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.intro.bound_mtype - var objtype = v.get_class("Object").mclass_type - v.add_send(objtype, v.get_method(iteratortype, "is_ok")) + v.add_callsite(self.method_iterator) + v.add_callsite(self.method_is_ok) if self.variables.length == 1 then - v.add_send(objtype, v.get_method(iteratortype, "item")) + v.add_callsite(self.method_item) else if self.variables.length == 2 then - v.add_send(objtype, v.get_method(iteratortype, "key")) - v.add_send(objtype, v.get_method(iteratortype, "item")) + v.add_callsite(self.method_key) + v.add_callsite(self.method_item) else abort end - v.add_send(objtype, v.get_method(iteratortype, "next")) + v.add_callsite(self.method_next) end end diff --combined src/typing.nit index f87a38e,c001f3a..fbd3f36 --- a/src/typing.nit +++ b/src/typing.nit @@@ -242,8 -242,8 +242,8 @@@ private class TypeVisito end assert mproperty isa MMethod - if mproperty.visibility == protected_visibility and not recv_is_self and self.mmodule.visibility_for(mproperty.intro_mclassdef.mmodule) < intrude_visibility then - self.modelbuilder.error(node, "Error: Method '{name}' is protected and can only acceded by self. {mproperty.intro_mclassdef.mmodule.visibility_for(self.mmodule)}") + if mproperty.visibility == protected_visibility and not recv_is_self and self.mmodule.visibility_for(mproperty.intro_mclassdef.mmodule) < intrude_visibility and not modelbuilder.toolcontext.opt_ignore_visibility.value then + self.modelbuilder.error(node, "Error: Method '{name}' is protected and can only acceded by self.") return null end @@@ -274,7 -274,7 +274,7 @@@ end end - var callsite = new CallSite(node, recvtype, recv_is_self, mproperty, mpropdef, msignature, erasure_cast) + var callsite = new CallSite(node, recvtype, mmodule, anchor, recv_is_self, mproperty, mpropdef, msignature, erasure_cast) return callsite end @@@ -386,15 -386,9 +386,15 @@@ class CallSit # The assiciated node for location var node: ANode - # The statis type of the receiver + # The static type of the receiver (possibly unresolved) var recv: MType + # The module where the callsite is present + var mmodule: MModule + + # The anchor to use with `recv` or `msignature` + var anchor: nullable MClassType + # Is the receiver self? # If "for_self", virtual types of the signature are keeped # If "not_for_self", virtual type are erased @@@ -816,11 -810,11 +816,11 @@@ en redef class AForExpr var coltype: nullable MClassType - var method_iterator: nullable MMethod - var method_is_ok: nullable MMethod - var method_item: nullable MMethod - var method_next: nullable MMethod - var method_key: nullable MMethod + var method_iterator: nullable CallSite + var method_is_ok: nullable CallSite + var method_item: nullable CallSite + var method_next: nullable CallSite + var method_key: nullable CallSite private fun do_type_iterator(v: TypeVisitor, mtype: MType) do @@@ -834,22 -828,12 +834,12 @@@ if objcla == null then return # check iterator method - var unsafe_type = v.anchor_to(mtype) - if v.try_get_mproperty_by_name2(self, unsafe_type, "iterator") == null then - if v.try_get_mproperty_by_name2(self, unsafe_type, "iterate") == null then - v.error(self, "Type Error: 'for' expects a type providing 'iterator' method, got '{mtype}'.") - else - v.modelbuilder.error(self, "NOT YET IMPLEMENTED: Do 'for' on {mtype}") - end - return - end - var itdef = v.get_method(self, mtype, "iterator", true) if itdef == null then v.error(self, "Type Error: 'for' expects a type providing 'iterator' method, got '{mtype}'.") return end - self.method_iterator = itdef.mproperty + self.method_iterator = itdef # check that iterator return something var ittype = itdef.msignature.return_mtype @@@ -906,21 -890,21 +896,21 @@@ v.error(self, "Type Error: 'for' expects a method 'is_ok' in 'Iterator' type {ittype}.") return end - self.method_is_ok = ikdef.mproperty + self.method_is_ok = ikdef var itemdef = v.get_method(self, ittype, "item", false) if itemdef == null then v.error(self, "Type Error: 'for' expects a method 'item' in 'Iterator' type {ittype}.") return end - self.method_item = itemdef.mproperty + self.method_item = itemdef var nextdef = v.get_method(self, ittype, "next", false) if nextdef == null then v.error(self, "Type Error: 'for' expects a method 'next' in 'Iterator' type {ittype}.") return end - self.method_next = nextdef.mproperty + self.method_next = nextdef if is_map then var keydef = v.get_method(self, ittype, "key", false) @@@ -928,7 -912,7 +918,7 @@@ v.error(self, "Type Error: 'for' expects a method 'key' in 'Iterator' type {ittype}.") return end - self.method_key = keydef.mproperty + self.method_key = keydef end end @@@ -1101,6 -1085,8 +1091,8 @@@ redef class AArrayExp end redef class ARangeExpr + var init_callsite: nullable CallSite + redef fun accept_typing(v) do var discrete_class = v.get_mclass(self, "Discrete") @@@ -1111,13 -1097,28 +1103,28 @@@ if t1 == null or t2 == null then return var mclass = v.get_mclass(self, "Range") if mclass == null then return # Forward error + var mtype if v.is_subtype(t1, t2) then - self.mtype = mclass.get_mtype([t2]) + mtype = mclass.get_mtype([t2]) else if v.is_subtype(t2, t1) then - self.mtype = mclass.get_mtype([t1]) + mtype = mclass.get_mtype([t1]) else v.error(self, "Type Error: Cannot create range: {t1} vs {t2}") + return + end + + self.mtype = mtype + + # get the constructor + var callsite + if self isa ACrangeExpr then + callsite = v.get_method(self, mtype, "init", false) + else if self isa AOrangeExpr then + callsite = v.get_method(self, mtype, "without_last", false) + else + abort end + init_callsite = callsite end end @@@ -1497,7 -1498,7 +1504,7 @@@ redef class ASuperExp end var msignature = v.resolve_signature_for(superprop, recvtype, true) - var callsite = new CallSite(self, recvtype, true, superprop.mproperty, superprop, msignature, false) + var callsite = new CallSite(self, recvtype, v.mmodule, v.anchor, true, superprop.mproperty, superprop, msignature, false) self.callsite = callsite var args = self.n_args.to_a