X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index b512cdd..669159f 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -625,6 +625,20 @@ abstract class AbstractCompiler # The targeted specific platform var target_platform: Platform is noinit + # All methods who already has a callref_thunk generated for + var compiled_callref_thunk = new HashSet[MMethodDef] + + var all_routine_types_name: Set[String] do + var res = new HashSet[String] + for name in ["Fun", "Proc", "FunRef", "ProcRef"] do + # Currently there's 20 arity per func type + for i in [0..20[ do + res.add("{name}{i}") + end + end + return res + end + init do self.realmainmodule = mainmodule @@ -1377,6 +1391,12 @@ abstract class AbstractCompilerVisitor # The method is unsafe and is just a direct wrapper for the specific implementation of native arrays fun native_array_set(native_array: RuntimeVariable, index: Int, value: RuntimeVariable) is abstract + # Instantiate a new routine pointer + fun routine_ref_instance(routine_mclass_type: MClassType, recv: RuntimeVariable, mmethoddef: MMethodDef): RuntimeVariable is abstract + + # Call the underlying referenced function + fun routine_ref_call(mmethoddef: MMethodDef, args: Array[RuntimeVariable]) is abstract + # Allocate `size` bytes with the low_level `nit_alloc` C function # # This method can be redefined to inject statistic or tracing code. @@ -2524,6 +2544,19 @@ redef class MClassType end end +redef class MSignature + fun change_all_mtype_for(mtype: MType): MSignature + do + var ps = new Array[MParameter] + for p in mparameters do + ps.push(new MParameter(p.name, mtype, p.is_vararg)) + end + var ret: nullable MType = null + if return_mtype != null then ret = mtype + return new MSignature(ps, ret) + end +end + redef class MPropDef type VISITOR: AbstractCompilerVisitor end @@ -2689,10 +2722,15 @@ redef class AMethPropdef var pname = mpropdef.mproperty.name var cname = mpropdef.mclassdef.mclass.name var ret = mpropdef.msignature.return_mtype - if ret != null then + var compiler = v.compiler + # WARNING: we must not resolve the return type when it's a functional type. + # Otherwise, we get a compile error exactly here. This weird behavior doesn't affect + # the inner mecanics of callref since the return type is already solved by + # `routine_ref_call` + if ret != null and not compiler.all_routine_types_name.has(cname) then ret = v.resolve_for(ret, arguments.first) end - if pname != "==" and pname != "!=" then + if pname != "==" and pname != "!=" and pname != "call" and not compiler.all_routine_types_name.has(cname) then v.adapt_signature(mpropdef, arguments) v.unbox_signature_extern(mpropdef, arguments) end @@ -3455,6 +3493,9 @@ redef class AMethPropdef v.ret(v.new_expr("~{arguments[0]}", ret.as(not null))) return true end + else if compiler.all_routine_types_name.has(cname) then + v.routine_ref_call(mpropdef, arguments) + return true end if pname == "exit" then v.add("exit((int){arguments[1]});") @@ -4375,8 +4416,9 @@ end redef class ACallrefExpr redef fun expr(v) do - v.add_abort("NOT YET IMPLEMENTED callref expressions.") - return null + var recv = v.expr(self.n_expr, null) + var res = v.routine_ref_instance(mtype.as(MClassType), recv, callsite.as(not null).mpropdef) + return res end end