# The C function associated to a methoddef separately compiled
class SeparateRuntimeFunction
super AbstractRuntimeFunction
# The call-side static receiver
var called_recv: MType
# The call-side static signature
var called_signature: MSignature
# The name on the compiled method
redef var build_c_name:
redef fun to_s do return self.mmethoddef.to_s
redef fun msignature
do
return called_signature
end
redef fun recv_mtype
do
return called_recv
end
redef fun return_mtype
do
return called_signature.return_mtype
end
# The C return type (something or `void`)
var c_ret: String is lazy do
var ret = called_signature.return_mtype
if ret != null then
return ret.ctype
else
return "void"
end
end
# The C signature (only the parmeter part)
var c_sig: String is lazy do
var sig = new FlatBuffer
sig.append("({called_recv.ctype} self")
for i in [0..called_signature.arity[ do
var mp = called_signature.mparameters[i]
var mtype = mp.mtype
if mp.is_vararg then
mtype = mmethoddef.mclassdef.mmodule.array_type(mtype)
end
sig.append(", {mtype.ctype} p{i}")
end
sig.append(")")
return sig.to_s
end
# The C type for the function pointer.
var c_funptrtype: String is lazy do return "{c_ret}(*){c_sig}"
redef fun declare_signature(v, sig)
do
v.compiler.provide_declaration(c_name, "{sig};")
end
redef fun body_to_c(v)
do
var rta = v.compiler.as(SeparateCompiler).runtime_type_analysis
if rta != null and not rta.live_mmodules.has(mmethoddef.mclassdef.mmodule) then
v.add_abort("FATAL: Dead method executed.")
else
super
end
end
redef fun end_compile_to_c(v)
do
var compiler = v.compiler
compiler.names[self.c_name] = "{mmethoddef.full_name} ({mmethoddef.location.file.}:{mmethoddef.location.line_start})"
end
redef fun build_frame(v, arguments)
do
var recv = mmethoddef.mclassdef.bound_mtype
return new StaticFrame(v, mmethoddef, recv, arguments)
end
# Compile the trampolines used to implement late-binding.
#
# See `opt_trampoline_call`.
fun compile_trampolines(compiler: SeparateCompiler)
do
var recv = self.mmethoddef.mclassdef.bound_mtype
var selfvar = new RuntimeVariable("self", called_recv, recv)
var ret = called_signature.return_mtype
var arguments = ["self"]
for i in [0..called_signature.arity[ do arguments.add "p{i}"
if mmethoddef.is_intro and not recv.is_c_primitive then
var m = mmethoddef.mproperty
var n2 = "CALL_" + m.const_color
compiler.provide_declaration(n2, "{c_ret} {n2}{c_sig};")
var v2 = compiler.new_visitor
v2.add "{c_ret} {n2}{c_sig} \{"
v2.require_declaration(m.const_color)
var call = "(({c_funptrtype})({v2.class_info(selfvar)}->vft[{m.const_color}]))({arguments.join(", ")});"
if ret != null then
v2.add "return {call}"
else
v2.add call
end
v2.add "\}"
end
if mmethoddef.has_supercall and not recv.is_c_primitive then
var m = mmethoddef
var n2 = "CALL_" + m.const_color
compiler.provide_declaration(n2, "{c_ret} {n2}{c_sig};")
var v2 = compiler.new_visitor
v2.add "{c_ret} {n2}{c_sig} \{"
v2.require_declaration(m.const_color)
var call = "(({c_funptrtype})({v2.class_info(selfvar)}->vft[{m.const_color}]))({arguments.join(", ")});"
if ret != null then
v2.add "return {call}"
else
v2.add call
end
v2.add "\}"
end
end
end
src/compiler/separate_compiler.nit:2463,1--2594,3