Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix closure handling bug with nested subs; should fix it for my-scope…
…d methods/regexes too.
  • Loading branch information
jnthn committed Sep 9, 2011
1 parent efe1f21 commit 00a1159
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 5 deletions.
8 changes: 4 additions & 4 deletions src/Perl6/Actions.pm
Expand Up @@ -1394,12 +1394,12 @@ class Perl6::Actions is HLL::Actions {
~$<deflongname>[0].ast ~ "'");
}
if $*SCOPE eq '' || $*SCOPE eq 'my' {
$*ST.install_lexical_symbol($outer, $name, $code);
$*ST.install_lexical_symbol($outer, $name, $code, :clone(1));
}
elsif $*SCOPE eq 'our' {
# Install in lexpad and in package, and set up code to
# re-bind it per invocation of its outer.
$*ST.install_lexical_symbol($outer, $name, $code);
$*ST.install_lexical_symbol($outer, $name, $code, :clone(1));
$*ST.install_package_symbol($*PACKAGE, $name, $code);
$outer[0].push(PAST::Op.new(
:pasttype('bind_6model'),
Expand Down Expand Up @@ -1554,10 +1554,10 @@ class Perl6::Actions is HLL::Actions {

# May also need it in lexpad and/or package.
if $*SCOPE eq 'my' {
$*ST.install_lexical_symbol($outer, '&' ~ $name, $code);
$*ST.install_lexical_symbol($outer, '&' ~ $name, $code, :clone(1));
}
elsif $*SCOPE eq 'our' {
$*ST.install_lexical_symbol($outer, '&' ~ $name, $code);
$*ST.install_lexical_symbol($outer, '&' ~ $name, $code, :clone(1));
$*ST.install_package_symbol($*PACKAGE, '&' ~ $name, $code);
}
}
Expand Down
17 changes: 16 additions & 1 deletion src/Perl6/SymbolTable.pm
Expand Up @@ -321,11 +321,26 @@ class Perl6::SymbolTable is HLL::Compiler::SerializationContextBuilder {
# the object to install. Does an immediate installation in the
# compile-time block symbol table, and ensures that the installation
# gets fixed up at runtime too.
method install_lexical_symbol($block, $name, $obj) {
method install_lexical_symbol($block, $name, $obj, :$clone) {
# Install the object directly as a block symbol.
$block.symbol($name, :scope('lexical_6model'), :value($obj));
$block[0].push(PAST::Var.new( :scope('lexical_6model'), :name($name), :isdecl(1) ));

# Add a clone if needed.
# XXX Horrible workaround here. We don't have proper serialization
# yet, and if we look up a cloned trait_mod (e.g. from the setting)
# then the serialization will blow up when we apply the trait. For
# now we just skip these, until the serializer lands.
if $clone && pir::substr($name, 0, 11) ne '&trait_mod:' {
$block[0].push(PAST::Op.new(
:pasttype('bind_6model'),
PAST::Var.new( :name($name), :scope('lexical_6model') ),
PAST::Op.new(
:pasttype('callmethod'), :name('clone'),
PAST::Var.new( :name($name), :scope('lexical_6model') )
)));
}

# Add to static lexpad, and generate deserialization code.
my $slp := self.get_static_lexpad($block);
$slp.add_static_value(~$name, $obj, 0, 0);
Expand Down

0 comments on commit 00a1159

Please sign in to comment.