X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/global_compiler.nit b/src/compiler/global_compiler.nit index 9a89064..ce61657 100644 --- a/src/compiler/global_compiler.nit +++ b/src/compiler/global_compiler.nit @@ -151,7 +151,7 @@ class GlobalCompiler if self.classids.has_key(mtype) then return self.classids[mtype] end - print "No classid for {mtype}" + print_error "No classid for {mtype}" abort end @@ -246,8 +246,7 @@ class GlobalCompiler var res = v.new_var(mtype) res.is_exact = true if is_native_array then - var mtype_elt = mtype.arguments.first - v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}) + length*sizeof({mtype_elt.ctype}));") + v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}) + length*sizeof(val*));") v.add("((struct {mtype.c_name}*){res})->length = length;") else v.add("{res} = nit_alloc(sizeof(struct {mtype.c_name}));") @@ -331,7 +330,7 @@ class GlobalCompilerVisitor redef fun unbox_extern(value, mtype) do if mtype isa MClassType and mtype.mclass.kind == extern_kind and - mtype.mclass.name != "NativeString" then + mtype.mclass.name != "CString" then var res = self.new_var_extern(mtype) self.add "{res} = ((struct {mtype.c_name}*){value})->value; /* unboxing {value.mtype} */" return res @@ -343,7 +342,7 @@ class GlobalCompilerVisitor redef fun box_extern(value, mtype) do if not mtype isa MClassType or mtype.mclass.kind != extern_kind or - mtype.mclass.name == "NativeString" then return value + mtype.mclass.name == "CString" then return value var valtype = value.mtype.as(MClassType) var res = self.new_var(mtype) @@ -386,30 +385,45 @@ class GlobalCompilerVisitor var recv = "((struct {arguments[0].mcasttype.c_name}*){arguments[0]})->values" if pname == "[]" then self.ret(self.new_expr("{recv}[{arguments[1]}]", ret_type.as(not null))) - return + return true else if pname == "[]=" then self.add("{recv}[{arguments[1]}]={arguments[2]};") - return + return true else if pname == "length" then self.ret(self.new_expr("((struct {arguments[0].mcasttype.c_name}*){arguments[0]})->length", ret_type.as(not null))) - return + return true else if pname == "copy_to" then var recv1 = "((struct {arguments[1].mcasttype.c_name}*){arguments[1]})->values" self.add("memmove({recv1},{recv},{arguments[2]}*sizeof({elttype.ctype}));") - return - end + return true + else if pname == "memmove" then + # fun memmove(start: Int, length: Int, dest: NativeArray[E], dest_start: Int) is intern do + var recv1 = "((struct {arguments[3].mcasttype.c_name}*){arguments[3]})->values" + self.add("memmove({recv1}+{arguments[4]}, {recv}+{arguments[1]}, {arguments[2]}*sizeof({elttype.ctype}));") + return true + end + return false end - redef fun native_array_instance(elttype: MType, length: RuntimeVariable): RuntimeVariable + redef fun native_array_instance(elttype, length) do var ret_type = mmodule.native_array_type(elttype) ret_type = anchor(ret_type).as(MClassType) - return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type) + length = autobox(length, compiler.mainmodule.int_type) + return self.new_expr("NEW_{ret_type.c_name}((int){length})", ret_type) + end + + redef fun native_array_get(nat, i) + do + var recv = "((struct {nat.mcasttype.c_name}*){nat})->values" + var ret_type = nat.mcasttype.as(MClassType).arguments.first + return self.new_expr("{recv}[{i}]", ret_type) end - redef fun calloc_array(ret_type, arguments) + redef fun native_array_set(nat, i, val) do - self.ret(self.new_expr("NEW_{ret_type.c_name}({arguments[1]})", ret_type)) + var recv = "((struct {nat.mcasttype.c_name}*){nat})->values" + self.add("{recv}[{i}]={val};") end redef fun send(m, args) @@ -429,6 +443,10 @@ class GlobalCompilerVisitor if args.first.mtype.is_c_primitive then var mclasstype = args.first.mtype.as(MClassType) if not self.compiler.runtime_type_analysis.live_types.has(mclasstype) then + self.add("/* skip, dead class {mclasstype} */") + return res + end + if not mclasstype.has_mproperty(self.compiler.mainmodule, m) then self.add("/* skip, no method {m} */") return res end @@ -505,7 +523,7 @@ class GlobalCompilerVisitor fun check_valid_reciever(recvtype: MClassType) do if self.compiler.runtime_type_analysis.live_types.has(recvtype) or recvtype.mclass.name == "Object" then return - print "{recvtype} is not a live type" + print_error "{recvtype} is not a live type" abort end @@ -515,11 +533,6 @@ class GlobalCompilerVisitor private fun get_recvtype(m: MMethodDef, recvtype: MClassType, args: Array[RuntimeVariable]): MClassType do check_valid_reciever(recvtype) - #debug("call {m} on {recvtype} on {args.first}:{args.first.mtype}") - if m.mproperty.is_toplevel then - # Do not customize top-level methods - recvtype = m.mclassdef.bound_mtype - end return recvtype end @@ -597,8 +610,9 @@ class GlobalCompilerVisitor do var recv = args.first for i in [0..m.msignature.arity[ do - var t = m.msignature.mparameters[i].mtype - if i == m.msignature.vararg_rank then + var mp = m.msignature.mparameters[i] + var t = mp.mtype + if mp.is_vararg then t = args[i+1].mtype end t = self.resolve_for(t, recv) @@ -610,8 +624,9 @@ class GlobalCompilerVisitor do var recv = args.first for i in [0..m.msignature.arity[ do - var t = m.msignature.mparameters[i].mtype - if i == m.msignature.vararg_rank then + var mp = m.msignature.mparameters[i] + var t = mp.mtype + if mp.is_vararg then t = args[i+1].mtype end t = self.resolve_for(t, recv) @@ -911,7 +926,7 @@ class GlobalCompilerVisitor end end -# A runtime function customized on a specific monomrph receiver type +# A runtime function customized on a specific monomorph receiver type private class CustomizedRuntimeFunction super AbstractRuntimeFunction @@ -956,73 +971,51 @@ private class CustomizedRuntimeFunction end end - # compile the code customized for the reciever - redef fun compile_to_c(compiler) - do - var recv = self.recv - var mmethoddef = self.mmethoddef - if not recv.is_subtype(compiler.mainmodule, null, mmethoddef.mclassdef.bound_mtype) then - print("problem: why do we compile {self} for {recv}?") - abort - end - - var v = compiler.new_visitor - var selfvar = new RuntimeVariable("self", recv, recv) - if compiler.runtime_type_analysis.live_types.has(recv) then - selfvar.is_exact = true - end - var arguments = new Array[RuntimeVariable] - var frame = new StaticFrame(v, mmethoddef, recv, arguments) - v.frame = frame - - var sig = new FlatBuffer - var comment = new FlatBuffer - var ret = mmethoddef.msignature.return_mtype - if ret != null then - ret = v.resolve_for(ret, selfvar) - sig.append("{ret.ctype} ") - else - sig.append("void ") - end - sig.append(self.c_name) - sig.append("({recv.ctype} {selfvar}") - comment.append("(self: {recv}") - arguments.add(selfvar) - for i in [0..mmethoddef.msignature.arity[ do - var mtype = mmethoddef.msignature.mparameters[i].mtype - if i == mmethoddef.msignature.vararg_rank then - mtype = v.mmodule.array_type(mtype) - end - mtype = v.resolve_for(mtype, selfvar) - comment.append(", {mtype}") - sig.append(", {mtype.ctype} p{i}") - var argvar = new RuntimeVariable("p{i}", mtype, mtype) - arguments.add(argvar) - end - sig.append(")") - comment.append(")") - if ret != null then - comment.append(": {ret}") - end - compiler.header.add_decl("{sig};") - - v.add_decl("/* method {self} for {comment} */") - v.add_decl("{sig} \{") - #v.add("printf(\"method {self} for {comment}\\n\");") - if ret != null then - frame.returnvar = v.new_var(ret) - end - frame.returnlabel = v.get_name("RET_LABEL") + redef fun recv_mtype + do + return recv + end - mmethoddef.compile_inside_to_c(v, arguments) + redef var return_mtype - v.add("{frame.returnlabel.as(not null)}:;") - if ret != null then - v.add("return {frame.returnvar.as(not null)};") + redef fun resolve_receiver(v) + do + var selfvar = new RuntimeVariable("self", recv, recv) + if v.compiler.runtime_type_analysis.live_types.has(recv) then + selfvar.is_exact = true end - v.add("\}") - if not self.c_name.has_substring("VIRTUAL", 0) then compiler.names[self.c_name] = "{mmethoddef.mclassdef.mmodule.name}::{mmethoddef.mclassdef.mclass.name}::{mmethoddef.mproperty.name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})" - end + return selfvar + end + + redef fun resolve_return_mtype(v) + do + var selfvar = v.frame.selfvar + if has_return then + var ret = msignature.return_mtype.as(not null) + return_mtype = v.resolve_for(ret, selfvar) + end + end + redef fun resolve_ith_parameter(v, i) + do + var selfvar = v.frame.selfvar + var mp = msignature.mparameters[i] + var mtype = mp.mtype + if mp.is_vararg then + mtype = v.mmodule.array_type(mtype) + end + mtype = v.resolve_for(mtype, selfvar) + return new RuntimeVariable("p{i}", mtype, mtype) + end + + redef fun declare_signature(v, sig) + do + v.compiler.header.add_decl("{sig};") + end + + redef fun end_compile_to_c(v) + do + if not self.c_name.has_substring("VIRTUAL", 0) then v.compiler.names[self.c_name] = "{mmethoddef.mclassdef.mmodule.name}::{mmethoddef.mclassdef.mclass.name}::{mmethoddef.mproperty.name} ({mmethoddef.location.file.filename}:{mmethoddef.location.line_start})" + end redef fun call(v: VISITOR, arguments: Array[RuntimeVariable]): nullable RuntimeVariable do