# Instantiate a new routine pointer
fun routine_ref_instance(routine_mclass_type: MClassType, recv: RuntimeVariable, callsite: CallSite): RuntimeVariable is abstract
src/compiler/abstract_compiler.nit:1371,2--1372,130
redef fun routine_ref_instance(routine_type, recv, callsite)
do
#debug "ENTER ref_instance"
var mmethoddef = callsite.mpropdef
var mmethod = mmethoddef.mproperty
# routine_mclass is the specialized one, e.g: FunRef1, ProcRef2, etc..
var routine_mclass = routine_type.mclass
var nclasses = mmodule.model.get_mclasses_by_name("RoutineRef").as(not null)
var base_routine_mclass = nclasses.first
# All routine classes use the same `NEW` constructor.
# However, they have different declared `class` and `type` value.
self.require_declaration("NEW_{base_routine_mclass.c_name}")
var recv_class_cname = recv.mcasttype.as(MClassType).mclass.c_name
var my_recv = recv
if recv.mtype.is_c_primitive then
my_recv = autobox(recv, mmodule.object_type)
end
var my_recv_mclass_type = my_recv.mtype.as(MClassType)
# The class of the concrete Routine must exist (e.g ProcRef0, FunRef0, etc.)
self.require_declaration("class_{routine_mclass.c_name}")
self.require_declaration(mmethoddef.c_name)
var thunk_function = mmethoddef.callref_thunk(my_recv_mclass_type)
# If the receiver is exact, then there's no need to make a
# polymorph call to the underlying method.
thunk_function.polymorph_call_flag = not my_recv.is_exact
var runtime_function = mmethoddef.virtual_runtime_function
var is_c_equiv = runtime_function.msignature.c_equiv(thunk_function.msignature)
var c_ref = thunk_function.c_ref
if is_c_equiv then
var const_color = mmethoddef.mproperty.const_color
c_ref = "{class_info(my_recv)}->vft[{const_color}]"
self.require_declaration(const_color)
else
self.require_declaration(thunk_function.c_name)
compiler.thunk_todo(thunk_function)
end
var res: RuntimeVariable
if routine_type.need_anchor then
hardening_live_open_type(routine_type)
link_unresolved_type(self.frame.mpropdef.mclassdef, routine_type)
var recv2 = self.frame.arguments.first
var recv2_type_info = self.type_info(recv2)
self.require_declaration(routine_type.const_color)
res = self.new_expr("NEW_{base_routine_mclass.c_name}({my_recv}, (nitmethod_t){c_ref}, &class_{routine_mclass.c_name}, {recv2_type_info}->resolution_table->types[{routine_type.const_color}])", routine_type)
else
self.require_declaration("type_{routine_type.c_name}")
compiler.undead_types.add(routine_type)
res = self.new_expr("NEW_{base_routine_mclass.c_name}({my_recv}, (nitmethod_t){c_ref}, &class_{routine_mclass.c_name}, &type_{routine_type.c_name})", routine_type)
end
return res
end
src/compiler/separate_compiler.nit:2233,2--2291,4
redef fun routine_ref_instance(routine_mclass_type, recv, callsite)
do
var mmethoddef = callsite.mpropdef
var method = new CustomizedRuntimeFunction(mmethoddef, recv.mcasttype.as(MClassType))
var my_recv = recv
if recv.mtype.is_c_primitive then
var object_type = mmodule.object_type
my_recv = autobox(recv, object_type)
end
var thunk = new CustomizedThunkFunction(mmethoddef, my_recv.mtype.as(MClassType))
thunk.polymorph_call_flag = not my_recv.is_exact
compiler.todo(method)
compiler.todo(thunk)
var ret_type = self.anchor(routine_mclass_type).as(MClassType)
var res = self.new_expr("NEW_{ret_type.c_name}({my_recv}, &{thunk.c_name})", ret_type)
return res
end
src/compiler/global_compiler.nit:466,9--482,11
redef fun routine_ref_instance(routine_type, recv, callsite)
do
var mmethoddef = callsite.mpropdef
#debug "ENTER ref_instance"
var mmethod = mmethoddef.mproperty
# routine_mclass is the specialized one, e.g: FunRef1, ProcRef2, etc..
var routine_mclass = routine_type.mclass
var nclasses = mmodule.model.get_mclasses_by_name("RoutineRef").as(not null)
var base_routine_mclass = nclasses.first
# All routine classes use the same `NEW` constructor.
# However, they have different declared `class` and `type` value.
self.require_declaration("NEW_{base_routine_mclass.c_name}")
var recv_class_cname = recv.mcasttype.as(MClassType).mclass.c_name
var my_recv = recv
if recv.mtype.is_c_primitive then
my_recv = autobox(recv, mmodule.object_type)
end
var my_recv_mclass_type = my_recv.mtype.as(MClassType)
# The class of the concrete Routine must exist (e.g ProcRef0, FunRef0, etc.)
self.require_declaration("class_{routine_mclass.c_name}")
self.require_declaration(mmethoddef.c_name)
var thunk_function = mmethoddef.callref_thunk(my_recv_mclass_type)
var runtime_function = mmethoddef.virtual_runtime_function
var is_c_equiv = runtime_function.msignature.c_equiv(thunk_function.msignature)
var c_ref = thunk_function.c_ref
if is_c_equiv then
var const_color = mmethoddef.mproperty.const_color
c_ref = "{class_info(my_recv)}->vft[{const_color}]"
self.require_declaration(const_color)
else
self.require_declaration(thunk_function.c_name)
compiler.thunk_todo(thunk_function)
end
compiler.thunk_todo(thunk_function)
# Each RoutineRef points to a receiver AND a callref_thunk
var res = self.new_expr("NEW_{base_routine_mclass.c_name}({my_recv}, (nitmethod_t){c_ref}, &class_{routine_mclass.c_name})", routine_type)
#debug "LEAVING ref_instance"
return res
end
src/compiler/separate_erasure_compiler.nit:723,9--772,11