for m in mainmodule.in_importation.greaters do for cd in m.mclassdefs do
var mclass = cd.mclass
- # Collect methods ad attributes
+ # Collect methods and attributes
for p in cd.intro_mproperties do
if p isa MMethod then
if rta == null then
var alloc = v.nit_alloc("sizeof(struct instance) + {attrs.length}*sizeof(nitattribute_t)", mclass.full_name)
v.add("{res} = {alloc};")
end
+ if modelbuilder.toolcontext.opt_trace.value then
+ v.add("tracepoint(Nit_Compiler, Object_Instance,\"{mtype}\", (uintptr_t)self);")
+ v.add("GC_register_finalizer(self, object_destroy_callback, NULL, NULL, NULL);")
+ end
v.add("{res}->type = type;")
hardening_live_type(v, "type")
v.require_declaration("class_{c_name}")
var res: nullable RuntimeVariable = null
var recv = arguments.first
var consider_null = not self.compiler.modelbuilder.toolcontext.opt_no_check_null.value or mmethod.name == "==" or mmethod.name == "!="
- if maybenull(recv) and consider_null then
+ if maybe_null(recv) and consider_null then
self.add("if ({recv} == NULL) \{")
if mmethod.name == "==" or mmethod.name == "is_same_instance" then
res = self.new_var(bool_type)
return k == interface_kind or t.is_c_primitive
end
- fun maybe_null(value: RuntimeVariable): Bool
- do
- var t = value.mcasttype
- return t isa MNullableType or t isa MNullType
- end
-
redef fun array_instance(array, elttype)
do
var nclass = mmodule.native_array_class
return res
end
- redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable
+ redef fun native_array_instance(elttype, length)
do
var mtype = mmodule.native_array_type(elttype)
self.require_declaration("NEW_{mtype.mclass.c_name}")
var recv = self.frame.arguments.first
var recv_type_info = self.type_info(recv)
self.require_declaration(mtype.const_color)
- return self.new_expr("NEW_{mtype.mclass.c_name}({length}, {recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype)
+ return self.new_expr("NEW_{mtype.mclass.c_name}((int){length}, {recv_type_info}->resolution_table->types[{mtype.const_color}])", mtype)
end
compiler.undead_types.add(mtype)
self.require_declaration("type_{mtype.c_name}")
- return self.new_expr("NEW_{mtype.mclass.c_name}({length}, &type_{mtype.c_name})", mtype)
+ return self.new_expr("NEW_{mtype.mclass.c_name}((int){length}, &type_{mtype.c_name})", mtype)
end
redef fun native_array_def(pname, ret_type, arguments)
self.virtual_runtime_function_cache = res
return res
end
-
- res = new SeparateRuntimeFunction(self, recv, msignature, "VIRTUAL_{c_name}")
- self.virtual_runtime_function_cache = res
- res.is_thunk = true
+ res = new SeparateThunkFunction(self, recv, msignature, "VIRTUAL_{c_name}", mclassdef.bound_mtype)
end
return res
end
# The name on the compiled method
redef var build_c_name: String
- # Statically call the original body instead
- var is_thunk = false
-
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
# The C type for the function pointer.
var c_funptrtype: String is lazy do return "{c_ret}(*){c_sig}"
- redef fun compile_to_c(compiler)
- do
- var mmethoddef = self.mmethoddef
-
- var sig = "{c_ret} {c_name}{c_sig}"
- compiler.provide_declaration(self.c_name, "{sig};")
-
- var rta = compiler.as(SeparateCompiler).runtime_type_analysis
-
- var recv = self.mmethoddef.mclassdef.bound_mtype
- var v = compiler.new_visitor
- var selfvar = new RuntimeVariable("self", called_recv, recv)
- var arguments = new Array[RuntimeVariable]
- var frame = new StaticFrame(v, mmethoddef, recv, arguments)
- v.frame = frame
-
- var msignature = called_signature
- var ret = called_signature.return_mtype
+ redef fun declare_signature(v, sig)
+ do
+ v.compiler.provide_declaration(c_name, "{sig};")
+ end
- var comment = new FlatBuffer
- comment.append("({selfvar}: {selfvar.mtype}")
- arguments.add(selfvar)
- for i in [0..msignature.arity[ do
- var mp = msignature.mparameters[i]
- var mtype = mp.mtype
- if mp.is_vararg then
- mtype = v.mmodule.array_type(mtype)
- end
- comment.append(", {mtype}")
- var argvar = new RuntimeVariable("p{i}", mtype, mtype)
- arguments.add(argvar)
- end
- comment.append(")")
- if ret != null then
- comment.append(": {ret}")
- 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
- v.add_decl("/* method {self} for {comment} */")
- v.add_decl("{sig} \{")
- if ret != null then
- frame.returnvar = v.new_var(ret)
- end
- frame.returnlabel = v.get_name("RET_LABEL")
- if is_thunk then
- var subret = v.call(mmethoddef, recv, arguments)
- if ret != null then
- assert subret != null
- v.assign(frame.returnvar.as(not null), subret)
- end
- else if rta != null and not rta.live_mmodules.has(mmethoddef.mclassdef.mmodule) then
- v.add_abort("FATAL: Dead method executed.")
- else
- mmethoddef.compile_inside_to_c(v, arguments)
- end
+ redef fun end_compile_to_c(v)
+ do
+ var compiler = v.compiler
+ compiler.names[self.c_name] = "{mmethoddef.full_name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})"
+ end
- v.add("{frame.returnlabel.as(not null)}:;")
- if ret != null then
- v.add("return {frame.returnvar.as(not null)};")
- end
- v.add("\}")
- compiler.names[self.c_name] = "{mmethoddef.full_name} ({mmethoddef.location.file.filename}:{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.
#
end
end
+class SeparateThunkFunction
+ super ThunkFunction
+ super SeparateRuntimeFunction
+ redef var target_recv
+end
+
redef class MType
# Are values of `self` tagged?
# If false, it means that the type is not primitive, or is boxed.