X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/abstract_compiler.nit b/src/compiler/abstract_compiler.nit index f177ef6..02e489d 100644 --- a/src/compiler/abstract_compiler.nit +++ b/src/compiler/abstract_compiler.nit @@ -654,9 +654,21 @@ abstract class AbstractCompiler self.header.add_decl("#include \n") self.header.add_decl("#include \n") self.header.add_decl("#include \n") + self.header.add_decl("#ifdef __linux__") + self.header.add_decl(" #include ") + self.header.add_decl("#endif") self.header.add_decl("#include \n") self.header.add_decl("#include \"gc_chooser.h\"") + self.header.add_decl("#ifdef __APPLE__") + self.header.add_decl(" #include ") + self.header.add_decl(" #define be32toh(x) OSSwapBigToHostInt32(x)") + self.header.add_decl("#endif") + self.header.add_decl("#ifdef __pnacl__") + self.header.add_decl(" #define be16toh(val) (((val) >> 8) | ((val) << 8))") + self.header.add_decl(" #define be32toh(val) ((be16toh((val) << 16) | (be16toh((val) >> 16))))") + self.header.add_decl("#endif") self.header.add_decl("#ifdef ANDROID") + self.header.add_decl(" #define be32toh(val) betoh32(val)") self.header.add_decl(" #include ") self.header.add_decl(" #define PRINT_ERROR(...) (void)__android_log_print(ANDROID_LOG_WARN, \"Nit\", __VA_ARGS__)") self.header.add_decl("#else") @@ -853,12 +865,14 @@ extern void nitni_global_ref_decr( struct nitni_ref *ref ); v.add_decl("int main(int argc, char** argv) \{") end + v.add "#if !defined(__ANDROID__) && !defined(TARGET_OS_IPHONE)" v.add("signal(SIGABRT, sig_handler);") v.add("signal(SIGFPE, sig_handler);") v.add("signal(SIGILL, sig_handler);") v.add("signal(SIGINT, sig_handler);") v.add("signal(SIGTERM, sig_handler);") v.add("signal(SIGSEGV, sig_handler);") + v.add "#endif" v.add("signal(SIGPIPE, SIG_IGN);") v.add("glob_argc = argc; glob_argv = argv;") @@ -1178,7 +1192,7 @@ abstract class AbstractCompilerVisitor fun calloc_array(ret_type: MType, arguments: Array[RuntimeVariable]) is abstract - fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable]) is abstract + fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable]): Bool do return false # Return an element of a native array. # The method is unsafe and is just a direct wrapper for the specific implementation of native arrays @@ -1657,7 +1671,7 @@ abstract class AbstractCompilerVisitor # This is used for the legacy FFI fun add_extern(mmodule: MModule) do - var file = mmodule.location.file.filename + var file = mmodule.filepath file = file.strip_extension(".nit") var tryfile = file + ".nit.h" if tryfile.file_exists then @@ -2078,19 +2092,20 @@ redef class MMethodDef var msignature = self.msignature.as(not null) for i in [0..msignature.arity[ do + var mp = msignature.mparameters[i] # skip test for vararg since the array is instantiated with the correct polymorphic type - if msignature.vararg_rank == i then continue + if mp.is_vararg then continue # skip if the cast is not required var origmtype = self.mproperty.intro.msignature.mparameters[i].mtype if not origmtype.need_anchor then continue # get the parameter type - var mtype = msignature.mparameters[i].mtype + var mtype = mp.mtype # generate the cast # note that v decides if and how to implements the cast - v.add("/* Covariant cast for argument {i} ({msignature.mparameters[i].name}) {arguments[i+1].inspect} isa {mtype} */") + v.add("/* Covariant cast for argument {i} ({mp.name}) {arguments[i+1].inspect} isa {mtype} */") v.add_cast(arguments[i+1], mtype, "covariance") end end @@ -2132,7 +2147,8 @@ redef class AMethPropdef # Try special compilation if mpropdef.is_intern then if compile_intern_to_c(v, mpropdef, arguments) then return - else if mpropdef.is_extern then + end + if mpropdef.is_extern then if mpropdef.mproperty.is_init then if compile_externinit_to_c(v, mpropdef, arguments) then return else @@ -2247,6 +2263,21 @@ redef class AMethPropdef else if pname == "to_b" then v.ret(v.new_expr("(unsigned char){arguments[0]}", ret.as(not null))) return true + else if pname == "code_point" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true + else if pname == "|" then + v.ret(v.new_expr("{arguments[0]} | {arguments[1]}", ret.as(not null))) + return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true end else if cname == "Char" then if pname == "object_id" then @@ -2280,6 +2311,9 @@ redef class AMethPropdef else if pname == "to_i" then v.ret(v.new_expr("{arguments[0]}-'0'", ret.as(not null))) return true + else if pname == "code_point" then + v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) + return true end else if cname == "Byte" then if pname == "output" then @@ -2328,6 +2362,15 @@ redef class AMethPropdef else if pname == ">=" then v.ret(v.new_expr("{arguments[0]} >= {arguments[1]}", ret.as(not null))) return true + else if pname == ">>" then + v.ret(v.new_expr("{arguments[0]} >> {arguments[1]}", ret.as(not null))) + return true + else if pname == "<<" then + v.ret(v.new_expr("{arguments[0]} << {arguments[1]}", ret.as(not null))) + return true + else if pname == "&" then + v.ret(v.new_expr("{arguments[0]} & {arguments[1]}", ret.as(not null))) + return true else if pname == "to_i" then v.ret(v.new_expr("(long){arguments[0]}", ret.as(not null))) return true @@ -2349,6 +2392,9 @@ redef class AMethPropdef else if pname == "to_u32" then v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) return true + else if pname == "ascii" then + v.ret(v.new_expr("(uint32_t){arguments[0]}", ret.as(not null))) + return true end else if cname == "Bool" then if pname == "output" then @@ -2453,13 +2499,25 @@ redef class AMethPropdef else if pname == "fast_cstring" then v.ret(v.new_expr("{arguments[0]} + {arguments[1]}", ret.as(not null))) return true + else if pname == "==" then + v.ret(v.equal_test(arguments[0], arguments[1])) + return true + else if pname == "!=" then + var res = v.equal_test(arguments[0], arguments[1]) + v.ret(v.new_expr("!{res}", ret.as(not null))) + return true else if pname == "new" then v.ret(v.new_expr("(char*)nit_alloc({arguments[1]})", ret.as(not null))) return true + else if pname == "fetch_4_chars" then + v.ret(v.new_expr("(long)*((uint32_t*)({arguments[0]} + {arguments[1]}))", ret.as(not null))) + return true + else if pname == "fetch_4_hchars" then + v.ret(v.new_expr("(long)be32toh(*((uint32_t*)({arguments[0]} + {arguments[1]})))", ret.as(not null))) + return true end else if cname == "NativeArray" then - v.native_array_def(pname, ret, arguments) - return true + return v.native_array_def(pname, ret, arguments) else if cname == "Int8" then if pname == "output" then v.add("printf(\"%\"PRIi8 \"\\n\", {arguments.first});") @@ -3109,8 +3167,7 @@ end redef class AClassdef private fun compile_to_c(v: AbstractCompilerVisitor, mpropdef: MMethodDef, arguments: Array[RuntimeVariable]) do - if mpropdef == self.mfree_init then - assert mpropdef.mproperty.is_root_init + if mpropdef.mproperty.is_root_init then assert arguments.length == 1 if not mpropdef.is_intro then v.supercall(mpropdef, arguments.first.mtype.as(MClassType), arguments)