# Generate the init-instance of a live type (allocate + init-instance)
fun generate_init_instance(mtype: MClassType)
do
assert self.runtime_type_analysis.live_types.has(mtype)
assert not mtype.is_c_primitive
var v = self.new_visitor
var is_native_array = mtype.mclass.name == "NativeArray"
var is_routine_ref = all_routine_types_name.has(mtype.mclass.name)
var sig
if is_native_array then
sig = "int length"
else
sig = "void"
end
if is_routine_ref then
var c_args = ["val* self"]
var c_ret = "void"
var k = mtype.arguments.length
if mtype.mclass.name.has("Fun") then
c_ret = mtype.arguments.last.ctype
k -= 1
end
for i in [0..k[ do
var t = mtype.arguments[i]
c_args.push("{t.ctype} p{i}")
end
# The underlying method signature
var method_sig = "{c_ret} (*method)({c_args.join(", ")})"
sig = "val* recv, {method_sig}"
end
self.header.add_decl("{mtype.ctype} NEW_{mtype.c_name}({sig});")
v.add_decl("/* allocate {mtype} */")
v.add_decl("{mtype.ctype} NEW_{mtype.c_name}({sig}) \{")
var res = v.new_var(mtype)
res.is_exact = true
if is_native_array then
v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}) + length*sizeof(val*));")
v.add("((struct {mtype.c_name}*){res})->length = length;")
else
v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}));")
end
if is_routine_ref then
v.add("((struct {mtype.c_name}*){res})->recv = recv;")
v.add("((struct {mtype.c_name}*){res})->method = method;")
end
v.add("{res}->classid = {self.classid(mtype)};")
self.generate_init_attr(v, res, mtype)
v.set_finalizer res
v.add("return {res};")
v.add("\}")
end
src/compiler/global_compiler.nit:244,2--297,4