| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
For non-clonable state subs, this already happened to work.
For any clonable subs, we need to clone the sub as soon as it
is defined.
For redefined state subs, we need to apply the new sub to all recur-
sion levels, as state subs are shared.
|
| |
|
|
|
|
|
|
|
|
| |
newCVREF is changed to return a PADCV op, not an RV2CV with a PADCV
kid, to keep the rv2cv_op_cv changes to a minimum. (For some reason,
if newCVREF returns an RV2CV, we end up with two inside each other.)
I also added a test for recursion, since I nearly broke it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
By using find_runcv_where both for formats and my subs nested in inner
clonable subs, we can simplify the code.
It happens to make this work ($x is visible):
use 5.01;
sub not_lexical8 {
my sub foo;
foo();
sub not_lexical9 {
my sub bar {
my $x = 'khaki car keys for the khaki car';
not_lexical8();
sub foo { warn $x }
}
bar()
}
}
not_lexical9();
This is definitely iffy code, but if making it work makes the imple-
mentation simpler, so why not?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
sub foo {
my $x;
format =
@
$x||'#'
.
}
write;
__END__
Variable "$x" is not available at - line 9.
That one’s OK.
sub foo {
my sub x {};
format =
@
&x
.
}
write;
__END__
Variable "&x" is not available at - line 9.
Assertion failed: (SvTYPE(_svmagic) >= SVt_PVMG), function S_mg_findext_flags, file mg.c, line 404.
Abort trap
That should say ‘Subroutine’. And it shouldn’t crash.
The my-sub-cloning code was not taking this case into account. The
value in the proto pad is an undef scalar.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
sub {
my $x;
sub { eval '$x' }
}->()()
__END__
Variable "$x" is not available at (eval 1) line 2.
That one’s OK (though I wonder about the line number).
sub {
my sub x {};
sub { eval '\&x' }
}->()()
__END__
Variable "&x" is not available at (eval 1) line 1.
That should say ‘Subroutine’.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This code prints ARRAY(0x802e10), whereas it should print
SCALAR(0xfedbee):
undef &bar;
eval 'sub bar { my @x }';
{
my sub foo;
foo();
sub bar {
CORE::state $x;
sub foo { warn \$x }
}
}
The foo sub has a strong CvOUTSIDE pointer, but what it points to
can still be undefined and redefined. So we need to identify it
by its pad.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
PadnameOUTER (SvFAKE) entries in pads of clonable subs contain the
offset in the parent pad where the closed-over entry is to be found.
The pad itself does not reference the outer lexical until the sub is
cloned at run time.
newMYSUB had to account for that by following CvOUTSIDE for
PadnameOUTER entries, to account for cases like this:
my sub foo;
my sub bar { sub foo {} }
The sub foo{} definition would have to find the my sub foo declaration
from outside and store the sub there.
That code was not accounting for named package subs, which close over
variables at compile time, so they don’t need (and don’t) store a par-
ent offset.
So outcv would point to bar in this case:
my sub foo;
sub bar { sub foo {} }
If outcv matched CvOUTSIDE(foo), then CvOUTSIDE was made weak.
That does not help in cases like this:
undef *bar;
{
my sub foo;
sub bar { sub foo {} }
}
If foo has a weak CvOUTSIDE pointer, then it will still point to bar
after bar is freed, which does not help when the sub is cloned and
tries to look at CvROOT(CvOUTSIDE).
If the pad name is marked PadnameOUTER, even if it has no parent pad
index, newMYSUB needs to leave the CvOUTSIDE pointer strongc.
Also, pad_fixup_inner_anons did not account for subs with strong
CvOUTSIDE pointers whose CvOUTSIDE point to the sub whose pad is being
iterated through.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
In this example,
{
my sub foo;
sub bar {
sub foo { }
}
}
the foo sub is cloned when the scope containing the ‘my sub’ declara-
tion is entered, but foo’s CvOUTSIDE pointer points to something other
than the active sub. cv_clone assumes that the currently-running sub
is the right sub to close over (at least for subs; formats are another
matter). That was true in the absence of my subs. This commit
changes it to account.
I had to tweak the test, which was wrong, because sub foo was closing
over a stale var.
|
|
|
|
|
|
|
|
|
|
|
| |
The CvHASEVAL flag lets cv_clone know that the clone needs to have its
CvOUTSIDE pointer set, for the sake of string evals’ being able to
look up variables.
It was only being set on anonymous subs. It should be set for all
clonable subs. It doesn’t actually hurt to set it on all types of
subs, whether clonable or not, since it has no effect on non-clon-
able subs.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I had not yet fixed Perl_pad_fixup_inner_anons to account for the
fact that my sub prototype CVs are stored in magic attached to
the SV slot in the pad, rather than directly in the pad. It also
did not like & entries that close over subs defined in outer
or inner subs (‘my sub foo; sub bar; sub bar { &foo } }’ and
‘sub bar; sub bar { my sub foo; sub { sub foo { } } }’ respectively).
This was resulting in assertion failures, unsurprisingly.
Some of the tests I added, which were causing assertion failures, are
now failing for other reasons, and are marked as to-do.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The pad slot for a my sub now holds a stub with a prototype CV
attached to it by proto magic.
The prototype is cloned on scope entry. The stub in the pad is used
when cloning, so any code that references the sub before scope entry
will be able to see that stub become defined, making these behave
similarly:
our $x;
BEGIN { $x = \&foo }
sub foo { }
our $x;
my sub foo { }
BEGIN { $x = \&foo }
Constants are currently not cloned, but that may cause bugs in
pad_push. I’ll have to look into that.
On scope exit, lexical CVs go through leave_scope’s SAVEt_CLEARSV sec-
tion, like lexical variables. If the sub is referenced elsewhere, it
is abandoned, and its proto magic is stolen and attached to a new stub
stored in the pad. If the sub is not referenced elsewhere, it is
undefined via cv_undef.
To clone my subs on scope entry, we create a sequence of introcv and
clonecv ops. See the huge comment in block_end that explains why we
need two separate ops for each CV.
To allow my subs to be defined in inner subs (my sub foo; sub { sub
foo {} }), pad_add_name_pvn and S_pad_findlex now upgrade the entry
for a my sub to a CV to begin with, so that fake entries added to pads
(fake entries are those that reference outer pads) can share the same
CV. Otherwise newMYSUB would have to add the CV to every pad that
closes over the ‘my sub’ declaration. newMYSUB no longer throws away
the initial value replacing it with a new one.
Prototypes are not currently visible to sub calls at compile time,
because the lexer sees the empty stub. A future commit will
solve that.
When I added name heks to CV’s I made mistakes in a few places, by not
turning on the CVf_NAMED flag, or by not clearing the field when free-
ing the hek. Those code paths were not exercised enough by state
subs, so the problems did not show up till now. So this commit fixes
those, too.
One of the tests in lexsub.t, involving foreach loops, was incorrect,
and has been fixed. Another test has been added to the end for a par-
ticular case of state subs closing over my subs that I broke when ini-
tially trying to get sibling my subs to close over each other, before
I had separate introcv and clonecv ops.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
| |
This does just enough to get things to compile.
They currently do weird things in edge cases, including ‘Bizarre
copy of CODE’.
‘my sub’ now produces a SUB token, and goes through the same grammar
rule as ‘state sub’ and just plain ‘sub’. The separate MYSUB branch
of the barestmt rule will go soon, as it is now unused.
|
|
|
|
| |
This is just for consistency with package subs.
|
|
|
|
|
|
| |
The problem with writing to-do tests is that it is very easy to get
the tests wrong, such that they continue to fail even when the prob-
lems they test for are fixed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since state variables are not shared between closures, but only
between invocations of the same closure, state subs should behave
the same way.
This was a little tricky. When we clone a sub, we now clone inner
state subs at the same time. When walking through the pad, cloning
items, we cannot simply clone the inner sub when we see it, because it
may close over things we haven’t cloned yet:
sub {
state sub foo;
my $x
sub foo { $x }
}
We can’t just delay cloning it and do it afterwards, because they may
be multiple subs closing over each other:
sub {
state sub foo;
state sub bar;
sub foo { \&bar }
sub bar { \&foo }
}
So *all* the entries in the new pad must be filled before any inner
subs can be cloned.
So what we do is put a stub in place of the cloned sub. And then
in a second pass clone the inner subs, reusing the stubs from the
first pass.
|
|
|
|
|
|
| |
It should be ‘subroutine &foo’. (It could be ‘subroutine foo’, but we
use both forms elsewhere, and &foo is the easier to implement, the &
already being contained in the pad name.)
|
|
|
|
|
| |
I got this working a few commits ago, but the tests mentioned the
wrong sub name.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a sub starts being parsed, a new CV is created. When it fin-
ishes, it is stored in its final location. If there is a stub there
already, the pad is copied to the stub and the body attached thereto.
Since there may be closures inside the sub whose CvOUTSIDE
pointers point to the temporary CV used during compilation,
pad_fixup_inner_anons is called, to reassign all those
CvOUTSIDE pointers.
This happens in cases like this:
sub f;
sub f { sub { } }
When a sub closes over a lexical item in an outer sub, the inner sub
gets its own pad entry with the same value as the outer pad entry.
This means that, now that we have lexical subs (currently just state
subs), we can end up with a pad entry (&s) holding a sub whose
CvOUTSIDE does not point to the sub (f) that owns the pad:
state sub s { }
sub f { s() }
If the f sub has to reuse a stub, then pad_fixup_inner_anons gets to
see that, and complains bitterly:
$ ./perl -Ilib -E 'state sub s; sub f; sub f { s() }'
Assertion failed: (CvOUTSIDE(innercv) == old_cv), function Perl_pad_fixup_inner_anons, file pad.c, line 2095.
Abort trap
|
|
|
|
| |
instead of just ‘Undefined subroutine called’ without the name.
|
|
|
|
|
|
|
|
|
|
|
| |
State subs can now be referenced and called. Most of the tests in
lexsub.t are now passing. I noticed mistakes in a couple of the
tests and corrected them. In doing so I got an assertion failure
during compilation, so the tests in question I wrapped in a skipped
string eval.
State subs are now mostly working, but there are a few things to
clean up still.
|
|
|
|
|
|
|
|
|
|
|
| |
Most of these tests are still to-do. The previous commit got every-
thing compiling at least. Then I went through putting eval{} around
all the dying tests and marking the failing tests as to-do.
At least this way I don’t have to do everything at once (even though
that was how I wrote the tests).
About the only thing that works is constant inlining, of all things.
|
|
|
|
|
| |
The bareword logic in toke.c looks up GVs in various places. This
tests that we are bypassing those correctly.
|
|
|
|
|
|
| |
These take precedence over built-in keywords (just as my $AUTOLOAD
shadows the package var), but not the keyword plugin, as the latter
takes precedence over labels, and these don’t.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit switches all sub definitions, whether with ‘our’ or not,
to using S_force_ident_maybe_lex (formerly known as S_pending_ident).
This means that an unqualified (no our/my/state or package prefix)
‘sub foo’ declaration does a pad lookup, just like $foo.
It turns out that the vivification that I added to the then
S_pending_ident for CVs was unnecessary and actually buggy. We
*don’t* want to autovivify GVs for CVs, because they might be con-
stants or forward declarations, which are stored in a simpler form.
I also had to change the subname rule used by MYSUB in perly.y, since
it can now be fed a PRIVATEREF, which it does not expect. This may
prove to be temporary, but it keeps current tests passing.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
yylex must emit exactly one token each time it is called. Some-
times yylex needs to parse several tokens at once. That’s what
the various force functions are for. But that is also what
PL_pending_ident is for.
The various force_next, force_word, force_ident, etc., functions keep
a stack of tokens (PL_nextval/PL_nexttype) that yylex will check imme-
diately when called.
PL_pending_ident is used to track a single identifier that yylex will
hand off to S_pending_ident to handle.
S_pending_ident is the only piece of code for resolving an identi-
fier that could be lexical but could also be a package variable.
force_ident assumes it is looking for a package variable.
force_* takes precedence over PL_pending_ident.
All this means that, if an identifier needs to be looked up in the pad
on the next yylex invocation, it has to use PL_pending_ident, and the
force_* functions cannot be used at the same time.
Not realising that, when I made ‘our sub foo’ store the sub in the
pad I also made ‘our sub foo ($)’ into a syntax error, because it
was being parsed as ‘our sub ($) foo’ (the prototype being ‘forced’);
i.e., the pending tokens were being pulled out of the ‘queue’ in the
wrong order. (I put queue in quotes, because one queue and one unre-
lated buffer together don’t exactly count as ‘a queue’.)
Changing PL_pending_ident to have precedence over the force stack
breaks ext/XS-APItest/t/swaptwostmts.t, because the statement-parsing
interface does not localise PL_pending_ident. It could be changed to
do that, but I don’t think it is the right solution.
Having two separate pending token mechanisms makes things need-
lessly fragile.
This commit eliminates the PL_pending_ident mechanism and
modifies S_pending_ident (renaming it in the process to
S_force_ident_maybe_lex) to work with the force mechanism. I was
going to merge it with force_ident, but the two make incompatible
assumptions that just complicate the code if merged. S_pending_ident
needs the sigil in the same string buffer, to pass to the pad inter-
face. force_ident needs to be able to work without a sigil present.
So now we only have one queue for pending tokens and the order is more
predictable.
|
| |
|
|
|
|
|
|
|
|
| |
This is not testing what I meant it to test: that ‘sub d’ will respect
a preceding ‘our sub d;’. If ‘sub d’ is in the same package, it makes
no difference, so the test tests nothing.
It turns out this does not work yet.
|
|
|
|
| |
I thought cmd/ couldn’t use test.pl, but was mistaken.
|
|
|
|
|
|
|
|
|
|
| |
This changes &foo to go through S_pending_ident (by setting
PL_pending_ident, which causes yylex to defer to S_pending_ident for
the next token) the way $foo and %foo do.
This necessitated reducing the maximum identifier length of &foo from
252 to 251, making it match @foo, $foo, etc. So somebody’s JAPH might
break. :-)
|
| |
|
|
|
|
|
| |
Add some while tests, about the context of the last statement in a block
and about reinitializaiton of lexical variables.
|
|
|
|
|
|
|
| |
Add t/base/while.t testing the basic of a while loop with minimal
dependencies. Change t/cmd/while.t into a non-base test using "test.pl".
(Includes bugfixes by Zefram over Gerard's original patch.)
|
| |
|
| |
|
|
|
|
|
|
|
| |
Subject: Re: [PATCH t/cmd/for.t] Regression tests for 'for reverse ..'
Message-ID: <20080130200922.GA20450@fury.crisman.org>
p4raw-link: @33058 on //depot/perl: 4b70616db4b88e90e04bbf6a612b803f6a4d8dc1
p4raw-id: //depot/perl@33153
|
|
|
|
|
|
| |
Message-ID: <20080123225325.GA25959@abigail.be>
Date: Wed, 23 Jan 2008 23:53:25 +0100
p4raw-id: //depot/perl@33058
|
|
|
|
|
| |
'print do { foreach (1, 2) { 1; } }'"
p4raw-id: //depot/perl@27904
|
|
|
| |
p4raw-id: //depot/perl@27287
|
|
|
|
|
| |
Message-ID: <20051119061639.GA25086@petdance.com>
p4raw-id: //depot/perl@26178
|
|
|
|
|
| |
Message-ID: <20051022155627.GA22420@rpc142.cs.man.ac.uk>
p4raw-id: //depot/perl@25829
|
|
|
|
|
| |
tests.
p4raw-id: //depot/perl@23112
|
|
|
| |
p4raw-id: //depot/perl@23105
|
|
|
|
|
|
|
|
|
| |
pp_iter decremented the ref count of the previous iterant before
unaliasing it. This could lead to DESTROY being called with the
loop variable still aliased to the freed value. If the DESTROY
also contained a for loop with the same iterator variable, the
freed value would get resurrected then freed for a second time.
p4raw-id: //depot/perl@22913
|
|
|
|
|
|
|
| |
Subject: [PATCH] Perl_croak("Use of freed value in iteration")
Message-ID: <20030421121950.GB18189@fdgroup.com>
Message-ID: <20030421125433.GC18189@fdgroup.com>
p4raw-id: //depot/perl@19316
|
|
|
|
|
| |
Message-ID: <8765ugnffq.fsf@vran.herceg.de>
p4raw-id: //depot/perl@18264
|
|
|
|
|
|
|
| |
Message-ID: <m33d1tvjuq.fsf@anima.de>
(except for the three DB_File patch fragments)
p4raw-id: //depot/perl@13940
|