Return true
if the compilation was successful, false
if a fall-back is needed
# Compile an extern method
# Return `true` if the compilation was successful, `false` if a fall-back is needed
fun compile_externmeth_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]): Bool
do
var externname
var at = self.get_single_annotation("extern", v.compiler.modelbuilder)
if at != null and at.n_args.length == 1 then
externname = at.arg_as_string(v.compiler.modelbuilder)
if externname == null then return false
else
return false
end
v.add_extern(mpropdef.mclassdef.mmodule)
var res: nullable RuntimeVariable = null
var ret = mpropdef.msignature.return_mtype
if ret != null then
ret = v.resolve_for(ret, arguments.first)
res = v.new_var_extern(ret)
end
v.adapt_signature(mpropdef, arguments)
v.unbox_signature_extern(mpropdef, arguments)
if res == null then
v.add("{externname}({arguments.join(", ")});")
else
v.add("{res} = {externname}({arguments.join(", ")});")
res = v.box_extern(res, ret.as(not null))
v.ret(res)
end
return true
end
src/compiler/abstract_compiler.nit:3502,2--3532,4
redef fun compile_externmeth_to_c(v, mpropdef, arguments)
do
# if using the old native interface fallback on previous implementation
if n_extern_code_block == null then return super
if not accept_externmeth then return false
var mmodule = mpropdef.mclassdef.mmodule
mmodule.uses_ffi = true
var mclass_type = mpropdef.mclassdef.bound_mtype
# Outgoing code in compiler
var externname = mpropdef.mproperty.build_cname(mpropdef.mclassdef.bound_mtype, mmodule, "___impl", long_signature)
var recv_var: nullable RuntimeVariable = null
var return_mtype = mpropdef.msignature.return_mtype
if return_mtype != null then
return_mtype = return_mtype.anchor_to(mmodule, mclass_type)
recv_var = v.new_var(return_mtype)
end
v.adapt_signature(mpropdef, arguments)
v.unbox_signature_extern(mpropdef, arguments)
var arguments_for_c = new Array[String]
for a in [0..arguments.length[ do
var arg = arguments[a]
var param_mtype: MType
if a == 0 then
param_mtype = mpropdef.mclassdef.mclass.mclass_type
else param_mtype = mpropdef.msignature.mparameters[a-1].mtype
param_mtype = param_mtype.anchor_to(mmodule, mclass_type)
if param_mtype.is_cprimitive then
arguments_for_c.add(arg.name)
else
v.add("struct nitni_instance* var_for_c_{a};")
v.add("var_for_c_{a} = nit_alloc(sizeof(struct nitni_instance));")
v.add("var_for_c_{a}->value = {arg.name};")
arguments_for_c.add("var_for_c_{a}")
end
end
if recv_var == null then
v.add("{externname}({arguments_for_c.join(", ")});")
else
assert return_mtype != null
if return_mtype.is_cprimitive then
v.add("{recv_var} = {externname}({arguments_for_c.join(", ")});")
else
v.add("struct nitni_instance* ret_var;")
v.add("ret_var = {externname}({arguments_for_c.join(", ")});")
v.add("{recv_var} = ret_var->value;")
end
recv_var = v.box_extern(recv_var, return_mtype)
v.ret(recv_var)
end
compile_ffi_support_to_c(v)
return true
end
src/compiler/compiler_ffi/light.nit:107,2--168,4