nitg-s: rename SeparateCompiler:do_global_type_coloring to do_type_coloring
[nit.git] / src / separate_compiler.nit
index 0b42e00..bd93cae 100644 (file)
@@ -40,8 +40,7 @@ redef class ModelBuilder
                self.toolcontext.info("*** COMPILING TO C ***", 1)
 
                var compiler = new SeparateCompiler(mainmodule, runtime_type_analysis, self)
-               var v = compiler.new_visitor
-               compiler.header = v
+               var v = compiler.header
                v.add_decl("#include <stdlib.h>")
                v.add_decl("#include <stdio.h>")
                v.add_decl("#include <string.h>")
@@ -81,7 +80,7 @@ redef class ModelBuilder
                end
 
                # compile live & cast type structures
-               var mtypes = compiler.do_global_type_coloring
+               var mtypes = compiler.do_type_coloring
                for t in mtypes do
                        compiler.compile_type_to_c(t)
                end
@@ -127,6 +126,7 @@ class SeparateCompiler
        private var ft_tables: Map[MClass, Array[nullable MParameterType]]
 
        init(mainmodule: MModule, runtime_type_analysis: RapidTypeAnalysis, mmbuilder: ModelBuilder) do
+               self.header = self.new_visitor
                # classes coloration
                var class_coloring = new ClassColoring(mainmodule)
                self.class_colors = class_coloring.colorize(mmbuilder.model.mclasses)
@@ -203,7 +203,7 @@ class SeparateCompiler
        end
 
        # colorize live types of the program
-       private fun do_global_type_coloring: Set[MType] do
+       private fun do_type_coloring: Set[MType] do
                var mtypes = new HashSet[MType]
                mtypes.add_all(self.runtime_type_analysis.live_types)
                mtypes.add_all(self.runtime_type_analysis.live_cast_types)
@@ -435,24 +435,27 @@ class SeparateCompiler
                                        print "No bound found for virtual type {vt} ?"
                                        abort
                                else
-                                       var ntype = bound
-                                       if ntype isa MNullableType then ntype = ntype.mtype
-                                       if ntype isa MVirtualType then
-                                               bound = ntype.anchor_to(self.mainmodule, mclass_type)
-                                       else if ntype isa MParameterType then
-                                               bound = ntype.anchor_to(self.mainmodule, mclass_type)
-                                       else if ntype isa MGenericType and bound.need_anchor then
-                                               bound = ntype.anchor_to(self.mainmodule, mclass_type)
-                                       else if ntype isa MClassType then
+                                       var is_nullable = ""
+                                       if bound isa MNullableType then
+                                               bound = bound.mtype
+                                               is_nullable = "nullable_"
+                                       end
+                                       if bound isa MVirtualType then
+                                               bound = bound.anchor_to(self.mainmodule, mclass_type)
+                                       else if bound isa MParameterType then
+                                               bound = bound.anchor_to(self.mainmodule, mclass_type)
+                                       else if bound isa MGenericType and bound.need_anchor then
+                                               bound = bound.anchor_to(self.mainmodule, mclass_type)
+                                       else if bound isa MClassType then
                                        else
-                                               print "NOT YET IMPLEMENTED: mtype_to_livetype with type: {ntype}"
+                                               print "NOT YET IMPLEMENTED: mtype_to_livetype with type: {bound}"
                                                abort
                                        end
 
                                        if self.typeids.has_key(bound) then
-                                               v.add_decl("(struct type*)&type_{bound.c_name}, /* {ntype} */")
+                                               v.add_decl("(struct type*)&type_{is_nullable}{bound.c_name}, /* {bound} */")
                                        else
-                                               v.add_decl("NULL, /* dead type {ntype} */")
+                                               v.add_decl("NULL, /* dead type {bound} */")
                                        end
                                end
                        end
@@ -563,17 +566,25 @@ class SeparateCompiler
                v.add("{res}->type = type;")
                v.add("{res}->class = (struct class*) &class_{c_name};")
 
-               for cd in mtype.collect_mclassdefs(self.mainmodule)
-               do
-                       var n = self.modelbuilder.mclassdef2nclassdef[cd]
-                       for npropdef in n.n_propdefs do
-                               if npropdef isa AAttrPropdef then
-                                       npropdef.init_expr(v, res)
-                               end
-                       end
-               end
+               self.generate_init_attr(v, res, mtype)
                v.add("return {res};")
                v.add("\}")
+
+               generate_check_init_instance(mtype)
+       end
+
+       redef fun generate_check_init_instance(mtype)
+       do
+               if self.modelbuilder.toolcontext.opt_no_check_initialization.value then return
+
+               var v = self.new_visitor
+               var c_name = mtype.mclass.c_name
+               var res = new RuntimeVariable("self", mtype, mtype)
+               self.header.add_decl("void CHECK_NEW_{c_name}({mtype.ctype});")
+               v.add_decl("/* allocate {mtype} */")
+               v.add_decl("void CHECK_NEW_{c_name}({mtype.ctype} {res}) \{")
+               self.generate_check_attr(v, res, mtype)
+               v.add("\}")
        end
 
        redef fun new_visitor do return new SeparateCompilerVisitor(self)
@@ -1025,6 +1036,13 @@ class SeparateCompilerVisitor
                return self.new_expr("NEW_{mtype.mclass.c_name}((struct type *) &type_{mtype.c_name})", mtype)
        end
 
+       redef fun check_init_instance(value, mtype)
+       do
+               if self.compiler.modelbuilder.toolcontext.opt_no_check_initialization.value then return
+               self.add("CHECK_NEW_{mtype.mclass.c_name}({value});")
+       end
+
+
        redef fun type_test(value, mtype)
        do
                var compiler = self.compiler.as(SeparateCompiler)
@@ -1246,7 +1264,7 @@ class SeparateCompilerVisitor
                end
                var length = self.int_instance(array.length)
                self.send(self.get_property("with_native", arraytype), [res, nat, length])
-               self.check_init_instance(res)
+               self.check_init_instance(res, arraytype)
                self.add("\}")
                return res
        end
@@ -1292,3 +1310,24 @@ redef class MClass
        end
        private var c_name_cache: nullable String
 end
+redef class MParameterType
+       redef fun c_name
+       do
+               var res = self.c_name_cache
+               if res != null then return res
+               res = "{self.mclass.c_name}_FT{self.rank}"
+               self.c_name_cache = res
+               return res
+       end
+end
+
+redef class MNullableType
+       redef fun c_name
+       do
+               var res = self.c_name_cache
+               if res != null then return res
+               res = "nullable_{self.mtype.c_name}"
+               self.c_name_cache = res
+               return res
+       end
+end