clib: new raw_alloc and register_static_object services
[nit.git] / src / compiling / compiling_global.nit
index b66c57a..e878a30 100644 (file)
@@ -177,7 +177,9 @@ redef class MMModule
                var itab = new Array[TableElt]
 
                ctab.add(new TableEltClassSelfId)
+               ctab.add(new TableEltClassObjectSize)
                itab.add(new TableEltVftPointer)
+               itab.add(new TableEltObjectId)
 
                var pclassid = -1
                var classid = 3
@@ -461,6 +463,7 @@ redef class MMModule
                        else
                                var mainm = sys.select_method(name)
                                v.add_instr("G_sys = NEW_Sys();")
+                               v.add_instr("register_static_object(&G_sys);")
                                v.add_instr("{mainm.cname}(G_sys);")
                        end
                end
@@ -497,8 +500,8 @@ redef class MMModule
                                if pg.is_init_for(c) then
                                        # Declare constructors
                                        var params = new Array[String]
-                                       for i in [0..p.signature.arity[ do
-                                               params.add("val_t p{i}")
+                                       for j in [0..p.signature.arity[ do
+                                               params.add("val_t p{j}")
                                        end
                                        v.add_decl("val_t NEW_{c}_{p.global.intro.cname}({params.join(", ")});")
                                end
@@ -769,6 +772,39 @@ special TableElt
        end
 end
 
+
+# The element that represent the Object Size
+class TableEltClassObjectSize
+special TableElt
+       redef fun is_related_to(c) do return true
+       redef fun compile_to_c(v, c)
+       do
+        var nb = 0
+        var ga = v.global_analysis
+               if c.name == "NativeArray".to_symbol then
+                       nb = -1
+               else
+                       var cc = ga.compiled_classes[c.global]
+                       var itab = cc.instance_table
+                       for e in itab do
+                               nb += 1
+                       end
+               end
+               return "{nb} /* {ga.color(self)}: Object size (-1 if a NativeArray)*/"
+       end
+end
+
+# The element that represent the object id
+class TableEltObjectId
+special TableElt
+       redef fun is_related_to(c) do return true
+       redef fun compile_to_c(v, c)
+       do
+               var ga = v.global_analysis
+               return "/* {ga.color(self)}: Object_id */"
+       end
+end
+
 # The element that
 class TableEltVftPointer
 special TableElt
@@ -819,12 +855,14 @@ redef class MMLocalClass
                v.add_decl("")
                var pi = primitive_info
                v.add_decl("extern const classtable_elt_t VFT_{name}[];")
-               if pi == null then
+               if name == "NativeArray".to_symbol then
+                       v.add_decl("val_t NEW_NativeArray(size_t length, size_t size);")
+               else if pi == null then
                        # v.add_decl("val_t NEW_{name}(void);")
                else if not pi.tagged then
                        var t = pi.cname
                        var tbox = "struct TBOX_{name}"
-                       v.add_decl("{tbox} \{ const classtable_elt_t * vft; {t} val;};")
+                       v.add_decl("{tbox} \{ const classtable_elt_t * vft; bigint object_id; {t} val;};")
                        v.add_decl("val_t BOX_{name}({t} val);")
                        v.add_decl("#define UNBOX_{name}(x) ((({tbox} *)(VAL2OBJ(x)))->val)")
                end
@@ -864,62 +902,80 @@ redef class MMLocalClass
                end
 
                var pi = primitive_info
-               if pi == null then
-                       var iself = new IRegister(get_type)
-                       var iselfa = [iself]
-                       var iroutine = new IRoutine(new Array[IRegister], iself)
-                       var icb = new ICodeBuilder(module, iroutine, null)
-                       var obj = new INative("OBJ2VAL(obj)", null)
-                       obj.result = iself
-                       icb.stmt(obj)
-
-                       for g in global_properties do
-                               var p = self[g]
-                               var t = p.signature.return_type
-                               if p isa MMAttribute and t != null then
-                                       var ir = p.iroutine
-                                       if ir == null then continue
-                                       # FIXME: Not compatible with sep compilation
-                                       var e = ir.inline_in_seq(icb.seq, iselfa).as(not null)
-                                       icb.stmt(new IAttrWrite(p, iself, e))
-                               end
-                       end
-
-                       var cname = "NEW_{name}"
-                       var args = iroutine.compile_signature_to_c(v, cname, "new {name}", null, null)
-                       var ctx_old = v.ctx
-                       v.ctx = new CContext
-                       v.add_decl("obj_t obj;")
-                       v.add_instr("obj = alloc(sizeof(val_t) * {itab.length});")
-                       v.add_instr("obj->vft = (classtable_elt_t*)VFT_{name};")
-                       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
+               if name == "NativeArray".to_symbol then
+                       v.add_instr("val_t NEW_NativeArray(size_t length, size_t size) \{")
+                       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->object_id = object_id_counter;")
+                       v.add_instr("object_id_counter = object_id_counter + 1;")
+                       v.add_instr("array->size = length;")
+                       v.add_instr("return OBJ2VAL(array);")
                        v.unindent
                        v.add_instr("}")
+               else if pi == null then
+                       do
+                               var iself = new IRegister(get_type)
+                               var iselfa = [iself]
+                               var iroutine = new IRoutine(new Array[IRegister], iself)
+                               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]
+                                       var t = p.signature.return_type
+                                       if p isa MMAttribute and t != null then
+                                               var ir = p.iroutine
+                                               if ir == null then continue
+                                               # FIXME: Not compatible with sep compilation
+                                               var e = icb.inline_routine(ir, iselfa, null).as(not null)
+                                               icb.stmt(new IAttrWrite(p, iself, e))
+                                       end
+                               end
 
-                       # Compile CHECKNAME
-                       var iself = new IRegister(get_type)
-                       var iselfa = [iself]
-                       var iroutine = new IRoutine(iselfa, null)
-                       var icb = new ICodeBuilder(module, iroutine, null)
-                       for g in global_properties do
-                               var p = self[g]
-                               var t = p.signature.return_type
-                               if p isa MMAttribute and t != null and not t.is_nullable then
-                                       icb.add_attr_check(p, iself)
+                               var cname = "NEW_{name}"
+                               var args = iroutine.compile_signature_to_c(v, cname, "new {name}", null, null)
+                               var ctx_old = v.ctx
+                               v.ctx = new CContext
+                               v.add_decl("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.unindent
+                               v.add_instr("}")
+                       end
+
+                       do
+                               # Compile CHECKNAME
+                               var iself = new IRegister(get_type)
+                               var iselfa = [iself]
+                               var iroutine = new IRoutine(iselfa, null)
+                               var icb = new ICodeBuilder(module, iroutine)
+                               for g in global_properties do
+                                       var p = self[g]
+                                       var t = p.signature.return_type
+                                       if p isa MMAttribute and t != null and not t.is_nullable then
+                                               icb.add_attr_check(p, iself)
+                                       end
                                end
+                               var cname = "CHECKNEW_{name}"
+                               var args = iroutine.compile_signature_to_c(v, cname, "check new {name}", null, null)
+                               var ctx_old = v.ctx
+                               v.ctx = new CContext
+                               iroutine.compile_to_c(v, cname, args)
+                               ctx_old.append(v.ctx)
+                               v.ctx = ctx_old
+                               v.unindent
+                               v.add_instr("}")
                        end
-                       var cname = "CHECKNEW_{name}"
-                       var args = iroutine.compile_signature_to_c(v, cname, "check new {name}", null, null)
-                       var ctx_old = v.ctx
-                       v.ctx = new CContext
-                       iroutine.compile_to_c(v, cname, args)
-                       ctx_old.append(v.ctx)
-                       v.ctx = ctx_old
-                       v.unindent
-                       v.add_instr("}")
 
                        var init_table_size = cshe.greaters.length + 1
                        var init_table_decl = "int init_table[{init_table_size}] = \{0{", 0" * (init_table_size-1)}};"
@@ -935,7 +991,7 @@ redef class MMLocalClass
                                for i in [0..p.signature.arity[ do iparams.add(new IRegister(p.signature[i]))
                                var iroutine = new IRoutine(iparams, iself)
                                iroutine.location = p.iroutine.location
-                               var icb = new ICodeBuilder(module, iroutine, p)
+                               var icb = new ICodeBuilder(module, iroutine)
 
                                var inew = new INative("NEW_{name}()", null)
                                inew.result = iself
@@ -965,6 +1021,8 @@ redef class MMLocalClass
                        v.add_instr("{tbox} *box = ({tbox}*)alloc(sizeof({tbox}));")
                        v.add_instr("box->vft = VFT_{name};")
                        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;")
                        v.add_instr("return OBJ2VAL(box);")
                        v.unindent
                        v.add_instr("}")