From dc71ae49f0d7482e41feecc3de6abf636b0e4def Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Wed, 10 Feb 2010 16:49:54 -0500 Subject: [PATCH] icode: link INative with a MMMethod instead of a raw C code syntax/icode_generation.nit is made cleaner since all the C stuff is now done in compiling/compiling_icode.nit Signed-off-by: Jean Privat --- src/analysis/icode_dump.nit | 6 +- src/compiling/compiling_icode.nit | 213 +++++++++++++++++++++++++++++++++++-- src/icode/icode_base.nit | 13 ++- src/icode/icode_tools.nit | 2 +- src/syntax/icode_generation.nit | 197 ++-------------------------------- 5 files changed, 216 insertions(+), 215 deletions(-) diff --git a/src/analysis/icode_dump.nit b/src/analysis/icode_dump.nit index 4a618d3..f72f74c 100644 --- a/src/analysis/icode_dump.nit +++ b/src/analysis/icode_dump.nit @@ -371,11 +371,7 @@ end redef class INative redef fun dump_intern(icd) do - if exprs.is_empty then - return "NATIVE \"{code}\"" - else - return "NATIVE \"{code}\"({icd.register_all(exprs)})" - end + return "NATIVE \"{method.full_name}\"({icd.register_all(exprs)})" end end diff --git a/src/compiling/compiling_icode.nit b/src/compiling/compiling_icode.nit index 264bd5e..9b14dec 100644 --- a/src/compiling/compiling_icode.nit +++ b/src/compiling/compiling_icode.nit @@ -679,19 +679,210 @@ redef class INative redef fun compile_to_c(v) do v.add_location(location) - var w = new_result(v) - if exprs.is_empty then - w.add(code) + if method.is_intern then + compile_intern_method_to_c(v) else - var i = 0 - var c = code.split_with("@@@") - for s in c do - w.add(s) - if i < exprs.length and i < c.length-1 then - w.add(v.register(exprs[i])) - end - i += 1 + 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 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])) + for i in [0..sig.arity[ do + args.add(sig[i].unboxtype(regs[i+1])) + end + var s = "{ename}({args.join(", ")})" + + if need_result then s = sig.return_type.boxtype(s) + var w = new_result(v) + w.add(s) + end + + fun compile_intern_method_to_c(v: I2CCompilerVisitor) + do + var sig = method.signature + assert exprs.length == sig.arity + 1 + var c = method.local_class.name + var n = method.name + var regs = v.registers(exprs) + var s: nullable String = null + if c == once "Int".to_symbol then + if n == once "object_id".to_symbol then + s = regs[0] + else if n == once "unary -".to_symbol then + s = "TAG_Int(-UNTAG_Int({regs[0]}))" + else if n == once "output".to_symbol then + s = "printf(\"%ld\\n\", UNTAG_Int({regs[0]}));" + else if n == once "ascii".to_symbol then + s = "TAG_Char(UNTAG_Int({regs[0]}))" + else if n == once "succ".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})+1)" + else if n == once "prec".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})-1)" + else if n == once "to_f".to_symbol then + s = "BOX_Float((float)UNTAG_Int({regs[0]}))" + else if n == once "+".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})+UNTAG_Int({regs[1]}))" + else if n == once "-".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})-UNTAG_Int({regs[1]}))" + else if n == once "*".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})*UNTAG_Int({regs[1]}))" + else if n == once "/".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})/UNTAG_Int({regs[1]}))" + else if n == once "%".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})%UNTAG_Int({regs[1]}))" + else if n == once "<".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})>UNTAG_Int({regs[1]}))" + else if n == once "<=".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})<=UNTAG_Int({regs[1]}))" + else if n == once ">=".to_symbol then + s = "TAG_Bool(UNTAG_Int({regs[0]})>=UNTAG_Int({regs[1]}))" + else if n == once "lshift".to_symbol then + s = "TAG_Int(UNTAG_Int({regs[0]})<".to_symbol then + s = "TAG_Bool(UNBOX_Float({regs[0]})>UNBOX_Float({regs[1]}))" + else if n == once "<=".to_symbol then + s = "TAG_Bool(UNBOX_Float({regs[0]})<=UNBOX_Float({regs[1]}))" + else if n == once ">=".to_symbol then + s = "TAG_Bool(UNBOX_Float({regs[0]})>=UNBOX_Float({regs[1]}))" + end + else if c == once "Char".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(UNTAG_Char({regs[0]}))" + else if n == once "unary -".to_symbol then + s = "TAG_Char(-UNTAG_Char({regs[0]}))" + else if n == once "output".to_symbol then + s = "printf(\"%c\", (unsigned char)UNTAG_Char({regs[0]}));" + else if n == once "ascii".to_symbol then + s = "TAG_Int((unsigned char)UNTAG_Char({regs[0]}))" + else if n == once "succ".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})+1)" + else if n == once "prec".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})-1)" + else if n == once "to_i".to_symbol then + s = "TAG_Int(UNTAG_Char({regs[0]})-'0')" + else if n == once "+".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})+UNTAG_Char({regs[1]}))" + else if n == once "-".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})-UNTAG_Char({regs[1]}))" + else if n == once "*".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})*UNTAG_Char({regs[1]}))" + else if n == once "/".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})/UNTAG_Char({regs[1]}))" + else if n == once "%".to_symbol then + s = "TAG_Char(UNTAG_Char({regs[0]})%UNTAG_Char({regs[1]}))" + else if n == once "<".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})>UNTAG_Char({regs[1]}))" + else if n == once "<=".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})<=UNTAG_Char({regs[1]}))" + else if n == once ">=".to_symbol then + s = "TAG_Bool(UNTAG_Char({regs[0]})>=UNTAG_Char({regs[1]}))" + else if n == once "==".to_symbol then + s = "TAG_Bool(({regs[0]})==({regs[1]}))" + else if n == once "!=".to_symbol then + s = "TAG_Bool(({regs[0]})!=({regs[1]}))" + end + else if c == once "Bool".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(UNTAG_Bool({regs[0]}))" + else if n == once "unary -".to_symbol then + s = "TAG_Bool(-UNTAG_Bool({regs[0]}))" + else if n == once "output".to_symbol then + s = "(void)printf(UNTAG_Bool({regs[0]})?\"true\\n\":\"false\\n\");" + else if n == once "ascii".to_symbol then + s = "TAG_Bool(UNTAG_Bool({regs[0]}))" + else if n == once "to_i".to_symbol then + s = "TAG_Int(UNTAG_Bool({regs[0]}))" + else if n == once "==".to_symbol then + s = "TAG_Bool(({regs[0]})==({regs[1]}))" + else if n == once "!=".to_symbol then + s = "TAG_Bool(({regs[0]})!=({regs[1]}))" end + else if c == once "NativeArray".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(((Nit_NativeArray){regs[0]})->object_id)" + else if n == once "[]".to_symbol then + s = "((Nit_NativeArray){regs[0]})->val[UNTAG_Int({regs[1]})]" + else if n == once "[]=".to_symbol then + s = "((Nit_NativeArray){regs[0]})->val[UNTAG_Int({regs[1]})]={regs[2]}" + else if n == once "copy_to".to_symbol then + s = "(void)memcpy(((Nit_NativeArray ){regs[1]})->val, ((Nit_NativeArray){regs[0]})->val, UNTAG_Int({regs[2]})*sizeof(val_t))" + end + else if c == once "NativeString".to_symbol then + if n == once "object_id".to_symbol then + s = "TAG_Int(UNBOX_NativeString({regs[0]}))" + else if n == once "atoi".to_symbol then + s = "TAG_Int(atoi(UNBOX_NativeString({regs[0]})))" + else if n == once "[]".to_symbol then + s = "TAG_Char(UNBOX_NativeString({regs[0]})[UNTAG_Int({regs[1]})])" + else if n == once "[]=".to_symbol then + s = "UNBOX_NativeString({regs[0]})[UNTAG_Int({regs[1]})]=UNTAG_Char({regs[2]});" + 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 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 + s = "(G_sys)" + else if n == once "is_same_type".to_symbol then + s = "TAG_Bool((VAL2VFT({regs[0]})==VAL2VFT({regs[1]})))" + else if n == once "exit".to_symbol then + s = "exit(UNTAG_Int({regs[1]}));" + else if n == once "calloc_array".to_symbol then + 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))))" + end + if s == null then + var ll = location + if ll != null then v.add_instr("fprintf(stderr, \"{ll.to_s}: \");") + v.add_instr("fprintf(stderr, \"Fatal error: unknown intern method {method.full_name}.\\n\");") + v.add_instr("nit_exit(1);") + s = "NIT_NULL" + end + if result == null then + v.new_instr.add(s).add(";\n") + else if need_result then + var w = new_result(v) + w.add(s) end end end diff --git a/src/icode/icode_base.nit b/src/icode/icode_base.nit index 3db7132..6afa03d 100644 --- a/src/icode/icode_base.nit +++ b/src/icode/icode_base.nit @@ -322,19 +322,18 @@ special ICodeN end end -# A native C code -# Mainly used to implements things that do not have a specific ICode yet +# A native inlined call +# Native are associated to local properties to distinguish them # expr are the arguments class INative special ICodeN - # The native C code - # Special character sequence '@@@' will be substitued in order with the arguments - readable var _code: String + # The associated local property + readable var _method: MMMethod - init(c: String, e: nullable Sequence[IRegister]) + init(m: MMMethod, e: nullable Sequence[IRegister]) do super(e) - _code = c + _method = m end redef readable writable var _is_pure: Bool = false diff --git a/src/icode/icode_tools.nit b/src/icode/icode_tools.nit index 2ee7b8b..cfe1992 100644 --- a/src/icode/icode_tools.nit +++ b/src/icode/icode_tools.nit @@ -384,7 +384,7 @@ end redef class INative redef fun inner_dup_with(d) do - var c2 = new INative(code, d.dup_iregs(exprs)) + var c2 = new INative(method, d.dup_iregs(exprs)) c2.is_pure = is_pure return c2 end diff --git a/src/syntax/icode_generation.nit b/src/syntax/icode_generation.nit index b5de2be..acf2efe 100644 --- a/src/syntax/icode_generation.nit +++ b/src/syntax/icode_generation.nit @@ -397,21 +397,11 @@ redef class AExternMethPropdef redef fun fill_iroutine(v, method) do var params = v.iroutine.params - var ename = method.extern_name.as(not null) - var sig = method.signature - assert params.length == sig.arity + 1 - var args = new Array[String] - args.add(sig.recv.unboxtype("@@@")) - for i in [0..sig.arity[ do - args.add(sig[i].unboxtype("@@@")) - end - var s = "{ename}({args.join(", ")})" - var rtype = sig.return_type + var rtype = method.signature.return_type if rtype != null then - s = rtype.boxtype(s) - v.add_return_value(v.expr(new INative(s, params), rtype)) + v.add_return_value(v.expr(new INative(method, params), rtype)) else - v.stmt(new INative(s, params)) + v.stmt(new INative(method, params)) end end end @@ -419,187 +409,12 @@ end redef class AInternMethPropdef redef fun fill_iroutine(v, method) do - var p = v.iroutine.params.to_a - var c = method.local_class.name - var n = method.name - var s: nullable String = null - if c == once "Int".to_symbol then - if n == once "object_id".to_symbol then - s = "@@@" - else if n == once "unary -".to_symbol then - s = "TAG_Int(-UNTAG_Int(@@@))" - else if n == once "output".to_symbol then - s = "printf(\"%ld\\n\", UNTAG_Int(@@@));" - else if n == once "ascii".to_symbol then - s = "TAG_Char(UNTAG_Int(@@@))" - else if n == once "succ".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)+1)" - else if n == once "prec".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)-1)" - else if n == once "to_f".to_symbol then - s = "BOX_Float((float)UNTAG_Int(@@@))" - else if n == once "+".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)+UNTAG_Int(@@@))" - else if n == once "-".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)-UNTAG_Int(@@@))" - else if n == once "*".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)*UNTAG_Int(@@@))" - else if n == once "/".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)/UNTAG_Int(@@@))" - else if n == once "%".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)%UNTAG_Int(@@@))" - else if n == once "<".to_symbol then - s = "TAG_Bool(UNTAG_Int(@@@)".to_symbol then - s = "TAG_Bool(UNTAG_Int(@@@)>UNTAG_Int(@@@))" - else if n == once "<=".to_symbol then - s = "TAG_Bool(UNTAG_Int(@@@)<=UNTAG_Int(@@@))" - else if n == once ">=".to_symbol then - s = "TAG_Bool(UNTAG_Int(@@@)>=UNTAG_Int(@@@))" - else if n == once "lshift".to_symbol then - s = "TAG_Int(UNTAG_Int(@@@)<".to_symbol then - s = "TAG_Bool(UNBOX_Float(@@@)>UNBOX_Float(@@@))" - else if n == once "<=".to_symbol then - s = "TAG_Bool(UNBOX_Float(@@@)<=UNBOX_Float(@@@))" - else if n == once ">=".to_symbol then - s = "TAG_Bool(UNBOX_Float(@@@)>=UNBOX_Float(@@@))" - end - else if c == once "Char".to_symbol then - if n == once "object_id".to_symbol then - s = "TAG_Int(UNTAG_Char(@@@))" - else if n == once "unary -".to_symbol then - s = "TAG_Char(-UNTAG_Char(@@@))" - else if n == once "output".to_symbol then - s = "printf(\"%c\", (unsigned char)UNTAG_Char(@@@));" - else if n == once "ascii".to_symbol then - s = "TAG_Int((unsigned char)UNTAG_Char(@@@))" - else if n == once "succ".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)+1)" - else if n == once "prec".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)-1)" - else if n == once "to_i".to_symbol then - s = "TAG_Int(UNTAG_Char(@@@)-'0')" - else if n == once "+".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)+UNTAG_Char(@@@))" - else if n == once "-".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)-UNTAG_Char(@@@))" - else if n == once "*".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)*UNTAG_Char(@@@))" - else if n == once "/".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)/UNTAG_Char(@@@))" - else if n == once "%".to_symbol then - s = "TAG_Char(UNTAG_Char(@@@)%UNTAG_Char(@@@))" - else if n == once "<".to_symbol then - s = "TAG_Bool(UNTAG_Char(@@@)".to_symbol then - s = "TAG_Bool(UNTAG_Char(@@@)>UNTAG_Char(@@@))" - else if n == once "<=".to_symbol then - s = "TAG_Bool(UNTAG_Char(@@@)<=UNTAG_Char(@@@))" - else if n == once ">=".to_symbol then - s = "TAG_Bool(UNTAG_Char(@@@)>=UNTAG_Char(@@@))" - else if n == once "==".to_symbol then - s = "TAG_Bool((@@@)==(@@@))" - else if n == once "!=".to_symbol then - s = "TAG_Bool((@@@)!=(@@@))" - end - else if c == once "Bool".to_symbol then - if n == once "object_id".to_symbol then - s = "TAG_Int(UNTAG_Bool(@@@))" - else if n == once "unary -".to_symbol then - s = "TAG_Bool(-UNTAG_Bool(@@@))" - else if n == once "output".to_symbol then - s = "(void)printf(UNTAG_Bool(@@@)?\"true\\n\":\"false\\n\");" - else if n == once "ascii".to_symbol then - s = "TAG_Bool(UNTAG_Bool(@@@))" - else if n == once "to_i".to_symbol then - s = "TAG_Int(UNTAG_Bool(@@@))" - else if n == once "==".to_symbol then - s = "TAG_Bool((@@@)==(@@@))" - else if n == once "!=".to_symbol then - s = "TAG_Bool((@@@)!=(@@@))" - end - else if c == once "NativeArray".to_symbol then - if n == once "object_id".to_symbol then - s = "TAG_Int(((Nit_NativeArray)@@@)->object_id)" - else if n == once "[]".to_symbol then - s = "((Nit_NativeArray)@@@)->val[UNTAG_Int(@@@)]" - else if n == once "[]=".to_symbol then - s = "((Nit_NativeArray)@@@)->val[UNTAG_Int(@@@)]=@@@" - else if n == once "copy_to".to_symbol then - var t = p[0] - p[0] = p[1] - p[1] = t - s = "(void)memcpy(((Nit_NativeArray )@@@)->val, ((Nit_NativeArray)@@@)->val, UNTAG_Int(@@@)*sizeof(val_t))" - end - else if c == once "NativeString".to_symbol then - if n == once "object_id".to_symbol then - s = "TAG_Int(UNBOX_NativeString(@@@))" - else if n == once "atoi".to_symbol then - s = "TAG_Int(atoi(UNBOX_NativeString(@@@)))" - else if n == once "[]".to_symbol then - s = "TAG_Char(UNBOX_NativeString(@@@)[UNTAG_Int(@@@)])" - else if n == once "[]=".to_symbol then - s = "UNBOX_NativeString(@@@)[UNTAG_Int(@@@)]=UNTAG_Char(@@@);" - else if n == once "copy_to".to_symbol then - var t = p[0] - p[0] = p[1] - p[1] = p[4] - p[4] = p[2] - p[2] = t - s = "(void)memcpy(UNBOX_NativeString(@@@)+UNTAG_Int(@@@), UNBOX_NativeString(@@@)+UNTAG_Int(@@@), UNTAG_Int(@@@));" - end - else if n == once "object_id".to_symbol then - s = "TAG_Int((bigint)((obj_t)@@@)[1].object_id)" - else if n == once "sys".to_symbol then - s = "(G_sys)" - else if n == once "is_same_type".to_symbol then - s = "TAG_Bool((VAL2VFT(@@@)==VAL2VFT(@@@)))" - else if n == once "exit".to_symbol then - p[0] = p[1] - s = "exit(UNTAG_Int(@@@));" - else if n == once "calloc_array".to_symbol then - p[0] = p[1] - s = "NEW_NativeArray(UNTAG_Int(@@@), sizeof(val_t))" - else if n == once "calloc_string".to_symbol then - p[0] = p[1] - s = "BOX_NativeString((char*)raw_alloc((UNTAG_Int(@@@) * sizeof(char))))" - end - if s == null then - v.visitor.error(self, "Fatal error: unknown intern method {method.full_name}.") - s = "NIT_NULL" - end + var params = v.iroutine.params var rtype = method.signature.return_type if rtype != null then - v.add_return_value(v.expr(new INative(s, p), rtype)) + v.add_return_value(v.expr(new INative(method, params), rtype)) else - v.stmt(new INative(s, p)) + v.stmt(new INative(method, params)) end end end -- 1.7.9.5