if _variables.has_key(v) then
return _variables[v]
else
- var reg = new_register(v.stype.as(not null))
+ var t = v.stype
+ if t == null then t = visitor.type_object.as_nullable
+ var reg = new_register(t)
_variables[v] = reg
return reg
end
# Register where a functionnal nit return must store its value
readable writable var _return_value: nullable IRegister
+ # The method associated to the iroutine (if any)
+ readable var _method: nullable MMMethod
+
init(visitor: AbsSyntaxVisitor, r: IRoutine, m: nullable MMMethod)
do
- super(visitor.module, r, m)
+ super(visitor.module, r)
_visitor = visitor
_return_seq = r.body
_return_value = r.result
+ _method = m
end
# Insert implicit super init calls
end
var l = n.super_init_calls.length
while i < l do
- var p = n.super_init_calls[i]
- if p == stop_prop then break
+ var sp = n.super_init_calls[i]
+ if sp == stop_prop then break
var cargs = new Array[IRegister]
- if p.signature.arity == 0 then
+ if sp.signature.arity == 0 then
cargs.add(iroutine.params.first)
else
for va in iroutine.params do
cargs.add(va)
end
end
- stmt(new ICall(p, cargs))
+ stmt(new ICall(sp, cargs))
i += 1
end
end
- # The current PExpr
- var _current_node: nullable PExpr = null
+ # The current AExpr
+ var _current_node: nullable AExpr = null
# Generate icode in the current sequence from a statement
- fun generate_stmt(n: nullable PExpr)
+ fun generate_stmt(n: nullable AExpr)
do
if n == null then return
var old = _current_node
end
# Generate icode in the current sequence from an expression
- fun generate_expr(n: PExpr): IRegister
+ fun generate_expr(n: AExpr): IRegister
do
var old = _current_node
_current_node = n
###############################################################################
-redef class PNode
+redef class ANode
fun accept_icode_generation(v: A2IVisitor) do accept_abs_syntax_visitor(v) end
end
fun fill_iroutine(v: A2IContext, method: MMSrcMethod) is abstract
end
-redef class PSignature
- fun fill_iroutine_parameters(v: A2IContext, orig_sig: MMSignature, params: IndexedCollection[IRegister], closdecls: nullable IndexedCollection[IClosureDecl]) is abstract
-end
-
redef class ASignature
- redef fun fill_iroutine_parameters(v: A2IContext, orig_sig: MMSignature, params: IndexedCollection[IRegister], closdecls: nullable IndexedCollection[IClosureDecl])
+ fun fill_iroutine_parameters(v: A2IContext, orig_sig: MMSignature, params: Sequence[IRegister], closdecls: nullable Sequence[IClosureDecl])
do
for ap in n_params do
var reg = v.variable(ap.variable)
redef fun accept_icode_generation(vv)
do
var v = vv.icode_ctx
- var iclos = variable.closure.signature.generate_empty_iclosuredef
+ var iclos = variable.closure.signature.generate_empty_iclosuredef(v)
var old_seq = v.seq
v.seq = iclos.body
escapable.continue_seq = iclos.body
end
else if c == once "NativeArray".to_symbol then
if n == once "object_id".to_symbol then
- s = "TAG_Int(UNBOX_NativeArray(@@@))"
+ s = "TAG_Int(((Nit_NativeArray)@@@)->object_id)"
else if n == once "[]".to_symbol then
- s = "UNBOX_NativeArray(@@@)[UNTAG_Int(@@@)]"
+ s = "((Nit_NativeArray)@@@)->val[UNTAG_Int(@@@)]"
else if n == once "[]=".to_symbol then
- s = "UNBOX_NativeArray(@@@)[UNTAG_Int(@@@)]=@@@;"
+ 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(UNBOX_NativeArray(@@@), UNBOX_NativeArray(@@@), UNTAG_Int(@@@)*sizeof(val_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 = "(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)@@@)"
+ 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 = "exit(UNTAG_Int(@@@));"
else if n == once "calloc_array".to_symbol then
p[0] = p[1]
- s = "BOX_NativeArray((val_t*)malloc((UNTAG_Int(@@@) * sizeof(val_t))))"
+ 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*)malloc((UNTAG_Int(@@@) * sizeof(char))))"
+ 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}.")
###############################################################################
-redef class PExpr
+redef class AExpr
redef fun accept_icode_generation(v) do end
# Generate icode sequence in the current A2IContext
redef class ADoExpr
redef fun generate_icode(v)
do
+ var seq_old = v.seq
+ var seq = new ISeq
+ v.stmt(seq)
+ escapable.break_seq = seq
+ v.seq = seq
+
v.generate_stmt(n_block)
+
+ v.seq = seq_old
return null
end
end
end
end
+redef class ALoopExpr
+ redef fun generate_icode(v)
+ do
+ var seq_old = v.seq
+ var iloop = new ILoop
+ v.stmt(iloop)
+ escapable.break_seq = iloop
+ v.seq = iloop
+
+ # Process inside
+ if n_block != null then
+ var seq = new ISeq
+ v.stmt(seq)
+ v.seq = seq
+ escapable.continue_seq = seq
+ v.generate_stmt(n_block)
+ end
+
+ v.seq = seq_old
+ return null
+ end
+end
+
redef class AForExpr
redef fun generate_icode(v)
do
v.stmt(iif)
var seq_old = v.seq
v.seq = iif.else_seq
+ v.generate_stmt(n_else)
var id = n_id
if id == null then
v.add_abort("Assert failed")
v.stmt(iif)
var seq_old = v.seq
v.seq = iif.then_seq
- v.add_assignment(reg, v.generate_expr(n_expr))
+ v.add_assignment(reg, v.lit_true_reg)
# Process right operand (in the else)
v.seq = iif.else_seq
v.stmt(iif)
var seq_old = v.seq
v.seq = iif.else_seq
- v.add_assignment(reg, v.generate_expr(n_expr))
+ v.add_assignment(reg, v.lit_false_reg)
# Process right operand (in the then)
v.seq = iif.then_seq
redef class ATrueExpr
redef fun generate_icode(v)
do
- return v.expr(new INative("TAG_Bool(true)", null), stype)
+ return v.lit_true_reg
end
end
redef class AFalseExpr
redef fun generate_icode(v)
do
- return v.expr(new INative("TAG_Bool(false)", null), stype)
+ return v.lit_false_reg
end
end
redef class ANullExpr
redef fun generate_icode(v)
do
- return v.new_register(stype)
+ return v.lit_null_reg
end
end
return null
end
else
- var p = prop
+ p = prop
var rtype = p.signature.return_type
if rtype == null then
v.stmt(new ISuper(p, args))
redef fun generate_icode(v)
do
var e = v.generate_expr(n_expr)
+ if n_expr.stype.is_nullable then v.add_null_reciever_check(e)
return v.add_attr_read(prop, e)
end
end
redef fun generate_icode(v)
do
var e = v.generate_expr(n_expr)
+ if n_expr.stype.is_nullable then v.add_null_reciever_check(e)
var e2 = v.generate_expr(n_value)
v.stmt(new IAttrWrite(prop, e, e2))
return null
redef fun generate_icode(v)
do
var e1 = v.generate_expr(n_expr)
+ if n_expr.stype.is_nullable then v.add_null_reciever_check(e1)
var e2 = v.expr(new IAttrRead(prop, e1), attr_type)
var e3 = v.generate_expr(n_value)
var e4 = v.expr(new ICall(assign_method, [e2, e3]), attr_type)
redef fun generate_icode(v)
do
var e = v.generate_expr(n_expr)
+ if n_expr.stype.is_nullable then v.add_null_reciever_check(e)
return v.expr(new IAttrIsset(prop, e), stype)
end
end
redef class AAbsAbsSendExpr
# Compile each argument and add them to the array
- fun generate_icode_for_arguments_in(v: A2IContext, args: Array[IRegister])
- do
- for a in arguments do
- args.add(v.generate_expr(a))
+ fun generate_icode_for_arguments_in(v: A2IContext, args: Array[IRegister], signature: MMSignature)
+ do
+ var par_arity = signature.arity
+ var par_vararg = signature.vararg_rank
+ var raw_args = raw_arguments
+ var raw_arity = raw_args.length
+ var arg_idx = 0
+ for par_idx in [0..par_arity[ do
+ var a: AExpr
+ var par_type = signature[par_idx]
+ if par_idx == par_vararg then
+ var arr = v.add_new_array(v.visitor.type_array(par_type), raw_arity-par_arity)
+ for i in [0..(raw_arity-par_arity)] do
+ a = raw_args[arg_idx]
+ v.add_call_array_add(arr, v.generate_expr(a))
+ arg_idx = arg_idx + 1
+ end
+ args.add(arr)
+ else
+ a = raw_args[arg_idx]
+ args.add(v.generate_expr(a))
+ arg_idx = arg_idx + 1
+ end
end
end
end
var recv = v.generate_expr(n_expr)
var args = new Array[IRegister]
args.add(recv)
- generate_icode_for_arguments_in(v, args)
var prop = prop
+ generate_icode_for_arguments_in(v, args, prop.signature.as(not null))
var r: nullable IRegister = null # The full result of the send (raw call + breaks)
var r2: nullable IRegister # The raw result of the call
closcns = new Array[nullable IClosureDef]
var cdarity = 0
if closure_defs != null then cdarity = closure_defs.length
- for i in [0..cdarity[ do
- closure_defs[i].escapable.break_seq = seq
- closure_defs[i].escapable.break_value = r
- var cn = closure_defs[i].generate_iclosuredef(v)
- closcns.add(cn)
- end
- for i in [cdarity..prop_signature.closures.length[ do
- closcns.add(null)
+ var closure_defs = closure_defs
+ for mmc in prop_signature.closures do
+ var found = false
+ var name = mmc.name
+ if closure_defs != null then
+ for cd in closure_defs do
+ if cd.n_id.to_symbol != name then continue
+ assert found == false
+ found = true
+ cd.escapable.break_seq = seq
+ cd.escapable.break_value = r
+ var cn = cd.generate_iclosuredef(v)
+ closcns.add(cn)
+ end
+ end
+ if not found then
+ closcns.add(null)
+ end
end
end
redef fun generate_icode(v)
do
var recv = v.generate_expr(n_expr)
+ if n_expr.stype.is_nullable then v.add_null_reciever_check(recv)
var args = new Array[IRegister]
args.add(recv)
- generate_icode_for_arguments_in(v, args)
+ generate_icode_for_arguments_in(v, args, read_prop.signature.as(not null))
var e2 = v.expr(new ICall(read_prop, args), read_prop.signature.return_type.as(not null))
var e3 = v.generate_expr(n_value)
redef fun generate_icode(v)
do
var args = new Array[IRegister]
- generate_icode_for_arguments_in(v, args)
+ generate_icode_for_arguments_in(v, args, prop.signature.as(not null))
return v.expr(new INew(stype, prop, args), stype)
end
end
end
-redef class PClosureDef
+redef class AClosureDef
var _iclosure_def: nullable IClosureDef
- fun generate_iclosuredef(v: A2IContext): IClosureDef is abstract
-end
-
-redef class AClosureDef
- redef fun generate_iclosuredef(v)
+ fun generate_iclosuredef(v: A2IContext): IClosureDef
do
# Prepare signature
var args = new Array[IRegister]
do
# Geneate arguments
var args = new Array[IRegister]
- generate_icode_for_arguments_in(v, args)
+ generate_icode_for_arguments_in(v, args, variable.closure.signature)
# Prepare icall
var closdecl = v.closurevariables[variable]
var iseq = new ISeq
icall.break_seq = iseq
v.seq = iseq
- v.generate_stmt(n_closure_defs.first.as(AClosureDef).n_expr)
+ v.generate_stmt(n_closure_defs.first.n_expr)
v.seq = seq_old
end
v.add_assignment(r, r2)
end
v.seq = iif.else_seq
- var r3 = closdecl_default.inline_in_seq(iif.else_seq, args)
+ var r3 = v.inline_routine(closdecl_default, args, null)
if r != null then
assert r3 != null
v.add_assignment(r, r3)