Skip to content

Commit ed3aa83

Browse files
committed
Implement handlepayload.
Will be used to implement new control-exception-based return in an efficient (allocation-free) way.
1 parent 7a9f8e5 commit ed3aa83

File tree

1 file changed

+31
-0
lines changed

1 file changed

+31
-0
lines changed

src/vm/moar/QAST/QASTOperationsMAST.nqp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,7 @@ my %handler_names := nqp::hash(
16361636
'AWAIT', $HandlerCategory::await,
16371637
'EMIT', $HandlerCategory::emit,
16381638
'DONE', $HandlerCategory::done,
1639+
'RETURN', $HandlerCategory::return,
16391640
);
16401641
QAST::MASTOperations.add_core_op('handle', :!inlinable, sub ($qastcomp, $op) {
16411642
my @children := nqp::clone($op.list());
@@ -1725,6 +1726,36 @@ QAST::MASTOperations.add_core_op('handle', :!inlinable, sub ($qastcomp, $op) {
17251726
MAST::InstructionList.new($il, $protil.result_reg, $MVM_reg_obj)
17261727
});
17271728

1729+
# Simple payload handler.
1730+
QAST::MASTOperations.add_core_op('handlepayload', :!inlinable, sub ($qastcomp, $op) {
1731+
my @children := $op.list;
1732+
if @children != 3 {
1733+
nqp::die("The 'handlepayload' op requires three children");
1734+
}
1735+
my str $type := @children[1];
1736+
unless nqp::existskey(%handler_names, $type) {
1737+
nqp::die("Invalid handler type '$type'");
1738+
}
1739+
my int $mask := %handler_names{$type};
1740+
1741+
my $il := nqp::list();
1742+
my $protected := $qastcomp.as_mast(@children[0], :want($MVM_reg_obj));
1743+
my $handler := $qastcomp.as_mast(@children[2], :want($MVM_reg_obj));
1744+
my $endlbl := MAST::Label.new();
1745+
my $handlelbl := MAST::Label.new();
1746+
push_op($protected.instructions, 'goto', $endlbl);
1747+
nqp::push($il, MAST::HandlerScope.new(
1748+
:instructions($protected.instructions), :goto($handlelbl),
1749+
:category_mask($mask), :action($HandlerAction::unwind_and_goto_with_payload)));
1750+
nqp::push($il, $handlelbl);
1751+
push_ilist($il, $handler);
1752+
push_op($il, 'set', $protected.result_reg, $handler.result_reg);
1753+
nqp::push($il, $endlbl);
1754+
$*REGALLOC.release_register($handler.result_reg, $MVM_reg_obj);
1755+
1756+
MAST::InstructionList.new($il, $protected.result_reg, $MVM_reg_obj)
1757+
});
1758+
17281759
# Control exception throwing.
17291760
my %control_map := nqp::hash(
17301761
'next', $HandlerCategory::next,

0 commit comments

Comments
 (0)