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
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
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]
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)
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
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
# 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
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
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