Skip to content

Commit

Permalink
Fix op_unless coercion
Browse files Browse the repository at this point in the history
Sample code:
```
my $foo := 42;
my int $bar := $foo || 200;
say($bar);
```

Before it says '0' and now '42'.
The problem is we generate $foo || 200 as

- QAST::Op(unless &infix:<||>)  ||
  - QAST::Var(lexical $bar)
  - QAST::IVal(200)

and thus $bar only be a condition. If we want to return its value,
we forget to coerce its kind.

Now this fix only apply on op_unless. If applies on the four ops
handled this block, it fails some tests in t/qast/01-qast.t.
  • Loading branch information
tisonkun committed Dec 7, 2017
1 parent 5f25c81 commit 335ac1c
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 4 deletions.
14 changes: 14 additions & 0 deletions src/vm/moar/QAST/QASTOperationsMAST.nqp
Expand Up @@ -807,6 +807,7 @@ for <if unless with without> -> $op_name {
);
}

my $fix_coercion;
# Emit the then, stash the result
push_ilist(@ins, @comp_ops[1]);
if (!$is_void && @comp_ops[1].result_kind != $res_kind) {
Expand All @@ -817,6 +818,14 @@ for <if unless with without> -> $op_name {
$res_reg := $regalloc.fresh_register($coercion.result_kind);
push_op(@ins, 'set', $res_reg, $coercion.result_reg);
$res_kind := $coercion.result_kind;
if ($op_name eq 'unless' && $operands == 2 && @comp_ops[0].result_kind != $res_kind) {
my $coercion := $qastcomp.coercion(@comp_ops[0],
(nqp::defined($*WANT) ?? $*WANT !! $MVM_reg_obj));
$fix_coercion := $coercion;
$regalloc.release_register($res_reg, $res_kind);
$res_reg := $regalloc.fresh_register($coercion.result_kind);
$res_kind := $coercion.result_kind;
}
}
elsif !$is_void {
push_op(@ins, 'set', $res_reg, @comp_ops[1].result_reg);
Expand Down Expand Up @@ -845,6 +854,11 @@ for <if unless with without> -> $op_name {
$regalloc.release_register(@comp_ops[0].result_reg, @comp_ops[0].result_kind);
nqp::push(@ins, $end_lbl);

if $fix_coercion {
push_ilist(@ins, $fix_coercion);
push_op(@ins, 'set', $res_reg, $fix_coercion.result_reg);
}

MAST::InstructionList.new(@ins, $res_reg, $res_kind)
});
}
Expand Down
8 changes: 4 additions & 4 deletions t/qast/01-qast.t
Expand Up @@ -651,7 +651,7 @@ test_qast_result(
-> $r {
ok(nqp::getattr_i($r, E, '$!x') == 99, 'attribute binding works');
});

my $test_obj := nqp::create(E);
nqp::bindattr_i($test_obj, E, '$!x', 199);
is_qast_args(
Expand Down Expand Up @@ -1392,9 +1392,9 @@ test_qast_result(
),
sval('D')
),
QAST::Op.new( :op<chain>, :name<op1>,
QAST::Op.new( :op<chain>, :name<op1>,
QAST::Op.new( :op<chain>, :name<op2>,
QAST::Op.new( :op<chain>, :name<op3>,
QAST::Op.new( :op<chain>, :name<op3>,
QAST::Op.new( :op<chain>, :name<op2>, sval('A'), sval('B')),
sval('E')
),
Expand Down Expand Up @@ -2172,7 +2172,7 @@ is_qast(
with_arity(1, QAST::Block.new(
:blocktype<immediate>,
QAST::Op.new(
:op<if>,
:op<if>,
QAST::Op.new(
:op<iseq_i>,
QAST::Var.new( :name('$j'), :scope<lexical>, :decl<param> ),
Expand Down

0 comments on commit 335ac1c

Please sign in to comment.