X-Git-Url: http://nitlanguage.org diff --git a/src/compiler/global_compiler.nit b/src/compiler/global_compiler.nit index 6b67611..7b07847 100644 --- a/src/compiler/global_compiler.nit +++ b/src/compiler/global_compiler.nit @@ -86,7 +86,7 @@ class GlobalCompiler self.header = new CodeWriter(file) self.live_primitive_types = new Array[MClassType] for t in runtime_type_analysis.live_types do - if t.ctype != "val*" or t.mclass.name == "Pointer" then + if t.is_c_primitive or t.mclass.name == "Pointer" then self.live_primitive_types.add(t) end end @@ -109,7 +109,7 @@ class GlobalCompiler # Init instance code (allocate and init-arguments) for t in runtime_type_analysis.live_types do - if t.ctype == "val*" then + if not t.is_c_primitive then compiler.generate_init_instance(t) if t.mclass.kind == extern_kind then compiler.generate_box_instance(t) @@ -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 @@ -228,7 +228,7 @@ class GlobalCompiler fun generate_init_instance(mtype: MClassType) do assert self.runtime_type_analysis.live_types.has(mtype) - assert mtype.ctype == "val*" + assert not mtype.is_c_primitive var v = self.new_visitor var is_native_array = mtype.mclass.name == "NativeArray" @@ -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}));") @@ -303,11 +302,11 @@ class GlobalCompilerVisitor do if value.mtype == mtype then return value - else if value.mtype.ctype == "val*" and mtype.ctype == "val*" then + else if not value.mtype.is_c_primitive and not mtype.is_c_primitive then return value - else if value.mtype.ctype == "val*" then + else if not value.mtype.is_c_primitive then return self.new_expr("((struct {mtype.c_name}*){value})->value; /* autounbox from {value.mtype} to {mtype} */", mtype) - else if mtype.ctype == "val*" then + else if not mtype.is_c_primitive then var valtype = value.mtype.as(MClassType) var res = self.new_var(mtype) if not compiler.runtime_type_analysis.live_types.has(valtype) then @@ -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 do var ret_type = mmodule.native_array_type(elttype) ret_type = anchor(ret_type).as(MClassType) + length = autobox(length, compiler.mainmodule.int_type) return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type) end - redef fun calloc_array(ret_type, arguments) + redef fun native_array_get(nat, i) do - self.ret(self.new_expr("NEW_{ret_type.c_name}({arguments[1]})", ret_type)) + 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 native_array_set(nat, i, val) + do + var recv = "((struct {nat.mcasttype.c_name}*){nat})->values" + self.add("{recv}[{i}]={val};") end redef fun send(m, args) @@ -426,9 +440,13 @@ class GlobalCompilerVisitor end self.add("/* send {m} on {args.first.inspect} */") - if args.first.mtype.ctype != "val*" then + 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 @@ -477,7 +495,7 @@ class GlobalCompilerVisitor var defaultpropdef: nullable MMethodDef = null for t in types do var propdef = m.lookup_first_definition(self.compiler.mainmodule, t) - if propdef.mclassdef.mclass.name == "Object" and t.ctype == "val*" then + if propdef.mclassdef.mclass.name == "Object" and not t.is_c_primitive then defaultpropdef = propdef continue 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 @@ -552,7 +565,7 @@ class GlobalCompilerVisitor end self.add("/* super {m} on {args.first.inspect} */") - if args.first.mtype.ctype != "val*" then + 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, no method {m} */") @@ -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) @@ -628,7 +643,7 @@ class GlobalCompilerVisitor fun bugtype(recv: RuntimeVariable) do - if recv.mtype.ctype != "val*" then return + if recv.mtype.is_c_primitive then return self.add("PRINT_ERROR(\"BTD BUG: Dynamic type is %s, static type is %s\\n\", class_names[{recv}->classid], \"{recv.mcasttype}\");") self.add("fatal_exit(1);") end @@ -659,7 +674,7 @@ class GlobalCompilerVisitor ta = self.resolve_for(ta, recv2) var attr = self.new_expr("((struct {t.c_name}*){recv})->{a.intro.c_name}", ta) if not ta isa MNullableType then - if ta.ctype == "val*" then + if not ta.is_c_primitive then self.add("{res} = ({attr} != NULL);") else self.add("{res} = 1; /*NOTYET isset on primitive attributes*/") @@ -705,7 +720,7 @@ class GlobalCompilerVisitor ta = self.resolve_for(ta, recv2) var res2 = self.new_expr("((struct {t.c_name}*){recv})->{a.intro.c_name}", ta) if not ta isa MNullableType and not self.compiler.modelbuilder.toolcontext.opt_no_check_attr_isset.value then - if ta.ctype == "val*" then + if not ta.is_c_primitive then self.add("if ({res2} == NULL) \{") self.add_abort("Uninitialized attribute {a.name}") self.add("\}") @@ -781,7 +796,7 @@ class GlobalCompilerVisitor var res = self.new_var(bool_type) self.add("/* isa {mtype} on {value.inspect} */") - if value.mtype.ctype != "val*" then + if value.mtype.is_c_primitive then if value.mtype.is_subtype(self.compiler.mainmodule, null, mtype) then self.add("{res} = 1;") else @@ -816,14 +831,14 @@ class GlobalCompilerVisitor redef fun is_same_type_test(value1, value2) do var res = self.new_var(bool_type) - if value2.mtype.ctype == "val*" then - if value1.mtype.ctype == "val*" then + if not value2.mtype.is_c_primitive then + if not value1.mtype.is_c_primitive then self.add "{res} = {value1}->classid == {value2}->classid;" else self.add "{res} = {self.compiler.classid(value1.mtype.as(MClassType))} == {value2}->classid;" end else - if value1.mtype.ctype == "val*" then + if not value1.mtype.is_c_primitive then self.add "{res} = {value1}->classid == {self.compiler.classid(value2.mtype.as(MClassType))};" else if value1.mcasttype == value2.mcasttype then self.add "{res} = 1;" @@ -838,7 +853,7 @@ class GlobalCompilerVisitor do var res = self.get_name("var_class_name") self.add_decl("const char* {res};") - if value.mtype.ctype == "val*" then + if not value.mtype.is_c_primitive then self.add "{res} = class_names[{value}->classid];" else self.add "{res} = class_names[{self.compiler.classid(value.mtype.as(MClassType))}];" @@ -849,15 +864,15 @@ class GlobalCompilerVisitor redef fun equal_test(value1, value2) do var res = self.new_var(bool_type) - if value2.mtype.ctype != "val*" and value1.mtype.ctype == "val*" then + if value2.mtype.is_c_primitive and not value1.mtype.is_c_primitive then var tmp = value1 value1 = value2 value2 = tmp end - if value1.mtype.ctype != "val*" then + if value1.mtype.is_c_primitive then if value2.mtype == value1.mtype then self.add("{res} = {value1} == {value2};") - else if value2.mtype.ctype != "val*" then + else if value2.mtype.is_c_primitive then self.add("{res} = 0; /* incompatible types {value1.mtype} vs. {value2.mtype}*/") else var mtype1 = value1.mtype.as(MClassType) @@ -989,8 +1004,9 @@ private class CustomizedRuntimeFunction 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 + var mp = mmethoddef.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)