# Return the name of the C structure associated to a Nit live type
# FIXME: move to GlobalCompiler so we can check that self is a live type
fun c_name: String is abstract
- private var c_name_cache: nullable String
+ protected var c_name_cache: nullable String protected writable
end
redef class MClassType
return res
end
+ fun native_array_def(pname: String, ret_type: nullable MType, arguments: Array[RuntimeVariable])
+ do
+ var elttype = arguments.first.mtype
+ 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
+ else if pname == "[]=" then
+ self.add("{recv}[{arguments[1]}]={arguments[2]};")
+ return
+ else if pname == "copy_to" then
+ var recv1 = "((struct {arguments[1].mcasttype.c_name}*){arguments[1]})->values"
+ self.add("memcpy({recv1},{recv},{arguments[2]}*sizeof({elttype.ctype}));")
+ return
+ end
+ end
+
+ fun calloc_array(ret_type: MType, arguments: Array[RuntimeVariable])
+ do
+ self.ret(self.new_expr("NEW_{ret_type.c_name}({arguments[1]})", ret_type))
+ end
+
# Generate a polymorphic send for the method `m' and the arguments `args'
fun send(m: MMethod, args: Array[RuntimeVariable]): nullable RuntimeVariable
do
var recv = self.autobox(args.first, recvtype)
recv = self.autoadapt(recv, recvtype)
- var vararg_rank = m.msignature.vararg_rank
- if vararg_rank >= 0 then
- assert args.length >= m.msignature.arity + 1 # because of self
- var rawargs = args
- args = new Array[RuntimeVariable]
-
- args.add(rawargs.first) # recv
-
- for i in [0..vararg_rank[ do
- args.add(rawargs[i+1])
- end
-
- var vararg_lastrank = vararg_rank + rawargs.length-1-m.msignature.arity
- var vararg = new Array[RuntimeVariable]
- for i in [vararg_rank..vararg_lastrank] do
- vararg.add(rawargs[i+1])
- end
- # FIXME: its it to late to determine the vararg type, this should have been done during a previous analysis
- var elttype = m.msignature.mparameters[vararg_rank].mtype
- elttype = self.resolve_for(elttype, recv)
- args.add(self.array_instance(vararg, elttype))
-
- for i in [vararg_lastrank+1..rawargs.length-1[ do
- args.add(rawargs[i+1])
- end
- else
- args = args.to_a
- end
+ args = args.to_a
+ self.varargize(m.msignature.as(not null), args)
if args.length != m.msignature.arity + 1 then # because of self
add("printf(\"NOT YET IMPLEMENTED: Invalid arity for {m}. {args.length} arguments given.\\n\"); exit(1);")
debug("NOT YET IMPLEMENTED: Invalid arity for {m}. {args.length} arguments given.")
end
end
+ # Transform varargs, in raw arguments, into a single argument of type Array
+ # Note: this method modify the given `args`
+ # If there is no vararg, then `args` is not modified.
+ fun varargize(msignature: MSignature, args: Array[RuntimeVariable])
+ do
+ var recv = args.first
+ var vararg_rank = msignature.vararg_rank
+ if vararg_rank >= 0 then
+ assert args.length >= msignature.arity + 1 # because of self
+ var rawargs = args
+ args = new Array[RuntimeVariable]
+
+ args.add(rawargs.first) # recv
+
+ for i in [0..vararg_rank[ do
+ args.add(rawargs[i+1])
+ end
+
+ var vararg_lastrank = vararg_rank + rawargs.length-1-msignature.arity
+ var vararg = new Array[RuntimeVariable]
+ for i in [vararg_rank..vararg_lastrank] do
+ vararg.add(rawargs[i+1])
+ end
+ # FIXME: its it to late to determine the vararg type, this should have been done during a previous analysis
+ var elttype = msignature.mparameters[vararg_rank].mtype
+ elttype = self.resolve_for(elttype, recv)
+ args.add(self.array_instance(vararg, elttype))
+
+ for i in [vararg_lastrank+1..rawargs.length-1[ do
+ args.add(rawargs[i+1])
+ end
+ rawargs.clear
+ rawargs.add_all(args)
+ end
+ end
+
fun bugtype(recv: RuntimeVariable)
do
if recv.mtype.ctype != "val*" then return
var res = self.new_var(bool_type)
self.add("/* isa {mtype} on {value.inspect} */")
+ if value.mtype.ctype != "val*" then
+ if value.mtype.is_subtype(self.compiler.mainmodule, null, mtype) then
+ self.add("{res} = 1;")
+ else
+ self.add("{res} = 0;")
+ end
+ return res
+ end
if value.mcasttype isa MNullableType then
self.add("if ({value} == NULL) \{")
if mtype isa MNullableType then
return
end
else if cname == "NativeArray" then
- var elttype = arguments.first.mtype
- #assert arguments[0].is_exact
- var recv = "((struct {arguments[0].mcasttype.c_name}*){arguments[0]})->values"
- if pname == "[]" then
- v.ret(v.new_expr("{recv}[{arguments[1]}]", ret.as(not null)))
- return
- else if pname == "[]=" then
- v.add("{recv}[{arguments[1]}]={arguments[2]};")
- return
- else if pname == "copy_to" then
- #assert arguments[1].is_exact
- #assert arguments[1].mcasttype == arguments[0].mcasttype else print "copy {arguments[0].mcasttype} to {arguments[1].mcasttype} "
- #assert arguments[1].mcasttype == arguments[0].mcasttype else print "copy {arguments[0].mcasttype} to {arguments[1].mcasttype} "
- var recv1 = "((struct {arguments[1].mcasttype.c_name}*){arguments[1]})->values"
- v.add("memcpy({recv1},{recv},{arguments[2]}*sizeof({elttype.ctype}));")
- return
- end
+ v.native_array_def(pname, ret, arguments)
+ return
end
if pname == "exit" then
v.add("exit({arguments[1]});")
v.ret(v.new_expr("(char*)GC_MALLOC({arguments[1]})", ret.as(not null)))
return
else if pname == "calloc_array" then
- #var elttype = arguments.first.mtype.supertype_to(v.compiler.mainmodule,arguments.first.mtype.as(MClassType),v.get_class("ArrayCapable")).arguments.first
-
- v.ret(v.new_expr("NEW_{ret.c_name}({arguments[1]})", ret.as(not null)))
+ v.calloc_array(ret.as(not null), arguments)
return
else if pname == "object_id" then
v.ret(v.new_expr("(long){arguments.first}", ret.as(not null)))