Skip to content

Commit 0860fab

Browse files
committed
Ensure we decont into a fresh register.
In cases where we actually get a register that is persistent (such as holding a local that a lexical was lowered into), we should not go and ruin the variable.
1 parent 32ddb22 commit 0860fab

File tree

1 file changed

+30
-12
lines changed

1 file changed

+30
-12
lines changed

src/vm/moar/QAST/QASTOperationsMAST.nqp

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -749,13 +749,22 @@ for <if unless> -> $op_name {
749749

750750
# Emit the jump.
751751
if @comp_ops[0].result_kind == $MVM_reg_obj {
752-
push_op(@ins, 'decont', @comp_ops[0].result_reg, @comp_ops[0].result_reg);
752+
my $decont_reg := $*REGALLOC.fresh_register($MVM_reg_obj);
753+
push_op(@ins, 'decont', $decont_reg, @comp_ops[0].result_reg);
754+
push_op(@ins,
755+
resolve_condition_op(@comp_ops[0].result_kind, $op_name eq 'if'),
756+
$decont_reg,
757+
($operands == 3 ?? $else_lbl !! $end_lbl)
758+
);
759+
$*REGALLOC.release_register($decont_reg, $MVM_reg_obj);
760+
}
761+
else {
762+
push_op(@ins,
763+
resolve_condition_op(@comp_ops[0].result_kind, $op_name eq 'if'),
764+
@comp_ops[0].result_reg,
765+
($operands == 3 ?? $else_lbl !! $end_lbl)
766+
);
753767
}
754-
push_op(@ins,
755-
resolve_condition_op(@comp_ops[0].result_kind, $op_name eq 'if'),
756-
@comp_ops[0].result_reg,
757-
($operands == 3 ?? $else_lbl !! $end_lbl)
758-
);
759768

760769
# Emit the then, stash the result
761770
push_ilist(@ins, @comp_ops[1]);
@@ -1030,13 +1039,22 @@ for ('', 'repeat_') -> $repness {
10301039
push_ilist(@loop_il, @comp_ops[0]);
10311040
push_op(@loop_il, 'set', $res_reg, @comp_ops[0].result_reg);
10321041
if @comp_ops[0].result_kind == $MVM_reg_obj {
1033-
push_op(@loop_il, 'decont', @comp_ops[0].result_reg, @comp_ops[0].result_reg);
1042+
my $decont_reg := $*REGALLOC.fresh_register($MVM_reg_obj);
1043+
push_op(@loop_il, 'decont', $decont_reg, @comp_ops[0].result_reg);
1044+
push_op(@loop_il,
1045+
resolve_condition_op(@comp_ops[0].result_kind, $op_name eq 'while'),
1046+
$decont_reg,
1047+
$done_lbl
1048+
);
1049+
$*REGALLOC.release_register($decont_reg, $MVM_reg_obj);
1050+
}
1051+
else {
1052+
push_op(@loop_il,
1053+
resolve_condition_op(@comp_ops[0].result_kind, $op_name eq 'while'),
1054+
@comp_ops[0].result_reg,
1055+
$done_lbl
1056+
);
10341057
}
1035-
push_op(@loop_il,
1036-
resolve_condition_op(@comp_ops[0].result_kind, $op_name eq 'while'),
1037-
@comp_ops[0].result_reg,
1038-
$done_lbl
1039-
);
10401058

10411059
# Handle immediate blocks wanting the value as an arg.
10421060
if $*IMM_ARG {

0 commit comments

Comments
 (0)