From: Jean-Sebastien Gelinas Date: Mon, 17 Aug 2009 21:11:11 +0000 (-0400) Subject: icode: add IAllocateInstance, ICheckInstance and IInitAttributes X-Git-Tag: v0.3~39 X-Git-Url: http://nitlanguage.org icode: add IAllocateInstance, ICheckInstance and IInitAttributes Trivially-hacked-by: Jean Privat Signed-off-by: Jean-Sebastien Gelinas Signed-off-by: Jean Privat --- diff --git a/src/analysis/icode_dump.nit b/src/analysis/icode_dump.nit index 2b31da6..e93d866 100644 --- a/src/analysis/icode_dump.nit +++ b/src/analysis/icode_dump.nit @@ -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 diff --git a/src/compiling/compiling_global.nit b/src/compiling/compiling_global.nit index 20e74c3..bc69ed1 100644 --- a/src/compiling/compiling_global.nit +++ b/src/compiling/compiling_global.nit @@ -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 diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index e0be792..011dca5 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -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 diff --git a/src/icode/icode_base.nit b/src/icode/icode_base.nit index 3dd1184..922284b 100644 --- a/src/icode/icode_base.nit +++ b/src/icode/icode_base.nit @@ -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 diff --git a/src/icode/icode_tools.nit b/src/icode/icode_tools.nit index 9109c38..100c4b3 100644 --- a/src/icode/icode_tools.nit +++ b/src/icode/icode_tools.nit @@ -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