-
-
Save zoffixznet/17fb70a6cccdf0231f74e0ff180acf5e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/Perl6/Actions.nqp b/src/Perl6/Actions.nqp | |
index ed0fee780..8365e7461 100644 | |
--- a/src/Perl6/Actions.nqp | |
+++ b/src/Perl6/Actions.nqp | |
@@ -8906,12 +8906,23 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
my $wStr := $*W.find_symbol: ['Str'], :setting-only; | |
my $wNum := $*W.find_symbol: ['Num'], :setting-only; | |
+ my $pos := 0; | |
for %info<post_constraints> { | |
my $var-qast := QAST::Var.new: :$name, :scope<local>; | |
my $wval := QAST::WVal.new: :value($_); | |
my $what := nqp::what($_); | |
$var.push: QAST::ParamTypeCheck.new: | |
- nqp::eqaddr($what, $wInt) | |
+ nqp::istype($_, NQPArray) | |
+ ?? nqp::stmts( | |
+ # we have an optimized where setup; grab optimized | |
+ # qast from second element of the array and then | |
+ # swap the array into the first element, which | |
+ # contains a Code object for the slow binder path | |
+ $_[1].ann('optimized-where').name($name), | |
+ (my $qast := $_[1]), | |
+ (%info<post_constraints>[$pos] := $_[0]), | |
+ $qast) | |
+ !! nqp::eqaddr($what, $wInt) | |
?? QAST::Op.new(:op<if>, | |
QAST::Op.new(:op<isconcrete>, $var-qast), | |
QAST::Op.new(:op<iseq_I>, $wval, | |
@@ -8934,7 +8945,8 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
?? QAST::Op.new(:op<p6capturelex>, | |
QAST::Op.new: :op<callmethod>, :name<clone>, $wval) | |
!! $wval, | |
- $var-qast | |
+ $var-qast; | |
+ $pos++; | |
} | |
} | |
@@ -9159,6 +9171,7 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
# Build a block that'll smartmatch the topic against the | |
# expression. | |
check_smartmatch($/,$expr); | |
+ my $where := optimized-where-block($/, $expr, $operand); | |
my $past := QAST::Block.new( | |
QAST::Stmts.new( | |
QAST::Var.new( :name('$_'), :scope('lexical'), :decl('var') ) | |
@@ -9178,9 +9191,42 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
my $sig := $*W.create_signature(nqp::hash('parameter_objects', | |
[$*W.create_parameter($/, $param)])); | |
add_signature_binding_code($past, $sig, [$param]); | |
- $*W.create_code_object($past, 'Block', $sig) | |
+ my $block := $*W.create_code_object($past, 'Block', $sig); | |
+ $where ?? nqp::list($block, $where) !! $block | |
+ } | |
+ | |
+ sub optimized-where-block($/, $expr, $operand) { | |
+ if nqp::istype($expr, QAST::WVal) { # a single typecheck? | |
+ # we don't declare this var; in post-constraints, we'll change the | |
+ # name to the name of the actual param in the typecheck | |
+ my $var := QAST::Var.new: :scope<local>, :name<optimized-where-var>; | |
+ my $qast := QAST::Op.new: :op<istype>, $var, $expr; | |
+ $qast.annotate: 'optimized-where', $var; | |
+ return $qast; | |
+ } | |
+ elsif nqp::istype($expr, QAST::Op) # an "or" junction with types only? | |
+ && $expr.op eq 'call' && $expr.name eq '&infix:<|>' { | |
+ return 0 unless nqp::istype($_, QAST::WVal) for @($expr); | |
+ # we don't declare this var; in post-constraints, we'll change the | |
+ # name to the name of the actual param in the typecheck | |
+ my $var := QAST::Var.new: :scope<local>, :name<optimized-where-var>; | |
+ my $op := my $qast := QAST::Stmts.new; | |
+ for @($expr) { | |
+ $op.push: my $new-op := QAST::Op.new: :op<unless>, | |
+ QAST::Op.new: :op<istype>, $var, $_; | |
+ $op := $new-op; | |
+ } | |
+ # rewrite last `unless` into `istype` in the second branch of | |
+ # parent `unless` (or just the top node, if we only got one WVal) | |
+ $op.op: 'istype'; $op.push: $op[0][1]; $op[0] := $op[0][0]; | |
+ $qast := $qast[0]; # toss Stmts, we no longer need 'em; | |
+ $qast.annotate: 'optimized-where', $var; | |
+ return $qast; | |
+ } | |
+ 0 | |
} | |
+ | |
sub when_handler_helper($when_block) { | |
unless nqp::existskey(%*HANDLERS, 'SUCCEED') { | |
%*HANDLERS<SUCCEED> := QAST::Op.new( |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment