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
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
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)
var recv1 = "((struct {arguments[1].mcasttype.c_name}*){arguments[1]})->values"
self.add("memmove({recv1},{recv},{arguments[2]}*sizeof({elttype.ctype}));")
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)
length = autobox(length, compiler.mainmodule.int_type)
- return self.new_expr("NEW_{ret_type.c_name}({length})", ret_type)
+ return self.new_expr("NEW_{ret_type.c_name}((int){length})", ret_type)
end
redef fun native_array_get(nat, i)
self.add("{recv}[{i}]={val};")
end
- redef fun calloc_array(ret_type, arguments)
- do
- self.ret(self.new_expr("NEW_{ret_type.c_name}({arguments[1]})", ret_type))
- end
-
redef fun send(m, args)
do
var types = self.collect_types(args.first)
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
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
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
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 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)
- 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