Skip to content

Commit b616d6c

Browse files
committed
keep the loop label as a MAST::Local
This means we can check for identical labels in the C code which resolves the handler, and do not need to do that in QAST.
1 parent 51b5ab0 commit b616d6c

File tree

1 file changed

+48
-53
lines changed

1 file changed

+48
-53
lines changed

src/vm/moar/QAST/QASTOperationsMAST.nqp

Lines changed: 48 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -958,10 +958,10 @@ for ('', 'repeat_') -> $repness {
958958
my @children;
959959
my $handler := 1;
960960
my $orig_type;
961-
my $label;
961+
my $label_wval;
962962
for $op.list {
963963
if $_.named eq 'nohandler' { $handler := 0; }
964-
elsif $_.named eq 'label' { $label := $_; }
964+
elsif $_.named eq 'label' { $label_wval := $_; }
965965
else { nqp::push(@children, $_) }
966966
}
967967
if needs_cond_passed(@children[1]) {
@@ -1060,39 +1060,45 @@ for ('', 'repeat_') -> $repness {
10601060
# just have the goto label be the place the control exception
10611061
# needs to send control to.
10621062
if $handler {
1063-
my $where := 0;
1063+
my $lablocal;
10641064
my $redo_mask := $HandlerCategory::redo;
10651065
my $next_mask := $HandlerCategory::next;
10661066
my $last_mask := $HandlerCategory::last;
1067-
if $label {
1068-
$where := nqp::where($label.value);
1069-
$redo_mask := $redo_mask + $HandlerCategory::labeled;
1070-
$next_mask := $next_mask + $HandlerCategory::labeled;
1071-
$last_mask := $last_mask + $HandlerCategory::labeled;
1067+
my $il := nqp::list();
1068+
if $label_wval {
1069+
$redo_mask := $redo_mask + $HandlerCategory::labeled;
1070+
$next_mask := $next_mask + $HandlerCategory::labeled;
1071+
$last_mask := $last_mask + $HandlerCategory::labeled;
1072+
my $labmast := $qastcomp.as_mast($label_wval, :want($MVM_reg_obj)); #nqp::where($label.value);
1073+
my $labreg := $labmast.result_reg;
1074+
$lablocal := MAST::Local.new(:index($*MAST_FRAME.add_local(NQPMu)));
1075+
push_ilist($il, $labmast);
1076+
push_op($il, 'set', $lablocal, $labreg);
1077+
$*REGALLOC.release_register($labreg, $MVM_reg_obj);
10721078
}
10731079
my @redo_il := [MAST::HandlerScope.new(
10741080
:instructions(@loop_il),
10751081
:category_mask($redo_mask),
10761082
:action($HandlerAction::unwind_and_goto),
10771083
:goto($redo_lbl),
1078-
:label($where)
1084+
:label($lablocal)
10791085
)];
10801086
my @next_il := [MAST::HandlerScope.new(
10811087
:instructions(@redo_il),
10821088
:category_mask($next_mask),
10831089
:action($HandlerAction::unwind_and_goto),
10841090
:goto($operands == 3 ?? $next_lbl !! $test_lbl),
1085-
:label($where)
1091+
:label($lablocal)
10861092
)];
1087-
my @last_il := [MAST::HandlerScope.new(
1093+
nqp::push($il, MAST::HandlerScope.new(
10881094
:instructions(@next_il),
10891095
:category_mask($last_mask),
10901096
:action($HandlerAction::unwind_and_goto),
10911097
:goto($done_lbl),
1092-
:label($where)
1093-
)];
1094-
nqp::push(@last_il, $done_lbl);
1095-
MAST::InstructionList.new(@last_il, $res_reg, $res_kind)
1098+
:label($lablocal)
1099+
));
1100+
nqp::push($il, $done_lbl);
1101+
MAST::InstructionList.new($il, $res_reg, $res_kind)
10961102
}
10971103
else {
10981104
nqp::push(@loop_il, $done_lbl);
@@ -1105,10 +1111,10 @@ for ('', 'repeat_') -> $repness {
11051111
QAST::MASTOperations.add_core_op('for', -> $qastcomp, $op {
11061112
my $handler := 1;
11071113
my @operands;
1108-
my $label;
1114+
my $label_wval;
11091115
for $op.list {
11101116
if $_.named eq 'nohandler' { $handler := 0; }
1111-
elsif $_.named eq 'label' { $label := $_; }
1117+
elsif $_.named eq 'label' { $label_wval := $_; }
11121118
else { @operands.push($_) }
11131119
}
11141120

@@ -1180,37 +1186,42 @@ QAST::MASTOperations.add_core_op('for', -> $qastcomp, $op {
11801186

11811187
# Emit postlude, wrapping in handlers if needed.
11821188
if $handler {
1183-
my $where := 0;
1189+
my $lablocal;
11841190
my $redo_mask := $HandlerCategory::redo;
11851191
my $next_mask := $HandlerCategory::next;
11861192
my $last_mask := $HandlerCategory::last;
1187-
if $label {
1188-
$where := nqp::where($label.value);
1189-
$redo_mask := $redo_mask + $HandlerCategory::labeled;
1190-
$next_mask := $next_mask + $HandlerCategory::labeled;
1191-
$last_mask := $last_mask + $HandlerCategory::labeled;
1193+
if $label_wval {
1194+
$redo_mask := $redo_mask + $HandlerCategory::labeled;
1195+
$next_mask := $next_mask + $HandlerCategory::labeled;
1196+
$last_mask := $last_mask + $HandlerCategory::labeled;
1197+
my $labmast := $qastcomp.as_mast($label_wval, :want($MVM_reg_obj));
1198+
my $labreg := $labmast.result_reg;
1199+
$lablocal := MAST::Local.new(:index($*MAST_FRAME.add_local(NQPMu)));
1200+
push_ilist($il, $labmast);
1201+
push_op($il, 'set', $lablocal, $labreg);
1202+
$*REGALLOC.release_register($labreg, $MVM_reg_obj);
11921203
}
11931204
my @ins_wrap := $loop_il.instructions;
11941205
@ins_wrap := [MAST::HandlerScope.new(
11951206
:instructions(@ins_wrap),
11961207
:category_mask($redo_mask),
11971208
:action($HandlerAction::unwind_and_goto),
11981209
:goto($lbl_redo),
1199-
:label($where)
1210+
:label($lablocal)
12001211
)];
12011212
@ins_wrap := [MAST::HandlerScope.new(
12021213
:instructions(@ins_wrap),
12031214
:category_mask($next_mask),
12041215
:action($HandlerAction::unwind_and_goto),
12051216
:goto($lbl_next),
1206-
:label($where)
1217+
:label($lablocal)
12071218
)];
12081219
nqp::push($il, MAST::HandlerScope.new(
12091220
:instructions(@ins_wrap),
12101221
:category_mask($last_mask),
12111222
:action($HandlerAction::unwind_and_goto),
12121223
:goto($lbl_done),
1213-
:label($where)
1224+
:label($lablocal)
12141225
));
12151226
}
12161227
else {
@@ -1559,6 +1570,7 @@ QAST::MASTOperations.add_core_op('handle', sub ($qastcomp, $op) {
15591570

15601571
# Otherwise, we need to generate and install a handler block, which will
15611572
# decide that to do by category.
1573+
my $il := nqp::list();
15621574
my $mask := 0;
15631575
my $hblock := QAST::Block.new(
15641576
QAST::Op.new(
@@ -1569,33 +1581,16 @@ QAST::MASTOperations.add_core_op('handle', sub ($qastcomp, $op) {
15691581
QAST::Op.new( :op('exception') )
15701582
)));
15711583
my $push_target := $hblock;
1572-
my $has_label := 0;
1584+
my $lablocal;
15731585
for @children -> $type, $handler {
15741586
if $type eq 'LABELED' {
1575-
$has_label := 1;
1576-
$mask := $HandlerCategory::handler;
1577-
# Rethrow if a label was requested for which we are not in charge for.
1578-
$hblock.push(
1579-
QAST::Op.new(
1580-
:op('if'),
1581-
QAST::Op.new(
1582-
:op('bitand_i'),
1583-
QAST::Var.new( :name('__category__'), :scope('local') ),
1584-
QAST::IVal.new( :value($HandlerCategory::labeled) )
1585-
),
1586-
QAST::Op.new(
1587-
:op('unless'),
1588-
QAST::Op.new(
1589-
:op('iseq_i'),
1590-
QAST::Op.new( :op('where'),
1591-
QAST::Op.new( :op('getpayload'), QAST::Op.new( :op('exception') ) )
1592-
),
1593-
QAST::Op.new( :op('where'), $handler )
1594-
),
1595-
QAST::Op.new( :op('rethrow'), QAST::Op.new( :op('exception') ) )
1596-
)
1597-
)
1598-
);
1587+
$mask := $HandlerCategory::labeled;
1588+
my $labmast := $qastcomp.as_mast($handler, :want($MVM_reg_obj));
1589+
my $labreg := $labmast.result_reg;
1590+
$lablocal := MAST::Local.new(:index($*MAST_FRAME.add_local(NQPMu)));
1591+
push_ilist($il, $labmast);
1592+
push_op($il, 'set', $lablocal, $labreg);
1593+
$*REGALLOC.release_register($labreg, $MVM_reg_obj);
15991594
}
16001595
else {
16011596
# Get the category mask.
@@ -1625,7 +1620,6 @@ QAST::MASTOperations.add_core_op('handle', sub ($qastcomp, $op) {
16251620

16261621
# Add a local and store the handler block into it.
16271622
my $hblocal := MAST::Local.new(:index($*MAST_FRAME.add_local(NQPMu)));
1628-
my $il := nqp::list();
16291623
my $hbmast := $qastcomp.as_mast($hblock, :want($MVM_reg_obj));
16301624
push_ilist($il, $hbmast);
16311625
push_op($il, 'set', $hblocal, $hbmast.result_reg);
@@ -1639,7 +1633,8 @@ QAST::MASTOperations.add_core_op('handle', sub ($qastcomp, $op) {
16391633
push_op($protil.instructions, 'goto', $endlbl);
16401634
nqp::push($il, MAST::HandlerScope.new(
16411635
:instructions($protil.instructions), :goto($uwlbl), :block($hblocal),
1642-
:category_mask($mask), :action($HandlerAction::invoke_and_we'll_see)));
1636+
:category_mask($mask), :action($HandlerAction::invoke_and_we'll_see),
1637+
:label($lablocal)));
16431638
nqp::push($il, $uwlbl);
16441639
push_op($il, 'takehandlerresult', $protil.result_reg);
16451640
nqp::push($il, $endlbl);

0 commit comments

Comments
 (0)