# 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
# 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.
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
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
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]});")
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