cd build
mkdir perl-current
cd perl-current
rsync -avz rsync://ftp.linux.activestate.com/perl-current/ .
####
sh Configure -Doptimize='-g' -Dusethreads -Dusedevel -Dprefix=/local/perl
-ders && make
##
##
perl -e 'my *x'
##
##
syntax error at -e line 1, near "my *x"
##
##
/* "my" declarations, with optional attributes */
myattrterm: MY myterm myattrlist
{ $$ = my_attrs($2,$3); }
| MY myterm
{ $$ = localize($2,$1); }
;
/* Things that can be "my"'d */
myterm : '(' expr ')'
{ $$ = sawparens($2); }
| '(' ')'
{ $$ = sawparens(newNULLLIST()); }
| scalar %prec '('
{ $$ = $1; }
| hsh %prec '('
{ $$ = $1; }
| ary %prec '('
{ $$ = $1; }
;
##
##
scalar : '$' indirob
{ $$ = newSVREF($2); }
;
ary : '@' indirob
{ $$ = newAVREF($2); }
;
hsh : '%' indirob
{ $$ = newHVREF($2); }
;
##
##
star : '*' indirob
{ $$ = newGVREF(0,$2); }
;
##
##
| star %prec '('
{ $$ = $1; }
##
##
perl regen_perly.pl
make perl
##
##
$ ./perl -e 'my *x'
Can't declare ref-to-glob cast in "my" at -e line 1, at EOF
##
##
$ ./perl -MO=Concise -e 'my $x; my @y; my %z'
8 <@> leave[1 ref] vKP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) v ->3
3 <0> padsv[$x:1,4] vM/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) v ->5
5 <0> padav[@y:2,4] vM/LVINTRO ->6
6 <;> nextstate(main 3 -e:1) v ->7
7 <0> padhv[%z:3,4] vM/LVINTRO ->8
-e syntax OK
##
##
$ diff -u opcode.pl{.orig,}
--- opcode.pl.orig 2005-10-18 19:07:24.000000000 +0100
+++ opcode.pl 2005-10-18 19:07:49.000000000 +0100
@@ -491,6 +491,7 @@
padsv private variable ck_null ds0
padav private array ck_null d0
padhv private hash ck_null d0
+padgv private glob ck_null d0
padany private value ck_null d0
pushre push regexp ck_null d/
##
##
--- op.c.before 2005-10-18 19:13:33.000000000 +0100
+++ op.c 2005-10-18 19:33:09.000000000 +0100
@@ -4902,7 +4902,13 @@
OP *
Perl_newGVREF(pTHX_ I32 type, OP *o)
{
- if (type == OP_MAPSTART || type == OP_GREPSTART || type == OP_SORT)
+ dVAR;
+ if (o->op_type == OP_PADANY) {
+ o->op_type = OP_PADGV;
+ o->op_ppaddr = PL_ppaddr[OP_PADGV];
+ return o;
+ }
+ else if (type == OP_MAPSTART || type == OP_GREPSTART || type == OP_SORT)
return newUNOP(OP_NULL, 0, o);
return ref(newUNOP(OP_RV2GV, OPf_REF, o), type);
}
##
##
--- pp.c.orig 2005-10-18 19:16:07.000000000 +0100
+++ pp.c 2005-10-18 19:17:51.000000000 +0100
@@ -127,6 +127,11 @@
RETURN;
}
+PP(pp_padgv)
+{
+ DIE(aTHX_ "OP_PADGV NOT YET IMPLEMENTED");
+}
+
PP(pp_padany)
{
DIE(aTHX_ "NOT IMPL LINE %d",__LINE__);
##
##
$ ./perl -MO=Concise -e 'my *x'
Can't declare ref-to-glob cast in "my" at -e line 1, at EOF
-e had compilation errors.
5 <@> leave[1 ref] KP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) ->3
4 <1> rv2gv sKR/1 ->5
3 <#> gv[*x] s ->4
##
##
$ gdb --args ./perl -e 'my *x'
...
(gdb) br Perl_newGVREF
Breakpoint 1 at 0x80a51e2: file op.c, line 4905.
(gdb) run
Starting program: /local/build/perl-current/perl -e my\ \*x
...
Breakpoint 1, Perl_newGVREF (my_perl=0x81b07c0, type=0, o=0x81ccc50)
at op.c:4905
4905 if (o->op_type == OP_PADANY) {
(gdb) p *o
$1 = {op_next = 0x81ccc50, op_sibling = 0x0,
op_ppaddr = 0x80e2c0c , op_targ = 0, op_type = 5, op_opt = 0,
op_static = 0, op_spare = 0, op_flags = 2 '\002', op_private = 16 '\020'}
##
##
$ grep OP_PADANY *.c
...
toke.c: yylval.opval = newOP(OP_PADANY, 0);
toke.c: yylval.opval = newOP(OP_PADANY, 0);
##
##
...
if (PL_pending_ident)
return REPORT(S_pending_ident(aTHX));
...
##
##
--- toke.c.orig 2005-10-18 19:47:57.000000000 +0100
+++ toke.c 2005-10-18 19:48:43.000000000 +0100
@@ -3169,7 +3169,7 @@
if (PL_expect != XOPERATOR) {
s = scan_ident(s, PL_bufend, PL_tokenbuf, sizeof PL_tokenbuf, TRUE);
PL_expect = XOPERATOR;
- force_ident(PL_tokenbuf, '*');
+ PL_pending_ident = '*';
if (!*PL_tokenbuf)
PREREF('*');
TERM('*');
##
##
syntax error at ../lib/vars.pm line 29, near "*$sym "
##
##
$ ./miniperl -DT -ce '*$x'
### 0:LEX_NORMAL/XSTATE "\n;"
### <== '*'
### 1:LEX_NORMAL/XREF "$x\n"
### Pending identifier ''
### <== WORD(opval=op_const) PV(""\0)
### 1:LEX_NORMAL/XREF "$x\n"
### <== '$'
### 1:LEX_NORMAL/XOPERATOR ";"
### Pending identifier '$x'
### <== WORD(opval=op_const) PV("x"\0)
### 1:LEX_NORMAL/XOPERATOR ";"
### <== ';'
### 1:LEX_NORMAL/XSTATE ""
### Tokener got EOF
### <== EOF
syntax error at -e line 1, next char $
-e had compilation errors.
##
##
$ ./miniperl -DT -ce '%$x'
### 0:LEX_NORMAL/XSTATE "\n;"
### <== '%'
### 1:LEX_NORMAL/XREF "$x\n"
### <== '$'
### 1:LEX_NORMAL/XOPERATOR ";"
### Pending identifier '$x'
### <== WORD(opval=op_const) PV("x"\0)
### 1:LEX_NORMAL/XOPERATOR ";"
### <== ';'
### 1:LEX_NORMAL/XSTATE ""
### Tokener got EOF
### <== EOF
EXECUTING...
-e syntax OK
##
##
--- toke.c.orig 2005-10-18 19:47:57.000000000 +0100
+++ toke.c 2005-10-18 20:16:52.000000000 +0100
@@ -3167,11 +3167,11 @@
case '*':
if (PL_expect != XOPERATOR) {
- s = scan_ident(s, PL_bufend, PL_tokenbuf, sizeof PL_tokenbuf, TRUE);
- PL_expect = XOPERATOR;
- force_ident(PL_tokenbuf, '*');
- if (!*PL_tokenbuf)
+ PL_tokenbuf[0] = '*';
+ s = scan_ident(s, PL_bufend, PL_tokenbuf + 1, sizeof PL_tokenbuf - 1, TRUE);
+ if (!PL_tokenbuf[1])
PREREF('*');
+ PL_pending_ident = '*';
TERM('*');
}
s++;
##
##
Global symbol "%DELETE" requires explicit package name at lib/Config_heavy.pl line 1158
##
##
*DELETE = \&STORE;
##
##
$ ./miniperl -ce '*foo'
-e syntax OK
$ ./miniperl -ce 'use strict; *foo'
Global symbol "%foo" requires explicit package name at -e line 1.
-e had compilation errors.
##
##
$ fgrep 'explicit package name' *.c
gv.c: "Global symbol \"%s%s\" requires explicit package name",
##
##
$ gdb --args ./miniperl -e '*foo'
(gdb) br Perl_gv_fetchpvn_flags
Breakpoint 1 at 0x806c485: file gv.c, line 710.
(gdb) condition 1 nambeg[0] == 'f'
(gdb) run
Starting program: /local/build/perl-current/miniperl -e \*foo
[New Thread 1074334048 (LWP 2919)]
[Switching to Thread 1074334048 (LWP 2919)]
Breakpoint 1, Perl_gv_fetchpvn_flags (my_perl=0x8199720,
nambeg=0x8199ca9 "foo", full_len=3, flags=1, sv_type=12) at gv.c:710
710 register const char *name = nambeg;
(gdb) bt
#0 Perl_gv_fetchpvn_flags (my_perl=0x8199720, nambeg=0x8199ca9 "foo",
full_len=3, flags=1, sv_type=12) at gv.c:710
#1 0x0806c406 in Perl_gv_fetchpv (my_perl=0x8199720, nambeg=0x8199ca9 "foo",
add=1, sv_type=12) at gv.c:696
#2 0x08087238 in S_pending_ident (my_perl=0x8199720) at toke.c:5669
#3 0x08076115 in Perl_yylex (my_perl=0x8199720) at toke.c:2431
#4 0x08092b5b in Perl_yyparse (my_perl=0x8199720) at perly.c:412
#5 0x08063ebc in S_parse_body (my_perl=0x8199720, env=0x0,
xsinit=0x804bb65 ) at perl.c:2136
#6 0x08062d16 in perl_parse (my_perl=0x8199720, xsinit=0x804bb65 ,
argc=3, argv=0xbffff3f4, env=0x0) at perl.c:1542
#7 0x0804baeb in main (argc=3, argv=0xbffff3f4, env=0xbffff404)
at miniperlmain.c:101
#8 0x42015704 in __libc_start_main () from /lib/tls/libc.so.6
##
##
gv_fetchpv(PL_tokenbuf+1, PL_in_eval ? (GV_ADDMULTI | GV_ADDINEVAL) : TRUE,
((PL_tokenbuf[0] == '$') ? SVt_PV
: (PL_tokenbuf[0] == '@') ? SVt_PVAV
: SVt_PVHV));
##
##
--- toke.c.1 2005-10-18 20:53:32.000000000 +0100
+++ toke.c 2005-10-18 20:54:34.000000000 +0100
@@ -5666,6 +5666,7 @@
gv_fetchpv(PL_tokenbuf+1, PL_in_eval ? (GV_ADDMULTI | GV_ADDINEVAL) : TRUE,
((PL_tokenbuf[0] == '$') ? SVt_PV
: (PL_tokenbuf[0] == '@') ? SVt_PVAV
+ : (PL_tokenbuf[0] == '*') ? SVt_PVGV
: SVt_PVHV));
return WORD;
}
##
##
$ ./perl -MO=Concise -e 'my *foo'
Can't declare private glob in "my" at -e line 1, at EOF
-e had compilation errors.
4 <@> leave[1 ref] KP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) ->3
3 <0> padgv[*foo:1,2] ->4
##
##
$ fgrep "Can't declare" *.c
op.c: "Can't declare class for non-scalar %s in \"%s\"",
op.c: yyerror(Perl_form(aTHX_ "Can't declare %s in %s",
op.c: yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
opmini.c: "Can't declare class for non-scalar %s in \"%s\"",
opmini.c: yyerror(Perl_form(aTHX_ "Can't declare %s in %s",
opmini.c: yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
##
##
else if (type != OP_PADSV &&
type != OP_PADAV &&
type != OP_PADHV &&
type != OP_PUSHMARK)
{
yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
OP_DESC(o),
PL_in_my == KEY_our ? "our" : "my"));
return o;
}
##
##
--- op.c.1 2005-10-18 21:03:51.000000000 +0100
+++ op.c 2005-10-18 21:04:11.000000000 +0100
@@ -1704,6 +1704,7 @@
else if (type != OP_PADSV &&
type != OP_PADAV &&
type != OP_PADHV &&
+ type != OP_PADGV &&
type != OP_PUSHMARK)
{
yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
##
##
$ ./perl -e 'my *foo'
OP_PADGV NOT YET IMPLEMENTED at -e line 1.
##
##
--- pp.c.orig 2005-10-18 19:16:07.000000000 +0100
+++ pp.c 2005-10-18 22:23:28.000000000 +0100
@@ -127,6 +127,15 @@
RETURN;
}
+PP(pp_padgv)
+{
+ dSP; dTARGET;
+ XPUSHs(TARG);
+ if (PL_op->op_private & OPpLVAL_INTRO)
+ SAVECLEARSV(PAD_SVl(PL_op->op_targ));
+ RETURN;
+}
+
PP(pp_padany)
{
DIE(aTHX_ "NOT IMPL LINE %d",__LINE__);
##
##
$ ./perl -e 'my *foo = *bar'
Can't modify private glob in scalar assignment at -e line 1, at EOF
##
##
$ fgrep "Can't modify" *.c
op.c: yyerror(Perl_form(aTHX_ "Can't modify %s in %s",
##
##
--- op.c.2 2005-10-18 21:43:38.000000000 +0100
+++ op.c 2005-10-18 21:44:12.000000000 +0100
@@ -1222,6 +1222,7 @@
o->op_private |= OPpMAYBE_LVSUB;
/* FALL THROUGH */
case OP_PADSV:
+ case OP_PADGV:
PL_modcount++;
if (!type) /* local() */
Perl_croak(aTHX_ "Can't localize lexical variable %s",
##
##
$ ./perl -we 'my *foo = *bar; print *foo, "\n"'
Name "main::bar" used only once: possible typo at -e line 1.
*main::bar
##
##
$ ./perl -we 'my *foo = *bar; $bar = "Hello, world!\n"; print ${*foo}'
Hello, world!
##
##
$ ./perl -we 'my *foo; print *foo{NAME}'
Segmentation fault
##
##
--- pp.c.1 2005-10-18 22:30:22.000000000 +0100
+++ pp.c 2005-10-19 00:47:33.000000000 +0100
@@ -130,9 +130,15 @@
PP(pp_padgv)
{
dSP; dTARGET;
- XPUSHs(TARG);
- if (PL_op->op_private & OPpLVAL_INTRO)
- SAVECLEARSV(PAD_SVl(PL_op->op_targ));
+ if (PL_op->op_private & OPpLVAL_INTRO) {
+ GV *gen_gv = newGVgen("lexical");
+ sv_upgrade(TARG, SVt_RV);
+ SvREFCNT_inc((SV *)gen_gv);
+ SvRV_set(TARG, (SV *)gen_gv);
+ SvROK_on(TARG);
+ SAVECLEARSV(PAD_SVl(PL_op->op_targ));
+ }
+ XPUSHs(SvRV(TARG));
RETURN;
}
##
##
$ ./perl -wle 'print my *x'
*lexical::_GEN_0
$ ./perl -wle 'my *x = *foo; $foo = "Nice!"; print ${*x}'
Nice!
$ ./perl -wle 'my *x = *foo; my *y = *x; $foo = "Even nicer!"; print ${*y}'
Even nicer!
$ ./perl -wle 'my *x = \23; ${*x} = 24'
Modification of a read-only value attempted at -e line 1.
$ ./perl -wle 'my *x = \23; *foo = *x; print $foo; $foo = 24'
23
Modification of a read-only value attempted at -e line 1.
##
##
sub foo {
my *foo = shift;
sub {${*foo}}
}
my $x = foo(*foo);
$foo = "Hmm";
print $x->();
my $y = foo(\23);
print $y->();
##
##
$ ./perl -wle 'for(1..10) {my *x} print sort keys %lexical::'
_GEN_0_GEN_1_GEN_2_GEN_3_GEN_4_GEN_5_GEN_6_GEN_7_GEN_8_GEN_9
##
##
$ ./perl -e 'while (1) {my *foo}'
##
##
--- pp.c.3 2005-10-19 01:26:19.000000000 +0100
+++ pp.c 2005-10-19 01:34:42.000000000 +0100
@@ -136,6 +136,7 @@
SvREFCNT_inc((SV *)gen_gv);
SvRV_set(TARG, (SV *)gen_gv);
SvROK_on(TARG);
+ hv_delete(GvSTASH(gen_gv), GvNAME(gen_gv), GvNAMELEN(gen_gv), 0);
SAVECLEARSV(PAD_SVl(PL_op->op_targ));
}
XPUSHs(SvRV(TARG));
##
##
$ ./perl -wle 'for (1..10) {print \my *foo}'
GLOB(0x81b22d8)
GLOB(0x81b22f8)
GLOB(0x81b22b8)
GLOB(0x81b22d8)
GLOB(0x81b22f8)
GLOB(0x81b22b8)
GLOB(0x81b22d8)
GLOB(0x81b22f8)
GLOB(0x81b22b8)
GLOB(0x81b22d8)
##
##
#!./perl
use Test::More tests => 7;
BEGIN {
# This is in a BEGIN block so that it will run even if
# the syntax causes a compilation error.
eval q{ my *foo };
ok(!$@, "Syntactically okay.");
}
{
my *foo = *bar;
is(*foo, "*main::bar", "Visible within scope,");
}
is(*foo, "*main::foo", "yet invisible without it.");
{
my *foo;
is(*foo{PACKAGE}, 'lexical', "Package is 'lexical'");
ok(!keys %lexical::, "Glob does not really exist.");
}
sub foo {
my *foo = shift;
sub {
return ${*foo};
}
}
my @foo = map foo($_), \(17, 23);
is($foo[0]->(), 17, 'Closure test ($foo[0] == 17)');
is($foo[1]->(), 23, 'Closure test ($foo[1] == 23)');
##
##
--- ext/Opcode/Opcode.pm.orig 2005-10-19 01:08:11.000000000 +0100
+++ ext/Opcode/Opcode.pm 2005-10-19 01:08:28.000000000 +0100
@@ -394,7 +394,7 @@
gvsv gv gelem
- padsv padav padhv padany
+ padsv padav padhv padgv padany
rv2gv refgen srefgen ref
##
##
--- ext/Safe/t/safeops.t.orig 2005-10-19 02:13:20.000000000 +0100
+++ ext/Safe/t/safeops.t 2005-10-19 02:13:52.000000000 +0100
@@ -19,7 +19,7 @@
}
use strict;
-use Test::More tests => 354;
+use Test::More tests => 355;
use Safe;
# Read the op names and descriptions directly from opcode.pl
@@ -72,6 +72,7 @@
SKIP my $x # padsv
SKIP my @x # padav
SKIP my %x # padhv
+SKIP my *x # padgv
SKIP (not implemented) # padany
SKIP split /foo/ # pushre
*x # rv2gv
##
##
--- ext/B/t/optree_concise.t.orig 2005-10-19 02:16:20.000000000 +0100
+++ ext/B/t/optree_concise.t 2005-10-19 02:16:37.000000000 +0100
@@ -183,13 +183,13 @@
UNOP (0x82b0918) leavesub [1]
LISTOP (0x82b08d8) lineseq
COP (0x82b0880) nextstate
- UNOP (0x82b0860) null [15]
+ UNOP (0x82b0860) null [16]
PADOP (0x82b0840) gvsv GV (0x82a818c) *a
EOT_EOT
# UNOP (0x8282310) leavesub [1]
# LISTOP (0x82822f0) lineseq
# COP (0x82822b8) nextstate
-# UNOP (0x812fc20) null [15]
+# UNOP (0x812fc20) null [16]
# SVOP (0x812fc00) gvsv GV (0x814692c) *a
EONT_EONT
##
##
--- patchlevel.h.orig 2005-10-19 03:31:04.000000000 +0100
+++ patchlevel.h 2005-10-19 03:32:24.000000000 +0100
@@ -122,6 +122,7 @@
static const char * const local_patches[] = {
NULL
,"DEVEL" STRINGIFY(PERL_PATCHNUM)
+ ,"LEXGLOB001 - lexically scoped globs!"
,NULL
};
##
##
...
Locally applied patches:
DEVEL25746
LEXGLOB001 - lexically scoped globs!
...