self.toolcontext.info("*** START INTERPRETING ***", 1)
var interpreter = new NaiveInterpreter(self, mainmodule, arguments)
- var mainclasses = model.get_mclasses_by_name("Sys")
- if mainclasses == null then return
- assert mainclasses.length == 1
- var mainclass = mainclasses.first
- var props = model.get_mproperties_by_name("main")
- assert props.length == 1
- var methods = props.first.lookup_definitions(mainmodule, mainclass.mclass_type)
- assert methods.length == 1 else print methods.join(", ")
- var mainobj = new Instance(mainclass.mclass_type)
+ var sys_type = mainmodule.sys_type
+ if sys_type == null then return # no class Sys
+ var mainobj = new Instance(sys_type)
interpreter.mainobj = mainobj
interpreter.init_instance(mainobj)
- var initprop = try_get_mproperty_by_name2(nmodules.first, mainmodule, mainclass.mclass_type, "init")
+ var initprop = mainmodule.try_get_primitive_method("init", sys_type)
if initprop != null then
- assert initprop isa MMethod
interpreter.send(initprop, [mainobj])
end
interpreter.check_init_instance(mainobj)
- interpreter.send(interpreter.get_property("main", mainobj), [mainobj])
+ var mainprop = mainmodule.try_get_primitive_method("main", sys_type)
+ if mainprop != null then
+ interpreter.send(mainprop, [mainobj])
+ end
var time1 = get_time
self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
self.modelbuilder = modelbuilder
self.mainmodule = mainmodule
self.arguments = arguments
- self.true_instance = new PrimitiveInstance[Bool](get_class("Bool").mclass_type, true)
- self.false_instance = new PrimitiveInstance[Bool](get_class("Bool").mclass_type, false)
+ self.true_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, true)
+ self.false_instance = new PrimitiveInstance[Bool](mainmodule.bool_type, false)
self.null_instance = new Instance(mainmodule.model.null_type)
end
- # Force to get the primitive class named `name' or abort
- fun get_class(name: String): MClass
- do
- var cla = mainmodule.model.get_mclasses_by_name(name)
- if cla == null then
- if name == "Bool" then
- var c = new MClass(mainmodule, name, 0, enum_kind, public_visibility)
- var cladef = new MClassDef(mainmodule, c.mclass_type, new Location(null, 0,0,0,0), new Array[String])
- return c
- end
- fatal("Fatal Error: no primitive class {name}")
- abort
- end
- assert cla.length == 1 else print cla.join(", ")
- return cla.first
- end
-
- # Force to get the primitive property named `name' in the instance `recv' or abort
- fun get_property(name: String, recv: Instance): MMethod
- do
- var props = self.mainmodule.model.get_mproperties_by_name(name)
- if props == null then
- fatal("Fatal Error: no primitive property {name} on {recv}")
- abort
- end
- var mtype = recv.mtype
- var res: nullable MMethod = null
- for mprop in props do
- assert mprop isa MMethod
- if not mtype.has_mproperty(self.mainmodule, mprop) then continue
- if res == null then
- res = mprop
- else
- fatal("Fatal Error: ambigous property name '{name}'; conflict between {mprop.full_name} and {res.full_name}")
- abort
- end
- end
- if res == null then
- fatal("Fatal Error: no primitive property {name} on {recv}")
- abort
- end
- return res
- end
-
# Subtype test in the context of the mainmodule
fun is_subtype(sub, sup: MType): Bool
do
# Return the integer instance associated with `val'.
fun int_instance(val: Int): Instance
do
- var ic = get_class("Int")
+ var ic = self.mainmodule.get_primitive_class("Int")
return new PrimitiveInstance[Int](ic.mclass_type, val)
end
# Return the char instance associated with `val'.
fun char_instance(val: Char): Instance
do
- var ic = get_class("Char")
+ var ic = self.mainmodule.get_primitive_class("Char")
return new PrimitiveInstance[Char](ic.mclass_type, val)
end
# Return the float instance associated with `val'.
fun float_instance(val: Float): Instance
do
- var ic = get_class("Float")
+ var ic = self.mainmodule.get_primitive_class("Float")
return new PrimitiveInstance[Float](ic.mclass_type, val)
end
fun array_instance(values: Array[Instance], elttype: MType): Instance
do
assert not elttype.need_anchor
- var nat = new PrimitiveInstance[Array[Instance]](self.get_class("NativeArray").get_mtype([elttype]), values)
- var mtype = self.get_class("Array").get_mtype([elttype])
+ var nat = new PrimitiveInstance[Array[Instance]](self.mainmodule.get_primitive_class("NativeArray").get_mtype([elttype]), values)
+ var mtype = self.mainmodule.get_primitive_class("Array").get_mtype([elttype])
var res = new Instance(mtype)
self.init_instance(res)
- self.send(self.get_property("with_native", res), [res, nat, self.int_instance(values.length)])
+ self.send(self.mainmodule.force_get_primitive_method("with_native", mtype), [res, nat, self.int_instance(values.length)])
self.check_init_instance(res)
return res
end
fun native_string_instance(txt: String): Instance
do
var val = new Buffer.from(txt)
- var ic = get_class("NativeString")
+ val.add('\0')
+ var ic = self.mainmodule.get_primitive_class("NativeString")
return new PrimitiveInstance[Buffer](ic.mclass_type, val)
end
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 = mpropdef.msignature.parameter_mtypes[vararg_rank].anchor_to(self.mainmodule, args.first.mtype.as(MClassType))
+ var elttype = mpropdef.msignature.mparameters[vararg_rank].mtype.anchor_to(self.mainmodule, args.first.mtype.as(MClassType))
args.add(self.array_instance(vararg, elttype))
for i in [vararg_lastrank+1..rawargs.length-1[ do
else if cname == "NativeString" then
var recvval = args.first.val.as(Buffer)
if pname == "[]" then
- return v.char_instance(recvval[args[1].to_i])
+ var arg1 = args[1].to_i
+ if arg1 >= recvval.length or arg1 < 0 then
+ debug("Illegal access on {recvval} for element {arg1}/{recvval.length}")
+ end
+ return v.char_instance(recvval[arg1])
else if pname == "[]=" then
- recvval[args[1].to_i] = args[2].val.as(Char)
+ var arg1 = args[1].to_i
+ if arg1 >= recvval.length or arg1 < 0 then
+ debug("Illegal access on {recvval} for element {arg1}/{recvval.length}")
+ end
+ recvval[arg1] = args[2].val.as(Char)
return null
else if pname == "copy_to" then
# sig= copy_to(dest: NativeString, length: Int, from: Int, to: Int)
- recvval.copy(args[3].to_i, args[2].to_i, args[1].val.as(Buffer), args[4].to_i)
+ var destval = args[1].val.as(Buffer)
+ var lenval = args[2].to_i
+ var fromval = args[3].to_i
+ var toval = args[4].to_i
+ if fromval < 0 then
+ debug("Illegal access on {recvval} for element {fromval}/{recvval.length}")
+ end
+ if fromval + lenval >= recvval.length then
+ debug("Illegal access on {recvval} for element {fromval}+{lenval}/{recvval.length}")
+ end
+ if toval < 0 then
+ debug("Illegal access on {destval} for element {toval}/{destval.length}")
+ end
+ if toval + lenval >= destval.length then
+ debug("Illegal access on {destval} for element {toval}+{lenval}/{destval.length}")
+ end
+ recvval.copy(fromval, lenval, destval, toval)
return null
else if pname == "atoi" then
return v.int_instance(recvval.to_i)
else if cname == "NativeArray" then
var recvval = args.first.val.as(Array[Instance])
if pname == "[]" then
- if args[1].to_i >= recvval.length then
+ if args[1].to_i >= recvval.length or args[1].to_i < 0 then
debug("Illegal access on {recvval} for element {args[1].to_i}/{recvval.length}")
end
return recvval[args[1].to_i]
end
else if pname == "calloc_array" then
var recvtype = args.first.mtype.as(MClassType)
- var mtype: MType = recvtype.supertype_to(v.mainmodule, recvtype, v.get_class("ArrayCapable"))
+ var mtype: MType = recvtype.supertype_to(v.mainmodule, recvtype, v.mainmodule.get_primitive_class("ArrayCapable"))
mtype = mtype.as(MGenericType).arguments.first
var val = new Array[Instance].filled_with(v.null_instance, args[1].to_i)
- return new PrimitiveInstance[Array[Instance]](v.get_class("NativeArray").get_mtype([mtype]), val)
+ return new PrimitiveInstance[Array[Instance]](v.mainmodule.get_primitive_class("NativeArray").get_mtype([mtype]), val)
end
fatal(v, "Unimplemented intern {mpropdef}")
abort
do
var pname = mpropdef.mproperty.name
var cname = mpropdef.mclassdef.mclass.name
- if cname == "NativeFile" then
+ if cname == "Int" then
+ var recvval = args.first.val.as(Int)
+ if pname == "rand" then
+ var res = recvval.rand
+ return v.int_instance(res)
+ end
+ else if cname == "NativeFile" then
var recvval = args.first.val
if pname == "io_write" then
var a1 = args[1].val.as(Buffer)
recvval.to_s.mkdir
return null
else if pname == "get_environ" then
- var txt = args.first.val.as(Buffer).to_s.to_symbol.environ
+ var txt = recvval.to_s.environ
return v.native_string_instance(txt)
+ else if pname == "system" then
+ var res = sys.system(recvval.to_s)
+ return v.int_instance(res)
end
else if pname == "native_argc" then
return v.int_instance(v.arguments.length)
do
var col = v.expr(self.n_expr)
#self.debug("col {col}")
- var iter = v.send(v.get_property("iterator", col), [col]).as(not null)
+ var iter = v.send(v.mainmodule.force_get_primitive_method("iterator", col.mtype), [col]).as(not null)
#self.debug("iter {iter}")
loop
- var isok = v.send(v.get_property("is_ok", iter), [iter]).as(not null)
+ var isok = v.send(v.mainmodule.force_get_primitive_method("is_ok", iter.mtype), [iter]).as(not null)
if not isok.is_true then return
- var item = v.send(v.get_property("item", iter), [iter]).as(not null)
+ var item = v.send(v.mainmodule.force_get_primitive_method("item", iter.mtype), [iter]).as(not null)
#self.debug("item {item}")
v.frame.map[self.variables.first] = item
v.stmt(self.n_block)
if v.is_break(self.escapemark) then return
v.is_continue(self.escapemark) # Clear the break
if v.is_escaping then return
- v.send(v.get_property("next", iter), [iter])
+ v.send(v.mainmodule.force_get_primitive_method("next", iter.mtype), [iter])
end
end
end
do
var txt = self.value.as(not null)
var nat = v.native_string_instance(txt)
- var res = new Instance(v.get_class("String").mclass_type)
+ var res = new Instance(v.mainmodule.get_primitive_class("String").mclass_type)
v.init_instance(res)
- v.send(v.get_property("from_cstring", res), [res, nat])
+ v.send(v.mainmodule.force_get_primitive_method("from_cstring", res.mtype), [res, nat])
v.check_init_instance(res)
return res
end
for nexpr in n_exprs do
array.add(v.expr(nexpr))
end
- var i = v.array_instance(array, v.get_class("Object").mclass_type)
- var res = v.send(v.get_property("to_s", i), [i])
+ var i = v.array_instance(array, v.mainmodule.get_primitive_class("Object").mclass_type)
+ var res = v.send(v.mainmodule.force_get_primitive_method("to_s", i.mtype), [i])
assert res != null
return res
end
var mtype = v.unanchor_type(self.mtype.as(not null))
var res = new Instance(mtype)
v.init_instance(res)
- v.send(v.get_property("init", res), [res, e1, e2])
+ v.send(v.mainmodule.force_get_primitive_method("init", mtype), [res, e1, e2])
v.check_init_instance(res)
return res
end
var mtype = v.unanchor_type(self.mtype.as(not null))
var res = new Instance(mtype)
v.init_instance(res)
- v.send(v.get_property("without_last", res), [res, e1, e2])
+ v.send(v.mainmodule.force_get_primitive_method("without_last", mtype), [res, e1, e2])
v.check_init_instance(res)
return res
end