# The method associated to the iroutine (if any)
readable var _method: nullable MMMethod
+ # The register of self (if any)
+ var selfreg: nullable IRegister writable
+
init(visitor: AbsSyntaxVisitor, r: IRoutine, m: nullable MMMethod)
do
super(visitor.mmmodule, r)
fun generate_icode(tc: ToolContext)
do
var v = new A2IVisitor(tc, self)
- for c in src_local_classes do
- for p in c.src_local_properties do
+ for c in src_local_classes.values do
+ for p in c.src_local_properties.values do
if p isa MMSrcMethod then
p.generate_iroutine(v)
else if p isa MMSrcAttribute then
var params = v.iroutine.params.to_a
var selfreg = v.variable(self_var)
v.stmt(new IMove(selfreg, params[0]))
+ v.selfreg = selfreg
params.shift
var orig_meth: MMLocalProperty = method.global.intro
if n_block != null then
v.generate_stmt(n_block)
end
+ v.selfreg = null
+ end
+end
+
+redef class AExternPropdef
+ redef fun fill_iroutine(v, method)
+ do
+ # add all explicit extern calls for this extern method
+ for explicit_import in method.as(MMMethSrcMethod).explicit_imports
+ do
+ var prop = explicit_import.method
+ var ic : IAbsCall
+ if prop.is_init then
+ ic = new INew(prop.signature.recv, prop, new List[IRegister])
+ else
+ ic = new ICall(prop, new List[IRegister])
+ end
+ ic.is_explicit_from_extern = true
+ v.stmt(ic)
+ end
+ end
+end
+
+redef class AExternInitPropdef
+ redef fun fill_iroutine(v, method)
+ do
+ var params = v.iroutine.params
+ var sig = method.signature
+ assert params.length == sig.arity + 1
+ var rtype = sig.recv # sig.return_type
+ v.add_assignment(new IRegister(rtype), v.expr(new INative(method, params), rtype))
+
+ super
end
end
else
v.stmt(new INative(method, params))
end
+
+ super
end
end
v.seq = iclos.body
escapable.continue_seq = iclos.body
escapable.continue_value = null
- v.stmt(new IMove(v.variable(variable), iclos.params.first))
+ for i in [0..variables.length[ do
+ v.stmt(new IMove(v.variable(variables[i]), iclos.params[i]))
+ end
v.generate_stmt(n_block)
# Call closure
if id == null then
v.add_abort("Assert failed")
else
- v.add_abort("Assert %s failed", id.to_s)
+ v.add_abort("Assert '%s' failed", id.text.to_s)
end
v.seq = seq_old
return null
redef fun generate_icode(v)
do
var e = v.generate_expr(n_expr)
- return v.expr(new ITypeCheck(e, n_type.stype), stype)
+ return v.expr(new ITypeCheck(v.selfreg.as(not null), e, n_type.stype), stype)
end
end