Merge branch 'fix-vt' into wip
authorJean Privat <jean@pryen.org>
Fri, 25 Nov 2011 16:59:12 +0000 (11:59 -0500)
committerJean Privat <jean@pryen.org>
Fri, 25 Nov 2011 16:59:12 +0000 (11:59 -0500)
1  2 
src/compiling/compiling_base.nit
src/compiling/compiling_global.nit
src/compiling/compiling_icode.nit
src/compiling/table_computation.nit
src/icode/icode_base.nit

@@@ -43,7 -43,7 +43,7 @@@ class CProgra
        do
                _program = p
                _compdir = p.tc.compdir.as(not null)
 -              _build_file = "{compdir}/{program.main_module.name}._build.sh"
 +              _build_file = "{compdir}/{program.main_module.cname}._build.sh"
        end
  
        # The Nit program compiled to C
@@@ -67,7 -67,7 +67,7 @@@
                if _module_include.has_key(m) then
                        return _module_include[m]
                end
 -              var filename = "{m.name}.{get_file_ending}.h"
 +              var filename = "{m.cname}.{get_file_ending}.h"
                _module_include[m] = filename
                return filename
        end
@@@ -94,7 -94,7 +94,7 @@@
                end
  
                f.write("#!/bin/sh\n")
 -              f.write("# This shell script is generated by NIT to compile the program {program.main_module.name}.\n")
 +              f.write("# This shell script is generated by NIT to compile the program {program.main_module.full_name}.\n")
                f.write("CLIBDIR=\"{tc.clibdir.as(not null)}\"\n")
                f.write("{tc.bindir.as(not null)}/gccx {verbose} -d {compdir} -I $CLIBDIR {include_dirs.join(" ")}")
                if tc.output_file != null then
@@@ -246,71 -246,40 +246,83 @@@ redef class MMGlobalPropert
        do
                return "ATTR_{intro.cname}"
        end
+       # C symbol refering a virtual type class color
+       fun vt_class_color: String
+       do
+               return "VTCOLOR_{intro.cname}"
+       end
+       # C symbol refering a virtual type class id
+       fun vt_class_id: String
+       do
+               return "VTID_{intro.cname}"
+       end
  end
  
  redef class MMGlobalClass
 +      # Cacher result of cname
 +      var _cname_cache: nullable String
 +
 +      # The mangled name of the global class
 +      fun cname: String
 +      do
 +              var cname = _cname_cache
 +              if cname == null then
 +                      cname = intro.mmmodule.cname + "___" + cmangle(intro.name)
 +                      _cname_cache = cname
 +              end
 +              return cname
 +      end
 +
        # C symbol refering the identifier of the class
        fun id_id: String
        do
 -              return "ID_{intro.name}"
 +              return "ID_{cname}"
        end
  
        # C symbol refering the color of the class (for subtype tests)
        fun color_id: String
        do
 -              return "COLOR_{intro.name}"
 +              return "COLOR_{cname}"
        end
  
        # C symbol refering the init table position of the class (for constructor linearization)
        fun init_table_pos_id: String
        do
 -              return "INIT_TABLE_POS_{intro.name}"
 +              return "INIT_TABLE_POS_{cname}"
 +      end
 +end
 +
 +redef class MMModule
 +      # Cacher result of cname
 +      var _cname_cache: nullable String
 +
 +      # The mangled name of the module
 +      fun cname: String
 +      do
 +              var cname = _cname_cache
 +              if cname == null then
 +                      var l = new List[String]
 +                      var m: nullable MMModule = self
 +                      while m != null do
 +                              l.unshift(cmangle(m.name))
 +                              var d: nullable MMDirectory = m.directory
 +                              while d != null and d.owner == m do d = d.parent
 +                              if d == null then m = null else m = d.owner
 +                      end
 +                      cname = l.to_a.join("___")
 +                      _cname_cache = cname
 +              end
 +              return cname
        end
  end
  
 +redef class MMLocalClass
 +      # The mangled name of the global class
 +      fun cname: String do return global.cname
 +end
 +
  redef class MMLocalProperty
        # Cacher result of cname
        var _cname_cache: nullable String
        do
                var cname = _cname_cache
                if cname == null then
 -                      cname = cmangle(mmmodule.name, local_class.name, name)
 +                      cname = mmmodule.cname + "___" + cmangle(local_class.name, name)
                        _cname_cache = cname
                end
                return cname
@@@ -36,8 -36,7 +36,8 @@@ redef class Progra
                var s = new Buffer.from("classtable_t TAG2VFT[4] = \{NULL")
                for t in ["Int","Char","Bool"] do
                        if main_module.has_global_class_named(t.to_symbol) then
 -                              s.append(", (const classtable_t)VFT_{t}")
 +                              var c = main_module.class_by_name(t.to_symbol)
 +                              s.append(", (const classtable_t)VFT_{c.cname}")
                        else
                                s.append(", NULL")
                        end
@@@ -56,8 -55,7 +56,8 @@@
                if v.program.main_method == null then
                        print("No main")
                else
 -                      v.add_instr("G_sys = NEW_Sys();")
 +                      var c = v.program.main_class
 +                      v.add_instr("G_sys = NEW_{c.cname}();")
                        v.add_instr("register_static_object(&G_sys);")
                        v.add_instr("{v.program.main_method.cname}(G_sys);")
                end
@@@ -81,9 -79,9 +81,9 @@@ redef class MMModul
        # Compile sep files
        fun compile_mod_to_c(v: CompilerVisitor)
        do
 -              v.add_decl("extern const char *LOCATE_{name};")
 +              v.add_decl("extern const char *LOCATE_{cname};")
                if not v.program.tc.use_SFT_optimization then
 -                      v.add_decl("extern const int SFT_{name}[];")
 +                      v.add_decl("extern const int SFT_{cname}[];")
                end
                var i = 0
                for e in local_table do
@@@ -91,7 -89,7 +91,7 @@@
                        if v.program.tc.use_SFT_optimization then
                                value = "{e.value(v.program)}"
                        else
 -                              value = "SFT_{name}[{i}]"
 +                              value = "SFT_{cname}[{i}]"
                                i = i + 1
                        end
                        e.compile_macros(v, value)
        # Compile module file for the current module
        fun compile_local_table_to_c(v: CompilerVisitor)
        do
 -              v.add_instr("const char *LOCATE_{name} = \"{location.file}\";")
 +              v.add_instr("const char *LOCATE_{cname} = \"{location.file.filename}\";")
  
                if v.program.tc.use_SFT_optimization or local_table.is_empty then
                        return
                end
  
 -              v.add_instr("const int SFT_{name}[{local_table.length}] = \{")
 +              v.add_instr("const int SFT_{cname}[{local_table.length}] = \{")
                v.indent
                for e in local_table do
                        v.add_instr(e.value(v.program) + ",")
@@@ -205,6 -203,39 +205,39 @@@ redef class TableEltSupe
        end
  end
  
+ redef class TableEltVTClassColor
+       redef fun compile_macros(v, value)
+       do
+               var pg = property.global
+               v.add_decl("#define {pg.vt_class_color}(recv) (VAL2VFT(recv)[{value}].i)")
+       end
+       redef fun compile_to_c(v, c)
+       do
+               var prog = v.program
+               var p = c[property.global]
+               var g = p.signature_for(c.get_type).return_type.local_class.global
+               var col = g.intro.as(MMConcreteClass).class_color_pos
+               return "{prog.table_information.color(col)} /* {prog.table_information.color(self)}: VT {c}::{p} : color of {g} */"
+       end
+ end
+ redef class TableEltVTClassId
+       redef fun compile_macros(v, value)
+       do
+               var pg = property.global
+               v.add_decl("#define {pg.vt_class_id}(recv) (VAL2VFT(recv)[{value}].i)")
+       end
+       redef fun compile_to_c(v, c)
+       do
+               var prog = v.program
+               var p = c[property.global]
+               var g = p.signature_for(c.get_type).return_type.local_class.global
+               return "{prog.compiled_classes[g].id} /* {prog.table_information.color(self)}: VT {c}::{p} : id of {g} */"
+       end
+ end
  redef class TableEltAttr
        redef fun compile_macros(v, value)
        do
        end
  end
  
  redef class AbsTableEltClass
        # The C macro name refering the value
        fun symbol: String is abstract
@@@ -283,14 -315,6 +317,14 @@@ redef class TableEltClassSelfI
        end
  end
  
 +redef class TableEltClassSelfName
 +      redef fun compile_to_c(v, c)
 +      do
 +              var prog = v.program
 +              return "\"{c.global.name}\" /* {prog.table_information.color(self)}: Class Name */"
 +      end
 +end
 +
  redef class TableEltClassObjectSize
        redef fun compile_to_c(v, c)
        do
@@@ -333,7 -357,7 +367,7 @@@ redef class MMLocalClas
        do
                v.add_decl("")
                var pi = primitive_info
 -              v.add_decl("extern const classtable_elt_t VFT_{name}[];")
 +              v.add_decl("extern const classtable_elt_t VFT_{cname}[];")
                if pi != null and not pi.tagged then
                        var t = pi.cname
                        var tbox = "struct TBOX_{name}"
                        clen = v.program.table_information.max_class_table_length
                end
  
 -              v.add_instr("const classtable_elt_t VFT_{name}[{clen}] = \{")
 +              v.add_instr("const classtable_elt_t VFT_{cname}[{clen}] = \{")
                v.indent
                for e in ctab do
                        if e == null then
                        v.indent
                        v.add_instr("Nit_NativeArray array;")
                        v.add_instr("array = (Nit_NativeArray)alloc(sizeof(struct Nit_NativeArray) + ((length - 1) * size));")
 -                      v.add_instr("array->vft = (classtable_elt_t*)VFT_{name};")
 +                      v.add_instr("array->vft = (classtable_elt_t*)VFT_{cname};")
                        v.add_instr("array->object_id = object_id_counter;")
                        v.add_instr("object_id_counter = object_id_counter + 1;")
                        v.add_instr("array->size = length;")
                else if pi == null then
                        do
                                # Generate INIT_ATTRIBUTES routine
 -                              var cname = "INIT_ATTRIBUTES__{name}"
 +                              var cname = "INIT_ATTRIBUTES__{cname}"
                                var args = init_var_iroutine.compile_signature_to_c(v, cname, "init var of {name}", null, null)
                                var decl_writer_old = v.decl_writer
                                v.decl_writer = v.writer.sub
                        end
                        do
                                # Generate NEW routine
 -                              v.add_decl("val_t NEW_{name}(void);")
 -                              v.add_instr("val_t NEW_{name}(void)")
 +                              v.add_decl("val_t NEW_{cname}(void);")
 +                              v.add_instr("val_t NEW_{cname}(void)")
                                v.add_instr("\{")
                                v.indent
                                v.add_instr("obj_t obj;")
                                v.add_instr("obj = alloc(sizeof(val_t) * {itab.length});")
 -                              v.add_instr("obj->vft = (classtable_elt_t*)VFT_{name};")
 +                              v.add_instr("obj->vft = (classtable_elt_t*)VFT_{cname};")
                                v.add_instr("obj[1].object_id = object_id_counter;")
                                v.add_instr("object_id_counter = object_id_counter + 1;")
                                v.add_instr("return OBJ2VAL(obj);")
                        end
                        do
                                # Compile CHECKNAME
 -                              var cname = "CHECKNEW_{name}"
 +                              var cname = "CHECKNEW_{cname}"
                                var args = checknew_iroutine.compile_signature_to_c(v, cname, "check new {name}", null, null)
                                var decl_writer_old = v.decl_writer
                                v.decl_writer = v.writer.sub
                        v.add_instr("val_t BOX_{name}({t} val) \{")
                        v.indent
                        v.add_instr("{tbox} *box = ({tbox}*)alloc(sizeof({tbox}));")
 -                      v.add_instr("box->vft = VFT_{name};")
 +                      v.add_instr("box->vft = VFT_{cname};")
                        v.add_instr("box->val = val;")
                        v.add_instr("box->object_id = object_id_counter;")
                        v.add_instr("object_id_counter = object_id_counter + 1;")
@@@ -168,7 -168,7 +168,7 @@@ class I2CCompilerVisito
                if l != null then
                        visitor.add_indent(w)
                        w.add("/* ")
 -                      w.add(l.file)
 +                      w.add(l.file.filename)
                        w.add(":")
                        w.add(l.line_start.to_s)
                        w.add(" */\n")
@@@ -289,7 -289,7 +289,7 @@@ redef class IRoutin
                        v.add_decl("struct \{struct stack_frame_t me;\} fra;")
                end
                v.add_instr("fra.me.prev = stack_frame_head; stack_frame_head = &fra.me;")
 -              v.add_instr("fra.me.file = LOCATE_{v.visitor.mmmodule.name};")
 +              v.add_instr("fra.me.file = LOCATE_{v.visitor.mmmodule.cname};")
                v.add_instr("fra.me.line = {ll};")
                v.add_instr("fra.me.meth = LOCATE_{v.basecname};")
                v.add_instr("fra.me.has_broke = 0;")
@@@ -624,7 -624,7 +624,7 @@@ redef class IAllocateInstanc
                v.add_location(location)
                var w = new_result(v)
                w.add("NEW_")
 -              w.add(stype.local_class.name.to_s)
 +              w.add(stype.local_class.cname)
                w.add("()")
        end
  end
@@@ -635,7 -635,7 +635,7 @@@ redef class ICheckInstanc
                v.add_location(location)
                var w = new_result(v)
                w.add("CHECKNEW_")
 -              w.add(stype.local_class.name.to_s)
 +              w.add(stype.local_class.cname)
                w.add("(")
                w.add(v.register(expr))
                w.add(")")
@@@ -648,7 -648,7 +648,7 @@@ redef class IInitAttribute
                v.add_location(location)
                var w = v.new_instr
                w.add("INIT_ATTRIBUTES__")
 -              w.add(stype.local_class.name.to_s)
 +              w.add(stype.local_class.cname)
                w.add("(")
                w.add(v.register(expr))
                w.add(");\n")
@@@ -864,14 -864,7 +864,14 @@@ redef class INativ
                        s = "NEW_NativeArray(UNTAG_Int({regs[1]}), sizeof(val_t))"
                else if n == once "calloc_string".to_symbol then
                        s = "BOX_NativeString((char*)raw_alloc((UNTAG_Int({regs[1]}) * sizeof(char))))"
 +              # Add output_class_name native implementation
 +              else if n == once "output_class_name".to_symbol then
 +                      s = "printf(\"%s\\n\", VAL2VFT({regs[0]})[2].cname);"
 +              # Add class_name implementation
 +              else if n == once "native_class_name".to_symbol then
 +                      s = "BOX_NativeString(VAL2VFT({regs[0]})[2].cname);"
                end
 +
                if s == null then
                        var ll = location
                        if ll != null then v.add_instr("fprintf(stderr, \"{ll.to_s}: \");")
@@@ -950,7 -943,7 +950,7 @@@ redef class IAbor
                        w.add("\", NULL")
                end
                w.add(", LOCATE_")
 -              w.add(module_location.name.to_s)
 +              w.add(module_location.cname)
                var ll = location
                if ll != null then
                        w.add(", ")
@@@ -1023,18 -1016,16 +1023,16 @@@ redef class ITypeChec
        redef fun compile_to_c(v)
        do
                if not need_result then return
-               # FIXME handle formaltypes
                v.add_location(location)
-               var g = stype.local_class.global
-               var recv = v.register(expr)
+               var recv = v.register(expr2)
                var w = new_result(v)
                w.add("TAG_Bool(")
-               if expr.stype.is_nullable then
+               if expr2.stype.is_nullable then
                        if stype.is_nullable then
                                w.add("(")
                                w.add(recv)
                                w.add("==NIT_NULL) || ")
-                       else if stype.as_nullable == expr.stype then
+                       else if stype.as_nullable == expr2.stype then
                                w.add(recv)
                                w.add("!=NIT_NULL)")
                                return
                                w.add("!=NIT_NULL) && ")
                        end
                end
-               w.add("VAL_ISA(")
-               w.add(recv)
-               w.add(", ")
-               w.add(g.color_id)
-               w.add(", ")
-               w.add(g.id_id)
-               w.add(")) /*cast ")
-               w.add(stype.to_s)
-               w.add("*/")
+               # FIXME handle formaltypes
+               var t = stype
+               if t isa MMVirtualType then
+                       var slf = v.register(expr1)
+                       var g = t.property.global
+                       w.add("VAL_ISA(")
+                       w.add(recv)
+                       w.add(", ")
+                       w.add(g.vt_class_color)
+                       w.add("(")
+                       w.add(slf)
+                       w.add(")")
+                       w.add(", ")
+                       w.add(g.vt_class_id)
+                       w.add("(")
+                       w.add(slf)
+                       w.add(")")
+                       w.add(")) /*cast ")
+                       w.add(t.to_s)
+                       w.add("*/")
+               else
+                       var g = t.local_class.global
+                       w.add("VAL_ISA(")
+                       w.add(recv)
+                       w.add(", ")
+                       w.add(g.color_id)
+                       w.add(", ")
+                       w.add(g.id_id)
+                       w.add(")) /*cast ")
+                       w.add(t.to_s)
+                       w.add("*/")
+               end
        end
  end
  
@@@ -112,6 -112,9 +112,9 @@@ redef class MMConcreteClas
                                        ilt.add(new TableEltAttr(p))
                                else if p isa MMMethod then
                                        clt.add(new TableEltMeth(p))
+                               else if p isa MMTypeProperty then
+                                       clt.add(new TableEltVTClassId(p))
+                                       clt.add(new TableEltVTClassColor(p))
                                end
                        end
                        if p isa MMMethod and p.need_super then
@@@ -162,7 -165,6 +165,7 @@@ redef class Progra
  
                ctab.add(new TableEltClassSelfId)
                ctab.add(new TableEltClassObjectSize)
 +              ctab.add(new TableEltClassSelfName)
                itab.add(new TableEltVftPointer)
                itab.add(new TableEltObjectId)
  
@@@ -453,6 -455,16 +456,16 @@@ class TableEltMet
        super TableEltProp
  end
  
+ # An element that represents a class color value for a virtual type
+ class TableEltVTClassColor
+       super TableEltProp
+ end
+ # An element that represents a class id value for a virtual type
+ class TableEltVTClassId
+       super TableEltProp
+ end
  # An element that represents a function pointer to the super method of a local method
  class TableEltSuper
        super TableEltProp
@@@ -537,12 -549,6 +550,12 @@@ class TableEltClassSelfI
        redef fun is_related_to(c) do return true
  end
  
 +# The element that represent the class name
 +class TableEltClassSelfName
 +      super TableElt
 +      redef fun is_related_to(c) do return true
 +end
 +
  # The element that represent the Object Size
  class TableEltClassObjectSize
        super TableElt
diff --combined src/icode/icode_base.nit
@@@ -332,10 -332,7 +332,10 @@@ class INativ
  
        init(m: MMMethod, e: nullable Sequence[IRegister])
        do
 -              super(e)
 +                # Checks that arguments contains at least one IRegister element
 +                assert e.length == m.signature.arity + 1
 +              
 +                super(e)
                _method = m
        end
  
@@@ -459,15 -456,16 +459,16 @@@ class IAttrIsse
  end
  
  # A type check
- # expr is the expression checked
+ # expr1 is the type reciever (self)
+ # expr2 is the expression checked
  class ITypeCheck
-       super ICode1
+       super ICode2
        # The static type checkes to
        readable var _stype: MMType
  
-       init(e: IRegister, t: MMType)
+       init(e1, e2: IRegister, t: MMType)
        do
-               super(e)
+               super(e1, e2)
                _stype = t
        end