Skip to content
Permalink
Browse files

Properly track and fixup getlexouter usages

These are only normally emitted as part of $_ handling, so naturally
need to be fixed up properly when doing block inlining or respected
then doing lexical to local lowering.
  • Loading branch information...
jnthn committed Jan 3, 2019
1 parent ab7f07d commit 91a4b3b1d928fca8602c063c329d1d5dbce64bf6
Showing with 23 additions and 3 deletions.
  1. +23 −3 src/Perl6/Optimizer.nqp
@@ -502,6 +502,8 @@ my class BlockVarOptimizer {

method get_usages_inner() { %!usages_inner }

method get_getlexouter_binds() { @!getlexouter_binds }

method get_calls() { $!calls }

method is_poisoned() { $!poisoned }
@@ -518,6 +520,15 @@ my class BlockVarOptimizer {
add_to_set($flattened ?? %!usages_flat !! %!usages_inner,
$vars_info.get_usages_flat, %decls);

# If the inner block uses getlexouter then we need to store those as
# usages.
for $vars_info.get_getlexouter_binds() {
my $name := $_[1][0].value;
my %target := $flattened ?? %!usages_flat !! %!usages_inner;
%target{$name} := [] unless %target{$name};
nqp::push(%target{$name}, $_);
}

# Add up call counts.
$!calls := $!calls + $vars_info.get_calls;

@@ -665,7 +676,7 @@ my class BlockVarOptimizer {
my int $ref'd := 0;
if %!usages_flat{$name} {
for %!usages_flat{$name} {
if $_.scope eq 'lexicalref' {
if nqp::istype($_, QAST::Var) && $_.scope eq 'lexicalref' {
$ref'd := 1;
last;
}
@@ -731,8 +742,17 @@ my class BlockVarOptimizer {
}
if %!usages_flat{$name} {
for %!usages_flat{$name} {
$_.scope('local');
$_.name($new_name);
if nqp::istype($_, QAST::Var) {
$_.scope('local');
$_.name($new_name);
}
elsif nqp::istype($_, QAST::Op) && $_.op eq 'bind' &&
nqp::istype($_[1], QAST::Op) && $_[1].op eq 'getlexouter' {
$_[1] := QAST::Var.new( :name($new_name), :scope('local') );
}
else {
nqp::die("Unexpected node in usages_flat");
}
}
}
}

0 comments on commit 91a4b3b

Please sign in to comment.
You can’t perform that action at this time.