compiler: Refactor `AbstractRuntimeFunction`
[nit.git] / src / compiler / separate_compiler.nit
index c4defe0..f9d1444 100644 (file)
@@ -344,7 +344,7 @@ class SeparateCompiler
 
                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
@@ -982,6 +982,10 @@ class SeparateCompiler
                                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}")
@@ -1405,7 +1409,7 @@ class SeparateCompilerVisitor
                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)
@@ -2061,12 +2065,6 @@ class SeparateCompilerVisitor
                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
@@ -2085,7 +2083,7 @@ class SeparateCompilerVisitor
                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}")
@@ -2098,11 +2096,11 @@ class SeparateCompilerVisitor
                        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)
@@ -2199,10 +2197,7 @@ redef class MMethodDef
                                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
@@ -2239,11 +2234,23 @@ class SeparateRuntimeFunction
        # 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
@@ -2273,69 +2280,33 @@ class SeparateRuntimeFunction
        # 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.
        #
@@ -2384,6 +2355,12 @@ class SeparateRuntimeFunction
        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.