-
-
Save zoffixznet/7e45adca9cb04d5aec3b7a711b509abf 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 8f8b8d750..996a84c8b 100644 | |
--- a/src/Perl6/Actions.nqp | |
+++ b/src/Perl6/Actions.nqp | |
@@ -2814,9 +2814,18 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
if +@name > 1 { | |
$*W.throw($/, 'X::Dynamic::Package', symbol => ~$/); | |
} | |
+ # Try to get the var, if it's not there, look for it in a couple | |
+ # more places by calling &DYNAMIC. The `ifnull`/`getlexdyn` | |
+ # call is not part of &DYNAMIC because with such a setup, it | |
+ # is larger than the spesh inline limit in MoarVM and dynvars | |
+ # are fairly common, for us to want them to be fast | |
+ my $sVal-name := $*W.add_string_constant: $name; | |
$past := QAST::Op.new( | |
- :op('call'), :name('&DYNAMIC'), | |
- $*W.add_string_constant($name)); | |
+ :op<ifnull>, | |
+ QAST::Op.new(:op<getlexreldyn>, | |
+ QAST::Op.new(:op<ctx>), $sVal-name), | |
+ QAST::Op.new: :op<call>, :name<&DYNAMIC>, $sVal-name | |
+ ).annotate_self: '&DYNAMIC', $name; | |
} | |
elsif $twigil eq '?' && $*IN_DECL eq 'variable' && !$*COMPILING_CORE_SETTING { | |
$*W.throw($/, 'X::Syntax::Variable::Twigil', | |
@@ -6576,10 +6585,8 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
# first item is a hash (%foo or %!foo) | |
$is_hash := 1; | |
} | |
- elsif nqp::istype($elem, QAST::Op) && $elem.name eq '&DYNAMIC' && | |
- nqp::istype($elem[0], QAST::Want) && $elem[0][1] eq 'Ss' && | |
- nqp::istype($elem[0][2], QAST::SVal) | |
- && nqp::eqat($elem[0][2].value, '%', 0) { | |
+ elsif nqp::istype($elem, QAST::Op) | |
+ && nqp::eqat($elem.ann('&DYNAMIC'), '%', 0) { | |
# first item is a hash (%*foo) | |
$is_hash := 1; | |
} | |
@@ -7159,14 +7166,13 @@ class Perl6::Actions is HLL::Actions does STDActions { | |
$source | |
)); | |
} | |
- elsif nqp::istype($target, QAST::Op) && $target.op eq 'call' | |
- && $target.name eq '&DYNAMIC' && $target[0][1] eq 'Ss' { | |
+ elsif nqp::istype($target, QAST::Op) && $target.has_ann('&DYNAMIC') { | |
my $complain := QAST::Op.new( | |
:op('die_s'), | |
- QAST::SVal.new( :value('Contextual ' ~ ~$/ ~ ' not found') ) | |
+ QAST::SVal.new( :value('Contextual ' ~ $/ ~ ' not found') ) | |
); | |
my $contextual := QAST::VarWithFallback.new( | |
- :name($target[0][2].value), :scope('contextual'), :fallback($complain) ); | |
+ :name($target.ann: '&DYNAMIC'), :scope('contextual'), :fallback($complain) ); | |
my $dynbind := QAST::Op.new( :op('bind'), $contextual, $source); | |
$dynbind.nosink(1); | |
make $dynbind; | |
diff --git a/src/Perl6/Grammar.nqp b/src/Perl6/Grammar.nqp | |
index c6658d46d..98aba19ad 100644 | |
--- a/src/Perl6/Grammar.nqp | |
+++ b/src/Perl6/Grammar.nqp | |
@@ -414,11 +414,24 @@ role STD { | |
} | |
method check_variable($var) { | |
+ return self if $*IN_DECL; | |
my $varast := $var.ast; | |
- if nqp::istype($varast, QAST::Op) && $varast.op eq 'ifnull' { | |
- $varast := $varast[0]; | |
+ | |
+ if nqp::istype($varast, QAST::Op) { | |
+ if $varast.has_ann('&DYNAMIC') { | |
+ my $lex := $*W.cur_lexpad(); | |
+ my $au := $lex.ann('also_uses'); | |
+ $lex.annotate('also_uses', $au := {}) unless $au; | |
+ $au{$varast.ann: '&DYNAMIC'} := 1; | |
+ return self | |
+ } | |
+ | |
+ # do this here, because `&DYNAMIC`'s QAST we're looking at | |
+ # above is an `ifnull` op, but we don't want to unwrap it | |
+ $varast := $varast[0] if $varast.op eq 'ifnull'; | |
} | |
- if !$*IN_DECL && nqp::istype($varast, QAST::Var) && $varast.scope eq 'lexical' { | |
+ | |
+ if nqp::istype($varast, QAST::Var) && $varast.scope eq 'lexical' { | |
my $name := $varast.name; | |
if $name ne '%_' && $name ne '@_' && !$*W.is_lexical($name) { | |
@@ -453,14 +466,6 @@ role STD { | |
self.mark_variable_used($name); | |
} | |
} | |
- if !$*IN_DECL && nqp::istype($varast, QAST::Op) && $varast.name eq '&DYNAMIC' { | |
- my $lex := $*W.cur_lexpad(); | |
- if nqp::istype($varast[0], QAST::Want) && nqp::istype($varast[0][2], QAST::SVal) { | |
- my $au := $lex.ann('also_uses'); | |
- $lex.annotate('also_uses', $au := {}) unless $au; | |
- $au{$varast[0][2].value} := 1; | |
- } | |
- } | |
self | |
} | |
diff --git a/src/core/stubs.pm6 b/src/core/stubs.pm6 | |
index 7388a84a7..e4daebcd4 100644 | |
--- a/src/core/stubs.pm6 | |
+++ b/src/core/stubs.pm6 | |
@@ -31,25 +31,29 @@ my class Lock is repr('ReentrantMutex') { ... } | |
my class Lock::Async { ... } | |
sub DYNAMIC(\name) is raw { | |
- nqp::ifnull( | |
- nqp::getlexdyn(name), | |
- nqp::stmts( | |
- nqp::unless( | |
- nqp::isnull(my $prom := nqp::getlexdyn('$*PROMISE')), | |
- (my Mu $x := nqp::getlexreldyn( | |
- nqp::getattr($prom,Promise,'$!dynamic_context'),name) | |
- ) | |
- ), | |
- nqp::ifnull( | |
- $x, | |
- nqp::stmts( | |
- (my str $pkgname = nqp::replace(name,1,1,'')), | |
+ # When we gen dynvar lookup, in Actions, we first do this: | |
+ # nqp::ifnull( | |
+ # nqp::getlexdyn(name), | |
+ # And the call to this sub is in the "else" branch of that `ifnull`. | |
+ # The reason that stuff lives outside this sub is because all together | |
+ # the code is above the spesh inline limit (in MoarVM) and dynvar lookup | |
+ # is fairly common for us to want it very fast | |
+ nqp::stmts( | |
+ nqp::unless( | |
+ nqp::isnull(my $prom := nqp::getlexdyn('$*PROMISE')), | |
+ (my Mu $x := nqp::getlexreldyn( | |
+ nqp::getattr($prom,Promise,'$!dynamic_context'),name) | |
+ ) | |
+ ), | |
+ nqp::ifnull( | |
+ $x, | |
+ nqp::stmts( | |
+ (my str $pkgname = nqp::replace(name,1,1,'')), | |
+ nqp::ifnull( | |
+ nqp::atkey(GLOBAL.WHO,$pkgname), | |
nqp::ifnull( | |
- nqp::atkey(GLOBAL.WHO,$pkgname), | |
- nqp::ifnull( | |
- nqp::atkey(PROCESS.WHO,$pkgname), | |
- Rakudo::Internals.INITIALIZE-DYNAMIC(name) | |
- ) | |
+ nqp::atkey(PROCESS.WHO,$pkgname), | |
+ Rakudo::Internals.INITIALIZE-DYNAMIC(name) | |
) | |
) | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment