icode: add IAllocateInstance, ICheckInstance and IInitAttributes
authorJean-Sebastien Gelinas <calestar@gmail.com>
Mon, 17 Aug 2009 21:11:11 +0000 (17:11 -0400)
committerJean Privat <jean@pryen.org>
Wed, 19 Aug 2009 00:59:34 +0000 (20:59 -0400)
Trivially-hacked-by: Jean Privat <jean@pryen.org>

Signed-off-by: Jean-Sebastien Gelinas <calestar@gmail.com>
Signed-off-by: Jean Privat <jean@pryen.org>

src/analysis/icode_dump.nit
src/compiling/compiling_global.nit
src/compiling/compiling_icode.nit
src/icode/icode_base.nit
src/icode/icode_tools.nit

index 2b31da6..e93d866 100644 (file)
@@ -265,6 +265,13 @@ redef class ICall
        end
 end
 
+redef class IAllocateInstance
+       redef fun dump_intern(icd)
+       do
+               return "ALLOCATE NEW_{stype}"
+       end
+end
+
 redef class IStaticCall
        redef fun dump_intern(icd)
        do
@@ -272,6 +279,20 @@ redef class IStaticCall
        end
 end
 
+redef class ICheckInstance
+       redef fun dump_intern(icd)
+       do
+               return "CHECK_INSTANCE CHECKNEW_{stype}({icd.register(expr)})"
+       end
+end
+
+redef class IInitAttributes
+       redef fun dump_intern(icd)
+       do
+               return "INIT_ATTRIBUTES INIT_ATTRIBUTES_{stype}({icd.register(expr)})"
+       end
+end
+
 redef class IClosCall
        redef fun dump_intern(icd)
        do
index 20e74c3..bc69ed1 100644 (file)
@@ -916,13 +916,11 @@ redef class MMLocalClass
                        v.add_instr("}")
                else if pi == null then
                        do
+                               # Generate INIT_ATTRIBUTES routine
                                var iself = new IRegister(get_type)
                                var iselfa = [iself]
-                               var iroutine = new IRoutine(new Array[IRegister], iself)
+                               var iroutine = new IRoutine(iselfa, null)
                                var icb = new ICodeBuilder(module, iroutine)
-                               var obj = new INative("OBJ2VAL(obj)", null)
-                               obj.result = iself
-                               icb.stmt(obj)
 
                                for g in global_properties do
                                        var p = self[g]
@@ -936,23 +934,31 @@ redef class MMLocalClass
                                        end
                                end
 
-                               var cname = "NEW_{name}"
-                               var args = iroutine.compile_signature_to_c(v, cname, "new {name}", null, null)
+                               var cname = "INIT_ATTRIBUTES__{name}"
+                               var args = iroutine.compile_signature_to_c(v, cname, "init attributes of {name}", null, null)
                                var ctx_old = v.ctx
                                v.ctx = new CContext
-                               v.add_decl("obj_t obj;")
+                               iroutine.compile_to_c(v, cname, args)
+                               ctx_old.append(v.ctx)
+                               v.ctx = ctx_old
+                               v.unindent
+                               v.add_instr("}")
+                       end
+                       do
+                               # Generate NEW routine
+                               v.add_decl("val_t NEW_{name}(void);")
+                               v.add_instr("val_t NEW_{name}(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[1].object_id = object_id_counter;")
                                v.add_instr("object_id_counter = object_id_counter + 1;")
-                               var r = iroutine.compile_to_c(v, cname, args).as(not null)
-                               v.add_instr("return {r};")
-                               ctx_old.append(v.ctx)
-                               v.ctx = ctx_old
+                               v.add_instr("return OBJ2VAL(obj);")
                                v.unindent
                                v.add_instr("}")
                        end
-
                        do
                                # Compile CHECKNAME
                                var iself = new IRegister(get_type)
@@ -993,14 +999,16 @@ redef class MMLocalClass
                                iroutine.location = p.iroutine.location
                                var icb = new ICodeBuilder(module, iroutine)
 
-                               var inew = new INative("NEW_{name}()", null)
+                               var inew = new IAllocateInstance(get_type)
                                inew.result = iself
                                icb.stmt(inew)
                                var iargs = [iself]
                                iargs.add_all(iparams)
 
+                               icb.stmt(new IInitAttributes(get_type, iself))
                                icb.stmt(new IStaticCall(p, iargs))
-                               icb.stmt(new INative("CHECKNEW_{name}(@@@)", [iself]))
+                               icb.stmt(new ICheckInstance(get_type, iself))
+
                                var cname = "NEW_{self}_{p.global.intro.cname}"
                                var new_args = iroutine.compile_signature_to_c(v, cname, "new {self} {p.full_name}", null, null)
                                var ctx_old = v.ctx
index e0be792..011dca5 100644 (file)
@@ -558,6 +558,27 @@ redef class INew
        end
 end
 
+redef class IAllocateInstance
+       redef fun inner_compile_to_c(v)
+       do
+               return "NEW_{stype.local_class.name}()"
+       end
+end
+
+redef class ICheckInstance
+       redef fun inner_compile_to_c(v)
+       do
+               return "CHECKNEW_{stype.local_class.name}({v.register(expr)})"
+       end
+end
+
+redef class IInitAttributes
+       redef fun inner_compile_to_c(v)
+       do
+               return "INIT_ATTRIBUTES__{stype.local_class.name}({v.register(expr)})"
+       end
+end
+
 redef class IStaticCall
        redef fun compile_call_to_c(v, args)
        do
index 3dd1184..922284b 100644 (file)
@@ -235,6 +235,11 @@ end
 
 # An instantiation
 # no reciever, all exprs are arguments
+# Will call in order:
+# - IAllocateInstance
+# - IInitAttributes
+# - IStaticCall -> target Initializer
+# - ICheckInstance
 class INew
 special IAbsCall
        # The type to instantiate
@@ -246,12 +251,49 @@ special IAbsCall
        end
 end
 
+# An allocation of a new object
+# No receivers, returns a new object of type 't'
+# Will allocate memory and ensure dynamic type and object identity
+class IAllocateInstance
+special ICode0
+       # The type to allocate
+       readable var _stype: MMType
+       init(t: MMType)
+       do
+               _stype = t
+       end
+end
+
 # A static call to a specific method
 class IStaticCall
 special IAbsCall
        init(p: MMMethod, a: Sequence[IRegister]) do super
 end
 
+# A validation of a newly constructed instance
+class ICheckInstance
+special ICode1
+       # The type to allocate
+       readable var _stype: MMType
+       init(t: MMType, e: IRegister)
+       do
+               super(e)
+               _stype = t
+       end
+end
+
+# Initialisation of default attributes of a new instance
+class IInitAttributes
+special ICode1
+       # The type to initialize
+       readable var _stype: MMType
+       init(t: MMType, e: IRegister)
+       do
+               super(e)
+               _stype = t
+       end
+end
+
 # A closure call
 # exprs are the arguments
 class IClosCall
index 9109c38..100c4b3 100644 (file)
@@ -298,12 +298,34 @@ redef class INew
        end
 end
 
+redef class IAllocateInstance
+       redef fun inner_dup_with(d)
+       do
+               return new IAllocateInstance(stype)
+       end
+end
+
 redef class IStaticCall
        redef fun inner_dup_with(d)
        do
                return new IStaticCall(property, d.dup_iregs(exprs))
        end
 end
+
+redef class ICheckInstance
+       redef fun inner_dup_with(d)
+       do
+               return new ICheckInstance(stype, d.dup_ireg(expr))
+       end
+end
+
+redef class IInitAttributes
+       redef fun inner_dup_with(d)
+       do
+               return new IInitAttributes(stype, d.dup_ireg(expr))
+       end
+end
+
 redef class IClosCall
        redef fun dup_with(d)
        do