X-Git-Url: http://nitlanguage.org diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index 52caff6..6287845 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -15,10 +15,11 @@ # limitations under the License. # Generate C code from intermediate code representation -package compiling_icode +module 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") @@ -266,7 +267,9 @@ redef class IRoutine else p = cparams.join(", ") end - if human_name != null then v.add_decl("static const char * const LOCATE_{cname} = \"{human_name}\";") + if human_name != null then + v.add_instr("static const char LOCATE_{cname}[] = \"{human_name}\";") + end v.add_decl("{r} {cname}({p});") v.add_decl("typedef {r} (*{cname}_t)({p});") v.add_instr("{r} {cname}({p})\{") @@ -289,11 +292,12 @@ 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;") v.add_instr("fra.me.REG_size = {std_slots_nb};") + v.add_instr("fra.me.nitni_local_ref_head = NULL;") # Declare/initialize local variables for i in [0..std_slots_nb[ do @@ -575,6 +579,11 @@ 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") w.add(prop.global.meth_call) @@ -590,6 +599,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 @@ -607,6 +620,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("_") @@ -624,7 +642,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 @@ -635,7 +653,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(")") @@ -648,7 +666,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") @@ -675,27 +693,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 @@ -852,6 +871,14 @@ 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()" + else if n == once "native_argc".to_symbol then + s = "TAG_Int(glob_argc)" + else if n == once "native_argv".to_symbol then + s = "BOX_NativeString(glob_argv[UNTAG_Int({regs[1]})])" + 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 @@ -864,7 +891,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}: \");") @@ -896,7 +930,7 @@ redef class IBoolValue v.add_location(location) var w = new_result(v) w.add("TAG_Bool(") - if value then w.add("true") else w.add("false") + if value then w.add("1") else w.add("0") w.add(")") end end @@ -943,7 +977,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(", ") @@ -1016,18 +1050,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 @@ -1037,15 +1069,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