summaryrefslogtreecommitdiff
path: root/ext/Opcode/Opcode.pm
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2012-07-26 12:38:14 -0700
committerFather Chrysostomos <sprout@cpan.org>2012-09-15 22:45:03 -0700
commit10342479afca0484c66269733fcc2f4a1fbabbb7 (patch)
treee3e43797240ed502e5f22246bb4d32ca997c7dbe /ext/Opcode/Opcode.pm
parent2a388207e072a645aa29f0b2b18f07d9a55cbf5e (diff)
downloadperl-10342479afca0484c66269733fcc2f4a1fbabbb7.tar.gz
Let state sub fwd decls and nested subs work in anons
I had this working: state sub foo; sub other { sub foo { # defines the state sub declared outside ... } } But it failed inside an anonymous subroutine: sub { state sub foo; sub other { sub foo { # defines the state sub declared outside ... } } } When an anonymous (or otherwise clonable) sub is cloned, any state vars, and, likewise, any state subs, inside it are cloned, too. In the first example above the state sub forward declaration creates a subroutine stub. The ‘other’ sub’s ‘sub foo’ declaration creates a pad entry in other’s pad that closes over the outer foo immediately, so the same stub is visible in two pads. The sub foo {} declaration uses that stub. When the outer sub containing the forward declaration is clonable, the pad entry is not closed over immediately at compile time, because the pad entry is just a prototype, not the actual value that will be shared by the clone and its nested subs. So the inner pad entry does not contain the sub. So the actual creation of the sub, if it only looks at the inner pad (other’s pad), will not see the stub, and will not attach a body to it. This was the result: $ ./miniperl -e 'CORE::state sub foo; CORE::state sub bar { sub foo {warn called} }; foo()' called at -e line 1. $ ./miniperl -e 'sub { CORE::state sub foo; CORE::state sub bar { sub foo {warn called} }; foo() }->()' Undefined subroutine &foo called at -e line 1. This commit fixes that by having newMYSUB follow the CvOUTSIDE chain to find the original pad entry where it defines the sub, if the for- ward declaration is occurs outside and has not been closed over yet.
Diffstat (limited to 'ext/Opcode/Opcode.pm')
0 files changed, 0 insertions, 0 deletions