redef class INative
redef fun dump_intern(icd)
do
- if exprs.is_empty then
- return "NATIVE \"{code}\""
- else
- return "NATIVE \"{code}\"({icd.register_all(exprs)})"
- end
+ return "NATIVE \"{method.full_name}\"({icd.register_all(exprs)})"
end
end
redef fun compile_to_c(v)
do
v.add_location(location)
- var w = new_result(v)
- if exprs.is_empty then
- w.add(code)
+ if method.is_intern then
+ compile_intern_method_to_c(v)
else
- var i = 0
- var c = code.split_with("@@@")
- for s in c do
- w.add(s)
- if i < exprs.length and i < c.length-1 then
- w.add(v.register(exprs[i]))
- end
- i += 1
+ compile_extern_method_to_c(v)
+ end
+ end
+
+ fun compile_extern_method_to_c(v: I2CCompilerVisitor)
+ do
+ var ename = method.extern_name.as(not null)#"{method.module.name}_{method.local_class.name}_{method.local_class.name}_{method.name}_{method.signature.arity}"
+ var sig = method.signature
+ assert exprs.length == sig.arity + 1
+
+ var regs = v.registers(exprs)
+
+ var args = new Array[String]
+ args.add(sig.recv.unboxtype(regs[0]))
+ for i in [0..sig.arity[ do
+ args.add(sig[i].unboxtype(regs[i+1]))
+ end
+ var s = "{ename}({args.join(", ")})"
+
+ if need_result then s = sig.return_type.boxtype(s)
+ var w = new_result(v)
+ w.add(s)
+ end
+
+ fun compile_intern_method_to_c(v: I2CCompilerVisitor)
+ do
+ var sig = method.signature
+ assert exprs.length == sig.arity + 1
+ var c = method.local_class.name
+ var n = method.name
+ var regs = v.registers(exprs)
+ var s: nullable String = null
+ if c == once "Int".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = regs[0]
+ else if n == once "unary -".to_symbol then
+ s = "TAG_Int(-UNTAG_Int({regs[0]}))"
+ else if n == once "output".to_symbol then
+ s = "printf(\"%ld\\n\", UNTAG_Int({regs[0]}));"
+ else if n == once "ascii".to_symbol then
+ s = "TAG_Char(UNTAG_Int({regs[0]}))"
+ else if n == once "succ".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})+1)"
+ else if n == once "prec".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})-1)"
+ else if n == once "to_f".to_symbol then
+ s = "BOX_Float((float)UNTAG_Int({regs[0]}))"
+ else if n == once "+".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})+UNTAG_Int({regs[1]}))"
+ else if n == once "-".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})-UNTAG_Int({regs[1]}))"
+ else if n == once "*".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})*UNTAG_Int({regs[1]}))"
+ else if n == once "/".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})/UNTAG_Int({regs[1]}))"
+ else if n == once "%".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})%UNTAG_Int({regs[1]}))"
+ else if n == once "<".to_symbol then
+ s = "TAG_Bool(UNTAG_Int({regs[0]})<UNTAG_Int({regs[1]}))"
+ else if n == once ">".to_symbol then
+ s = "TAG_Bool(UNTAG_Int({regs[0]})>UNTAG_Int({regs[1]}))"
+ else if n == once "<=".to_symbol then
+ s = "TAG_Bool(UNTAG_Int({regs[0]})<=UNTAG_Int({regs[1]}))"
+ else if n == once ">=".to_symbol then
+ s = "TAG_Bool(UNTAG_Int({regs[0]})>=UNTAG_Int({regs[1]}))"
+ else if n == once "lshift".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})<<UNTAG_Int({regs[1]}))"
+ else if n == once "rshift".to_symbol then
+ s = "TAG_Int(UNTAG_Int({regs[0]})>>UNTAG_Int({regs[1]}))"
+ else if n == once "==".to_symbol then
+ s = "TAG_Bool(({regs[0]})==({regs[1]}))"
+ else if n == once "!=".to_symbol then
+ s = "TAG_Bool(({regs[0]})!=({regs[1]}))"
+ end
+ else if c == once "Float".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = "TAG_Int((bigint)UNBOX_Float({regs[0]}))"
+ else if n == once "unary -".to_symbol then
+ s = "BOX_Float(-UNBOX_Float({regs[0]}))"
+ else if n == once "output".to_symbol then
+ s = "printf(\"%f\\n\", UNBOX_Float({regs[0]}));"
+ else if n == once "to_i".to_symbol then
+ s = "TAG_Int((bigint)UNBOX_Float({regs[0]}))"
+ else if n == once "+".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})+UNBOX_Float({regs[1]}))"
+ else if n == once "-".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})-UNBOX_Float({regs[1]}))"
+ else if n == once "*".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})*UNBOX_Float({regs[1]}))"
+ else if n == once "/".to_symbol then
+ s = "BOX_Float(UNBOX_Float({regs[0]})/UNBOX_Float({regs[1]}))"
+ else if n == once "<".to_symbol then
+ s = "TAG_Bool(UNBOX_Float({regs[0]})<UNBOX_Float({regs[1]}))"
+ else if n == once ">".to_symbol then
+ s = "TAG_Bool(UNBOX_Float({regs[0]})>UNBOX_Float({regs[1]}))"
+ else if n == once "<=".to_symbol then
+ s = "TAG_Bool(UNBOX_Float({regs[0]})<=UNBOX_Float({regs[1]}))"
+ else if n == once ">=".to_symbol then
+ s = "TAG_Bool(UNBOX_Float({regs[0]})>=UNBOX_Float({regs[1]}))"
+ end
+ else if c == once "Char".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = "TAG_Int(UNTAG_Char({regs[0]}))"
+ else if n == once "unary -".to_symbol then
+ s = "TAG_Char(-UNTAG_Char({regs[0]}))"
+ else if n == once "output".to_symbol then
+ s = "printf(\"%c\", (unsigned char)UNTAG_Char({regs[0]}));"
+ else if n == once "ascii".to_symbol then
+ s = "TAG_Int((unsigned char)UNTAG_Char({regs[0]}))"
+ else if n == once "succ".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})+1)"
+ else if n == once "prec".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})-1)"
+ else if n == once "to_i".to_symbol then
+ s = "TAG_Int(UNTAG_Char({regs[0]})-'0')"
+ else if n == once "+".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})+UNTAG_Char({regs[1]}))"
+ else if n == once "-".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})-UNTAG_Char({regs[1]}))"
+ else if n == once "*".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})*UNTAG_Char({regs[1]}))"
+ else if n == once "/".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})/UNTAG_Char({regs[1]}))"
+ else if n == once "%".to_symbol then
+ s = "TAG_Char(UNTAG_Char({regs[0]})%UNTAG_Char({regs[1]}))"
+ else if n == once "<".to_symbol then
+ s = "TAG_Bool(UNTAG_Char({regs[0]})<UNTAG_Char({regs[1]}))"
+ else if n == once ">".to_symbol then
+ s = "TAG_Bool(UNTAG_Char({regs[0]})>UNTAG_Char({regs[1]}))"
+ else if n == once "<=".to_symbol then
+ s = "TAG_Bool(UNTAG_Char({regs[0]})<=UNTAG_Char({regs[1]}))"
+ else if n == once ">=".to_symbol then
+ s = "TAG_Bool(UNTAG_Char({regs[0]})>=UNTAG_Char({regs[1]}))"
+ else if n == once "==".to_symbol then
+ s = "TAG_Bool(({regs[0]})==({regs[1]}))"
+ else if n == once "!=".to_symbol then
+ s = "TAG_Bool(({regs[0]})!=({regs[1]}))"
+ end
+ else if c == once "Bool".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = "TAG_Int(UNTAG_Bool({regs[0]}))"
+ else if n == once "unary -".to_symbol then
+ s = "TAG_Bool(-UNTAG_Bool({regs[0]}))"
+ else if n == once "output".to_symbol then
+ s = "(void)printf(UNTAG_Bool({regs[0]})?\"true\\n\":\"false\\n\");"
+ else if n == once "ascii".to_symbol then
+ s = "TAG_Bool(UNTAG_Bool({regs[0]}))"
+ else if n == once "to_i".to_symbol then
+ s = "TAG_Int(UNTAG_Bool({regs[0]}))"
+ else if n == once "==".to_symbol then
+ s = "TAG_Bool(({regs[0]})==({regs[1]}))"
+ else if n == once "!=".to_symbol then
+ s = "TAG_Bool(({regs[0]})!=({regs[1]}))"
end
+ else if c == once "NativeArray".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = "TAG_Int(((Nit_NativeArray){regs[0]})->object_id)"
+ else if n == once "[]".to_symbol then
+ s = "((Nit_NativeArray){regs[0]})->val[UNTAG_Int({regs[1]})]"
+ else if n == once "[]=".to_symbol then
+ s = "((Nit_NativeArray){regs[0]})->val[UNTAG_Int({regs[1]})]={regs[2]}"
+ else if n == once "copy_to".to_symbol then
+ s = "(void)memcpy(((Nit_NativeArray ){regs[1]})->val, ((Nit_NativeArray){regs[0]})->val, UNTAG_Int({regs[2]})*sizeof(val_t))"
+ end
+ else if c == once "NativeString".to_symbol then
+ if n == once "object_id".to_symbol then
+ s = "TAG_Int(UNBOX_NativeString({regs[0]}))"
+ else if n == once "atoi".to_symbol then
+ s = "TAG_Int(atoi(UNBOX_NativeString({regs[0]})))"
+ else if n == once "[]".to_symbol then
+ s = "TAG_Char(UNBOX_NativeString({regs[0]})[UNTAG_Int({regs[1]})])"
+ else if n == once "[]=".to_symbol then
+ s = "UNBOX_NativeString({regs[0]})[UNTAG_Int({regs[1]})]=UNTAG_Char({regs[2]});"
+ else if n == once "copy_to".to_symbol then
+ s = "(void)memcpy(UNBOX_NativeString({regs[1]})+UNTAG_Int({regs[4]}), UNBOX_NativeString({regs[0]})+UNTAG_Int({regs[3]}), UNTAG_Int({regs[2]}));"
+ end
+ else if n == once "object_id".to_symbol then
+ s = "TAG_Int((bigint)((obj_t){regs[0]})[1].object_id)"
+ else if n == once "sys".to_symbol then
+ s = "(G_sys)"
+ else if n == once "is_same_type".to_symbol then
+ s = "TAG_Bool((VAL2VFT({regs[0]})==VAL2VFT({regs[1]})))"
+ else if n == once "exit".to_symbol then
+ s = "exit(UNTAG_Int({regs[1]}));"
+ else if n == once "calloc_array".to_symbol then
+ s = "NEW_NativeArray(UNTAG_Int({regs[1]}), sizeof(val_t))"
+ else if n == once "calloc_string".to_symbol then
+ s = "BOX_NativeString((char*)raw_alloc((UNTAG_Int({regs[1]}) * sizeof(char))))"
+ end
+ if s == null then
+ var ll = location
+ if ll != null then v.add_instr("fprintf(stderr, \"{ll.to_s}: \");")
+ v.add_instr("fprintf(stderr, \"Fatal error: unknown intern method {method.full_name}.\\n\");")
+ v.add_instr("nit_exit(1);")
+ s = "NIT_NULL"
+ end
+ if result == null then
+ v.new_instr.add(s).add(";\n")
+ else if need_result then
+ var w = new_result(v)
+ w.add(s)
end
end
end
end
end
-# A native C code
-# Mainly used to implements things that do not have a specific ICode yet
+# A native inlined call
+# Native are associated to local properties to distinguish them
# expr are the arguments
class INative
special ICodeN
- # The native C code
- # Special character sequence '@@@' will be substitued in order with the arguments
- readable var _code: String
+ # The associated local property
+ readable var _method: MMMethod
- init(c: String, e: nullable Sequence[IRegister])
+ init(m: MMMethod, e: nullable Sequence[IRegister])
do
super(e)
- _code = c
+ _method = m
end
redef readable writable var _is_pure: Bool = false
redef class INative
redef fun inner_dup_with(d)
do
- var c2 = new INative(code, d.dup_iregs(exprs))
+ var c2 = new INative(method, d.dup_iregs(exprs))
c2.is_pure = is_pure
return c2
end
redef fun fill_iroutine(v, method)
do
var params = v.iroutine.params
- var ename = method.extern_name.as(not null)
- var sig = method.signature
- assert params.length == sig.arity + 1
- var args = new Array[String]
- args.add(sig.recv.unboxtype("@@@"))
- for i in [0..sig.arity[ do
- args.add(sig[i].unboxtype("@@@"))
- end
- var s = "{ename}({args.join(", ")})"
- var rtype = sig.return_type
+ var rtype = method.signature.return_type
if rtype != null then
- s = rtype.boxtype(s)
- v.add_return_value(v.expr(new INative(s, params), rtype))
+ v.add_return_value(v.expr(new INative(method, params), rtype))
else
- v.stmt(new INative(s, params))
+ v.stmt(new INative(method, params))
end
end
end
redef class AInternMethPropdef
redef fun fill_iroutine(v, method)
do
- var p = v.iroutine.params.to_a
- var c = method.local_class.name
- var n = method.name
- var s: nullable String = null
- if c == once "Int".to_symbol then
- if n == once "object_id".to_symbol then
- s = "@@@"
- else if n == once "unary -".to_symbol then
- s = "TAG_Int(-UNTAG_Int(@@@))"
- else if n == once "output".to_symbol then
- s = "printf(\"%ld\\n\", UNTAG_Int(@@@));"
- else if n == once "ascii".to_symbol then
- s = "TAG_Char(UNTAG_Int(@@@))"
- else if n == once "succ".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)+1)"
- else if n == once "prec".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)-1)"
- else if n == once "to_f".to_symbol then
- s = "BOX_Float((float)UNTAG_Int(@@@))"
- else if n == once "+".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)+UNTAG_Int(@@@))"
- else if n == once "-".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)-UNTAG_Int(@@@))"
- else if n == once "*".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)*UNTAG_Int(@@@))"
- else if n == once "/".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)/UNTAG_Int(@@@))"
- else if n == once "%".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)%UNTAG_Int(@@@))"
- else if n == once "<".to_symbol then
- s = "TAG_Bool(UNTAG_Int(@@@)<UNTAG_Int(@@@))"
- else if n == once ">".to_symbol then
- s = "TAG_Bool(UNTAG_Int(@@@)>UNTAG_Int(@@@))"
- else if n == once "<=".to_symbol then
- s = "TAG_Bool(UNTAG_Int(@@@)<=UNTAG_Int(@@@))"
- else if n == once ">=".to_symbol then
- s = "TAG_Bool(UNTAG_Int(@@@)>=UNTAG_Int(@@@))"
- else if n == once "lshift".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)<<UNTAG_Int(@@@))"
- else if n == once "rshift".to_symbol then
- s = "TAG_Int(UNTAG_Int(@@@)>>UNTAG_Int(@@@))"
- else if n == once "==".to_symbol then
- s = "TAG_Bool((@@@)==(@@@))"
- else if n == once "!=".to_symbol then
- s = "TAG_Bool((@@@)!=(@@@))"
- end
- else if c == once "Float".to_symbol then
- if n == once "object_id".to_symbol then
- s = "TAG_Int((bigint)UNBOX_Float(@@@))"
- else if n == once "unary -".to_symbol then
- s = "BOX_Float(-UNBOX_Float(@@@))"
- else if n == once "output".to_symbol then
- s = "printf(\"%f\\n\", UNBOX_Float(@@@));"
- else if n == once "to_i".to_symbol then
- s = "TAG_Int((bigint)UNBOX_Float(@@@))"
- else if n == once "+".to_symbol then
- s = "BOX_Float(UNBOX_Float(@@@)+UNBOX_Float(@@@))"
- else if n == once "-".to_symbol then
- s = "BOX_Float(UNBOX_Float(@@@)-UNBOX_Float(@@@))"
- else if n == once "*".to_symbol then
- s = "BOX_Float(UNBOX_Float(@@@)*UNBOX_Float(@@@))"
- else if n == once "/".to_symbol then
- s = "BOX_Float(UNBOX_Float(@@@)/UNBOX_Float(@@@))"
- else if n == once "<".to_symbol then
- s = "TAG_Bool(UNBOX_Float(@@@)<UNBOX_Float(@@@))"
- else if n == once ">".to_symbol then
- s = "TAG_Bool(UNBOX_Float(@@@)>UNBOX_Float(@@@))"
- else if n == once "<=".to_symbol then
- s = "TAG_Bool(UNBOX_Float(@@@)<=UNBOX_Float(@@@))"
- else if n == once ">=".to_symbol then
- s = "TAG_Bool(UNBOX_Float(@@@)>=UNBOX_Float(@@@))"
- end
- else if c == once "Char".to_symbol then
- if n == once "object_id".to_symbol then
- s = "TAG_Int(UNTAG_Char(@@@))"
- else if n == once "unary -".to_symbol then
- s = "TAG_Char(-UNTAG_Char(@@@))"
- else if n == once "output".to_symbol then
- s = "printf(\"%c\", (unsigned char)UNTAG_Char(@@@));"
- else if n == once "ascii".to_symbol then
- s = "TAG_Int((unsigned char)UNTAG_Char(@@@))"
- else if n == once "succ".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)+1)"
- else if n == once "prec".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)-1)"
- else if n == once "to_i".to_symbol then
- s = "TAG_Int(UNTAG_Char(@@@)-'0')"
- else if n == once "+".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)+UNTAG_Char(@@@))"
- else if n == once "-".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)-UNTAG_Char(@@@))"
- else if n == once "*".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)*UNTAG_Char(@@@))"
- else if n == once "/".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)/UNTAG_Char(@@@))"
- else if n == once "%".to_symbol then
- s = "TAG_Char(UNTAG_Char(@@@)%UNTAG_Char(@@@))"
- else if n == once "<".to_symbol then
- s = "TAG_Bool(UNTAG_Char(@@@)<UNTAG_Char(@@@))"
- else if n == once ">".to_symbol then
- s = "TAG_Bool(UNTAG_Char(@@@)>UNTAG_Char(@@@))"
- else if n == once "<=".to_symbol then
- s = "TAG_Bool(UNTAG_Char(@@@)<=UNTAG_Char(@@@))"
- else if n == once ">=".to_symbol then
- s = "TAG_Bool(UNTAG_Char(@@@)>=UNTAG_Char(@@@))"
- else if n == once "==".to_symbol then
- s = "TAG_Bool((@@@)==(@@@))"
- else if n == once "!=".to_symbol then
- s = "TAG_Bool((@@@)!=(@@@))"
- end
- else if c == once "Bool".to_symbol then
- if n == once "object_id".to_symbol then
- s = "TAG_Int(UNTAG_Bool(@@@))"
- else if n == once "unary -".to_symbol then
- s = "TAG_Bool(-UNTAG_Bool(@@@))"
- else if n == once "output".to_symbol then
- s = "(void)printf(UNTAG_Bool(@@@)?\"true\\n\":\"false\\n\");"
- else if n == once "ascii".to_symbol then
- s = "TAG_Bool(UNTAG_Bool(@@@))"
- else if n == once "to_i".to_symbol then
- s = "TAG_Int(UNTAG_Bool(@@@))"
- else if n == once "==".to_symbol then
- s = "TAG_Bool((@@@)==(@@@))"
- else if n == once "!=".to_symbol then
- s = "TAG_Bool((@@@)!=(@@@))"
- end
- else if c == once "NativeArray".to_symbol then
- if n == once "object_id".to_symbol then
- s = "TAG_Int(((Nit_NativeArray)@@@)->object_id)"
- else if n == once "[]".to_symbol then
- s = "((Nit_NativeArray)@@@)->val[UNTAG_Int(@@@)]"
- else if n == once "[]=".to_symbol then
- s = "((Nit_NativeArray)@@@)->val[UNTAG_Int(@@@)]=@@@"
- else if n == once "copy_to".to_symbol then
- var t = p[0]
- p[0] = p[1]
- p[1] = t
- s = "(void)memcpy(((Nit_NativeArray )@@@)->val, ((Nit_NativeArray)@@@)->val, UNTAG_Int(@@@)*sizeof(val_t))"
- end
- else if c == once "NativeString".to_symbol then
- if n == once "object_id".to_symbol then
- s = "TAG_Int(UNBOX_NativeString(@@@))"
- else if n == once "atoi".to_symbol then
- s = "TAG_Int(atoi(UNBOX_NativeString(@@@)))"
- else if n == once "[]".to_symbol then
- s = "TAG_Char(UNBOX_NativeString(@@@)[UNTAG_Int(@@@)])"
- else if n == once "[]=".to_symbol then
- s = "UNBOX_NativeString(@@@)[UNTAG_Int(@@@)]=UNTAG_Char(@@@);"
- else if n == once "copy_to".to_symbol then
- var t = p[0]
- p[0] = p[1]
- p[1] = p[4]
- p[4] = p[2]
- p[2] = t
- s = "(void)memcpy(UNBOX_NativeString(@@@)+UNTAG_Int(@@@), UNBOX_NativeString(@@@)+UNTAG_Int(@@@), UNTAG_Int(@@@));"
- end
- else if n == once "object_id".to_symbol then
- s = "TAG_Int((bigint)((obj_t)@@@)[1].object_id)"
- else if n == once "sys".to_symbol then
- s = "(G_sys)"
- else if n == once "is_same_type".to_symbol then
- s = "TAG_Bool((VAL2VFT(@@@)==VAL2VFT(@@@)))"
- else if n == once "exit".to_symbol then
- p[0] = p[1]
- s = "exit(UNTAG_Int(@@@));"
- else if n == once "calloc_array".to_symbol then
- p[0] = p[1]
- s = "NEW_NativeArray(UNTAG_Int(@@@), sizeof(val_t))"
- else if n == once "calloc_string".to_symbol then
- p[0] = p[1]
- s = "BOX_NativeString((char*)raw_alloc((UNTAG_Int(@@@) * sizeof(char))))"
- end
- if s == null then
- v.visitor.error(self, "Fatal error: unknown intern method {method.full_name}.")
- s = "NIT_NULL"
- end
+ var params = v.iroutine.params
var rtype = method.signature.return_type
if rtype != null then
- v.add_return_value(v.expr(new INative(s, p), rtype))
+ v.add_return_value(v.expr(new INative(method, params), rtype))
else
- v.stmt(new INative(s, p))
+ v.stmt(new INative(method, params))
end
end
end