sepcomp: `compile_class_to_c` protect access to null vtf/attrs
[nit.git] / src / compiler / separate_erasure_compiler.nit
index e26a73d..d1c67e5 100644 (file)
@@ -39,6 +39,11 @@ redef class ToolContext
                if opt_no_check_all.value then
                        opt_no_check_erasure_cast.value = true
                end
+
+               # Temporary disabled. TODO: implement tagging in the erasure compiler.
+               if opt_erasure.value then
+                       opt_no_tag_primitives.value = true
+               end
        end
 
        var erasure_compiler_phase = new ErasureCompilerPhase(self, null)
@@ -194,8 +199,6 @@ class SeparateErasureCompiler
                var mtype = mclass.intro.bound_mtype
                var c_name = mclass.c_name
 
-               var vft = self.method_tables[mclass]
-               var attrs = self.attr_tables[mclass]
                var class_table = self.class_tables[mclass]
                var v = self.new_visitor
 
@@ -225,7 +228,8 @@ class SeparateErasureCompiler
                        end
                        v.add_decl("&type_table_{c_name},")
                        v.add_decl("\{")
-                       for i in [0 .. vft.length[ do
+                       var vft = self.method_tables.get_or_null(mclass)
+                       if vft != null then for i in [0 .. vft.length[ do
                                var mpropdef = vft[i]
                                if mpropdef == null then
                                        v.add_decl("NULL, /* empty */")
@@ -235,13 +239,9 @@ class SeparateErasureCompiler
                                                v.add_decl("NULL, /* DEAD {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
                                                continue
                                        end
-                                       if true or mpropdef.mclassdef.bound_mtype.ctype != "val*" then
-                                               v.require_declaration("VIRTUAL_{mpropdef.c_name}")
-                                               v.add_decl("(nitmethod_t)VIRTUAL_{mpropdef.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
-                                       else
-                                               v.require_declaration("{mpropdef.c_name}")
-                                               v.add_decl("(nitmethod_t){mpropdef.c_name}, /* pointer to {mclass.intro_mmodule}:{mclass}:{mpropdef} */")
-                                       end
+                                       var rf = mpropdef.virtual_runtime_function
+                                       v.require_declaration(rf.c_name)
+                                       v.add_decl("(nitmethod_t){rf.c_name}, /* pointer to {mpropdef.full_name} */")
                                end
                        end
                        v.add_decl("\}")
@@ -271,7 +271,7 @@ class SeparateErasureCompiler
                        self.header.add_decl("\};")
 
                        #Build BOX
-                       self.provide_declaration("BOX_{c_name}", "val* BOX_{c_name}({mtype.ctype});")
+                       self.provide_declaration("BOX_{c_name}", "val* BOX_{c_name}({mtype.ctype_extern});")
                        v.add_decl("/* allocate {mtype} */")
                        v.add_decl("val* BOX_{mtype.c_name}({mtype.ctype} value) \{")
                        v.add("struct instance_{c_name}*res = nit_alloc(sizeof(struct instance_{c_name}));")
@@ -354,11 +354,18 @@ class SeparateErasureCompiler
 
                        var res = v.new_named_var(mtype, "self")
                        res.is_exact = true
-                       v.add("{res} = nit_alloc(sizeof(struct instance) + {attrs.length}*sizeof(nitattribute_t));")
+                       var attrs = self.attr_tables.get_or_null(mclass)
+                       if attrs == null then
+                               v.add("{res} = nit_alloc(sizeof(struct instance));")
+                       else
+                               v.add("{res} = nit_alloc(sizeof(struct instance) + {attrs.length}*sizeof(nitattribute_t));")
+                       end
                        v.require_declaration("class_{c_name}")
                        v.add("{res}->class = &class_{c_name};")
-                       self.generate_init_attr(v, res, mtype)
-                       v.set_finalizer res
+                       if attrs != null then
+                               self.generate_init_attr(v, res, mtype)
+                               v.set_finalizer res
+                       end
                        v.add("return {res};")
                end
                v.add("\}")
@@ -614,7 +621,7 @@ class SeparateErasureCompilerVisitor
                        var res = self.new_var(mtype)
                        if compiler.runtime_type_analysis != null and not compiler.runtime_type_analysis.live_types.has(value.mtype.as(MClassType)) then
                                self.add("/*no boxing of {value.mtype}: {value.mtype} is not live! */")
-                               self.add("PRINT_ERROR(\"Dead code executed!\\n\"); show_backtrace(1);")
+                               self.add("PRINT_ERROR(\"Dead code executed!\\n\"); fatal_exit(1);")
                                return res
                        end
                        self.require_declaration("BOX_{valtype.c_name}")