lib: adds a method to force invocation of garbage collector
[nit.git] / src / compiling / compiling_icode.nit
index 4623ed3..169d411 100644 (file)
@@ -19,6 +19,7 @@ package compiling_icode
 
 import icode
 private import analysis
+import primitive_info
 import compiling_base
 
 # Compiler context from ICode to C
@@ -168,7 +169,7 @@ class I2CCompilerVisitor
                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 +290,7 @@ redef class IRoutine
                        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.module.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;")
@@ -575,18 +576,17 @@ redef class ICall
        redef fun compile_call_to_c(v, args)
        do
                var w = new Writer
+               
+               # do not compile explicit calls from native methods
+               # theses are really manually called in the native implementation
+               if is_explicit_from_extern then return w
+
                var prop = property
                if prop.global.is_init then args.add("init_table")
-               if prop.name == (once ("add".to_symbol)) and prop.local_class.name == (once ("Array".to_symbol)) then
-                       w.add(prop.cname)
-                       w.add("(")
-               else
-                       w.add(prop.global.meth_call)
-                       w.add("(")
-                       w.add(args.first)
-                       w.add(")(")
-               end
-               var first = true
+               w.add(prop.global.meth_call)
+               w.add("(")
+               w.add(args.first)
+               w.add(")(")
                w.add_all(args, ", ")
                w.add(")")
                return w
@@ -596,6 +596,10 @@ end
 redef class ISuper
        redef fun compile_call_to_c(v, args)
        do
+               # do not compile explicit calls from native methods
+               # theses are really manually called in the native implementation
+               if is_explicit_from_extern then return new Writer
+
                var prop = property
                if prop.global.is_init then args.add("init_table")
                var w = new Writer
@@ -613,6 +617,11 @@ redef class INew
        redef fun compile_call_to_c(v, args)
        do
                var w = new Writer
+
+               # do not compile explicit calls from native methods
+               # theses are really manually called in the native implementation
+               if is_explicit_from_extern then return w
+
                w.add("NEW_")
                w.add(stype.local_class.to_s)
                w.add("_")
@@ -630,7 +639,7 @@ redef class IAllocateInstance
                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
@@ -641,7 +650,7 @@ redef class ICheckInstance
                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(")")
@@ -654,7 +663,7 @@ redef class IInitAttributes
                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")
@@ -681,27 +690,28 @@ redef class INative
                v.add_location(location)
                if method.is_intern then
                        compile_intern_method_to_c(v)
-               else
+               else if not method.global.is_init then
                        compile_extern_method_to_c(v)
                end
        end
 
        fun compile_extern_method_to_c(v: I2CCompilerVisitor)
        do
-               var ename = method.extern_name.as(not null)#"{method.module.name}_{method.local_class.name}_{method.local_class.name}_{method.name}_{method.signature.arity}"
+               var ename = "{method.friendly_extern_name(method.local_class)}___out"
+
                var sig = method.signature
                assert exprs.length == sig.arity + 1
 
                var regs = v.registers(exprs)
 
                var args = new Array[String]
-               args.add(sig.recv.unboxtype(regs[0]))
+               args.add(regs[0])
                for i in [0..sig.arity[ do
-                       args.add(sig[i].unboxtype(regs[i+1]))
+                       args.add(regs[i+1])
                end
                var s = "{ename}({args.join(", ")})"
 
-               if need_result then s = sig.return_type.boxtype(s)
+               if need_result then s = s # sig.return_type.boxtype(s)
                var w = new_result(v)
                w.add(s)
        end
@@ -858,6 +868,10 @@ redef class INative
                        else if n == once "copy_to".to_symbol then
                                s = "(void)memcpy(UNBOX_NativeString({regs[1]})+UNTAG_Int({regs[4]}), UNBOX_NativeString({regs[0]})+UNTAG_Int({regs[3]}), UNTAG_Int({regs[2]}));"
                        end
+               else if c == once "Sys".to_symbol then
+                       if n == once "force_garbage_collection".to_symbol then
+                               s = "Nit_gc_force_garbage_collection()"
+                       end
                else if n == once "object_id".to_symbol then
                        s = "TAG_Int((bigint)((obj_t){regs[0]})[1].object_id)"
                else if n == once "sys".to_symbol then
@@ -870,7 +884,14 @@ redef class INative
                        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}: \");")
@@ -949,7 +970,7 @@ redef class IAbort
                        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(", ")
@@ -1022,18 +1043,16 @@ redef class ITypeCheck
        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
@@ -1043,15 +1062,38 @@ redef class ITypeCheck
                                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