diff options
-rw-r--r-- | Porting/deparse-skips.txt | 1 | ||||
-rw-r--r-- | cpan/B-Debug/t/debug.t | 6 | ||||
-rw-r--r-- | dist/Safe/t/safeops.t | 1 | ||||
-rw-r--r-- | dump.c | 15 | ||||
-rw-r--r-- | embed.fnc | 2 | ||||
-rw-r--r-- | ext/B/B.pm | 2 | ||||
-rw-r--r-- | ext/B/B.xs | 23 | ||||
-rw-r--r-- | ext/B/B/Concise.pm | 48 | ||||
-rw-r--r-- | ext/B/t/b.t | 3 | ||||
-rw-r--r-- | ext/B/t/optree_concise.t | 4 | ||||
-rw-r--r-- | ext/B/t/walkoptree.t | 6 | ||||
-rw-r--r-- | ext/Opcode/Opcode.pm | 4 | ||||
-rw-r--r-- | lib/B/Deparse.pm | 88 | ||||
-rw-r--r-- | lib/B/Deparse.t | 26 | ||||
-rw-r--r-- | lib/B/Op_private.pm | 16 | ||||
-rw-r--r-- | op.c | 213 | ||||
-rw-r--r-- | op.h | 8 | ||||
-rw-r--r-- | opcode.h | 423 | ||||
-rw-r--r-- | opnames.h | 769 | ||||
-rw-r--r-- | pod/perldiag.pod | 8 | ||||
-rw-r--r-- | pp.c | 38 | ||||
-rw-r--r-- | pp_ctl.c | 12 | ||||
-rw-r--r-- | pp_hot.c | 19 | ||||
-rw-r--r-- | pp_proto.h | 1 | ||||
-rw-r--r-- | proto.h | 2 | ||||
-rw-r--r-- | regen/op_private | 13 | ||||
-rw-r--r-- | regen/opcodes | 4 | ||||
-rw-r--r-- | regexp.h | 5 | ||||
-rw-r--r-- | t/op/split.t | 17 | ||||
-rw-r--r-- | t/perf/benchmarks | 20 |
30 files changed, 934 insertions, 863 deletions
diff --git a/Porting/deparse-skips.txt b/Porting/deparse-skips.txt index 7e77d717a4..efac18fb0b 100644 --- a/Porting/deparse-skips.txt +++ b/Porting/deparse-skips.txt @@ -175,7 +175,6 @@ op/pack.t op/postfixderef.t op/range.t op/readline.t -op/split.t op/srand.t op/sub.t op/sub_lval.t diff --git a/cpan/B-Debug/t/debug.t b/cpan/B-Debug/t/debug.t index f4f0a10563..0c79adbc24 100644 --- a/cpan/B-Debug/t/debug.t +++ b/cpan/B-Debug/t/debug.t @@ -56,19 +56,19 @@ my $is_thread = $Config{use5005threads} && $Config{use5005threads} eq 'define'; if ($is_thread) { $b=<<EOF; leave enter nextstate label leaveloop enterloop null and defined null -threadsv readline gv lineseq nextstate aassign null pushmark split pushre +threadsv readline gv lineseq nextstate aassign null pushmark split threadsv const null pushmark rvav gv nextstate subst const unstack EOF } elsif ($] >= 5.021005) { $b=<<EOF; leave enter nextstate label leaveloop enterloop null and defined null null -gvsv readline gv lineseq nextstate split pushre null +gvsv readline gv lineseq nextstate split null gvsv const nextstate subst const unstack EOF } else { $b=<<EOF; leave enter nextstate label leaveloop enterloop null and defined null null -gvsv readline gv lineseq nextstate aassign null pushmark split pushre null +gvsv readline gv lineseq nextstate aassign null pushmark split null gvsv const null pushmark rvav gv nextstate subst const unstack EOF } diff --git a/dist/Safe/t/safeops.t b/dist/Safe/t/safeops.t index 2133bde16b..9094a00b93 100644 --- a/dist/Safe/t/safeops.t +++ b/dist/Safe/t/safeops.t @@ -111,7 +111,6 @@ padsv SKIP my $x padav SKIP my @x padhv SKIP my %x padany SKIP (not implemented) -pushre SKIP split /foo/ rv2gv *x rv2sv $x av2arylen $#x @@ -670,10 +670,17 @@ Perl_do_pmop_dump(pTHX_ I32 level, PerlIO *file, const PMOP *pm) (pm->op_private & OPpRUNTIME) ? " (RUNTIME)" : ""); else Perl_dump_indent(aTHX_ level, file, "PMf_PRE (RUNTIME)\n"); - if (pm->op_type != OP_PUSHRE && pm->op_pmreplrootu.op_pmreplroot) { - Perl_dump_indent(aTHX_ level, file, "PMf_REPL = "); - op_dump(pm->op_pmreplrootu.op_pmreplroot); + + if (pm->op_type == OP_SPLIT) + Perl_dump_indent(aTHX_ level, file, "TARGOFF/GV = 0x%"UVxf"\n", + PTR2UV(pm->op_pmreplrootu.op_pmtargetgv)); + else { + if (pm->op_pmreplrootu.op_pmreplroot) { + Perl_dump_indent(aTHX_ level, file, "PMf_REPL = "); + op_dump(pm->op_pmreplrootu.op_pmreplroot); + } } + if (pm->op_code_list) { if (pm->op_pmflags & PMf_CODELIST_PRIVATE) { Perl_dump_indent(aTHX_ level, file, "CODE_LIST =\n"); @@ -1043,7 +1050,7 @@ Perl_do_op_dump(pTHX_ I32 level, PerlIO *file, const OP *o) else PerlIO_printf(file, "DONE\n"); break; - case OP_PUSHRE: + case OP_SPLIT: case OP_MATCH: case OP_QR: case OP_SUBST: @@ -1228,7 +1228,7 @@ s |void |pidgone |Pid_t pid|int status #endif : Used in perly.y p |OP* |pmruntime |NN OP *o|NN OP *expr|NULLOK OP *repl \ - |bool isreg|I32 floor + |UV flags|I32 floor #if defined(PERL_IN_OP_C) s |OP* |pmtrans |NN OP* o|NN OP* expr|NN OP* repl #endif diff --git a/ext/B/B.pm b/ext/B/B.pm index ffe97248d6..5cc253e12a 100644 --- a/ext/B/B.pm +++ b/ext/B/B.pm @@ -15,7 +15,7 @@ require Exporter; # walkoptree comes from B.xs BEGIN { - $B::VERSION = '1.63'; + $B::VERSION = '1.64'; @B::EXPORT_OK = (); # Our BOOT code needs $VERSION set, and will append to @EXPORT_OK. diff --git a/ext/B/B.xs b/ext/B/B.xs index fb42954541..0490352e9b 100644 --- a/ext/B/B.xs +++ b/ext/B/B.xs @@ -542,7 +542,7 @@ walkoptree(pTHX_ OP *o, const char *method, SV *ref) ref = walkoptree(aTHX_ kid, method, ref); } } - if (o && (cc_opclass(aTHX_ o) == OPc_PMOP) && o->op_type != OP_PUSHRE + if (o && (cc_opclass(aTHX_ o) == OPc_PMOP) && o->op_type != OP_SPLIT && (kid = PMOP_pmreplroot(cPMOPo))) { ref = walkoptree(aTHX_ kid, method, ref); @@ -1128,16 +1128,19 @@ next(o) } break; case 34: /* B::PMOP::pmreplroot */ - if (cPMOPo->op_type == OP_PUSHRE) { -#ifdef USE_ITHREADS - ret = sv_newmortal(); - sv_setiv(ret, cPMOPo->op_pmreplrootu.op_pmtargetoff); -#else - GV *const target = cPMOPo->op_pmreplrootu.op_pmtargetgv; + if (cPMOPo->op_type == OP_SPLIT) { ret = sv_newmortal(); - sv_setiv(newSVrv(ret, target ? - svclassnames[SvTYPE((SV*)target)] : "B::SV"), - PTR2IV(target)); +#ifndef USE_ITHREADS + if (o->op_private & OPpSPLIT_LEX) +#endif + sv_setiv(ret, cPMOPo->op_pmreplrootu.op_pmtargetoff); +#ifndef USE_ITHREADS + else { + GV *const target = cPMOPo->op_pmreplrootu.op_pmtargetgv; + sv_setiv(newSVrv(ret, target ? + svclassnames[SvTYPE((SV*)target)] : "B::SV"), + PTR2IV(target)); + } #endif } else { diff --git a/ext/B/B/Concise.pm b/ext/B/B/Concise.pm index 34efc2c303..f474864779 100644 --- a/ext/B/B/Concise.pm +++ b/ext/B/B/Concise.pm @@ -14,7 +14,7 @@ use warnings; # uses #3 and #4, since warnings uses Carp use Exporter (); # use #5 -our $VERSION = "0.998"; +our $VERSION = "0.999"; our @ISA = qw(Exporter); our @EXPORT_OK = qw( set_style set_style_standard add_callback concise_subref concise_cv concise_main @@ -28,6 +28,8 @@ our %EXPORT_TAGS = # use #6 use B qw(class ppname main_start main_root main_cv cstring svref_2object SVf_IOK SVf_NOK SVf_POK SVf_IVisUV SVf_FAKE OPf_KIDS OPf_SPECIAL + OPf_STACKED + OPpSPLIT_ASSIGN OPpSPLIT_LEX CVf_ANON PAD_FAKELEX_ANON PAD_FAKELEX_MULTI SVf_ROK); my %style = @@ -845,22 +847,34 @@ sub concise_op { $extra = " replstart->" . seq($op->pmreplstart); } } - elsif ($op->name eq 'pushre') { - # with C<@stash_array = split(/pat/, str);>, - # *stash_array is stored in /pat/'s pmreplroot. - my $gv = $op->pmreplroot; - if (!ref($gv)) { - # threaded: the value is actually a pad offset for where - # the GV is kept (op_pmtargetoff) - if ($gv) { - $gv = (($curcv->PADLIST->ARRAY)[1]->ARRAY)[$gv]->NAME; - } - } - else { - # unthreaded: its a GV (if it exists) - $gv = (ref($gv) eq "B::GV") ? $gv->NAME : undef; - } - $extra = " => \@$gv" if $gv; + elsif ($op->name eq 'split') { + if ( ($op->private & OPpSPLIT_ASSIGN) + && (not $op->flags & OPf_STACKED)) + { + # with C<@array = split(/pat/, str);>, + # array is stored in /pat/'s pmreplroot; either + # as an integer index into the pad (for a lexical array) + # or as GV for a package array (which will be a pad index + # on threaded builds) + + if ($op->private & $B::Op_private::defines{'OPpSPLIT_LEX'}) { + my $off = $op->pmreplroot; # union with op_pmtargetoff + $extra = " => t$off"; + } + else { + # union with op_pmtargetoff, op_pmtargetgv + my $gv = $op->pmreplroot; + if (!ref($gv)) { + # the value is actually a pad offset + $gv = (($curcv->PADLIST->ARRAY)[1]->ARRAY)[$gv]->NAME; + } + else { + # unthreaded: its a GV + $gv = $gv->NAME; + } + $extra = " => \@$gv"; + } + } } $h{arg} = "($precomp$extra)"; } elsif ($h{class} eq "PVOP" and $h{name} !~ '^transr?\z') { diff --git a/ext/B/t/b.t b/ext/B/t/b.t index 4638c3e577..a5d724912b 100644 --- a/ext/B/t/b.t +++ b/ext/B/t/b.t @@ -298,8 +298,7 @@ is(B::opnumber("pp_null"), 0, "Testing opnumber with opname (pp_null)"); is(B::class(bless {}, "Wibble::Bibble"), "Bibble", "Testing B::class()"); is(B::cast_I32(3.14), 3, "Testing B::cast_I32()"); -is(B::opnumber("chop"), $] >= 5.015 ? 39 : 38, - "Testing opnumber with opname (chop)"); +is(B::opnumber("chop"), 38, "Testing opnumber with opname (chop)"); { no warnings 'once'; diff --git a/ext/B/t/optree_concise.t b/ext/B/t/optree_concise.t index 12781acdb8..1e2594703f 100644 --- a/ext/B/t/optree_concise.t +++ b/ext/B/t/optree_concise.t @@ -183,13 +183,13 @@ checkOptree ( name => "terse basic", UNOP (0x82b0918) leavesub [1] LISTOP (0x82b08d8) lineseq COP (0x82b0880) nextstate - UNOP (0x82b0860) null [15] + UNOP (0x82b0860) null [14] 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 [14] # SVOP (0x812fc00) gvsv GV (0x814692c) *a EONT_EONT diff --git a/ext/B/t/walkoptree.t b/ext/B/t/walkoptree.t index 3648835b7f..1d42dd5140 100644 --- a/ext/B/t/walkoptree.t +++ b/ext/B/t/walkoptree.t @@ -36,13 +36,13 @@ my $victim = sub { $_[0] =~ s/(a)/ $1/; # PMOP_pmreplroot(cPMOPo) is NULL for this $_[0] =~ s/(b)//; - # This gives an OP_PUSHRE + # This gives an OP_SPLIT split /c/; }; is (B::walkoptree_debug, 0, 'walkoptree_debug() is 0'); B::walkoptree(B::svref_2object($victim)->ROOT, "pie"); -foreach (qw(substcont pushre split leavesub)) { +foreach (qw(substcont split split leavesub)) { is ($seen{$_}, 1, "Our victim had a $_ OP"); } is_deeply ([keys %debug], [], 'walkoptree_debug was not called'); @@ -52,7 +52,7 @@ is (B::walkoptree_debug, 1, 'walkoptree_debug() is 1'); %seen = (); B::walkoptree(B::svref_2object($victim)->ROOT, "pie"); -foreach (qw(substcont pushre split leavesub)) { +foreach (qw(substcont split split leavesub)) { is ($seen{$_}, 1, "Our victim had a $_ OP"); } is_deeply (\%debug, \%seen, 'walkoptree_debug was called correctly'); diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm index 912aa4dfee..1b9f95f6e8 100644 --- a/ext/Opcode/Opcode.pm +++ b/ext/Opcode/Opcode.pm @@ -6,7 +6,7 @@ use strict; our($VERSION, @ISA, @EXPORT_OK); -$VERSION = "1.37"; +$VERSION = "1.38"; use Carp; use Exporter (); @@ -409,7 +409,7 @@ These are a hotchpotch of opcodes still waiting to be considered bless -- could be used to change ownership of objects (reblessing) - pushre regcmaybe regcreset regcomp subst substcont + regcmaybe regcreset regcomp subst substcont sprintf prtf -- can core dump diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm index 5254f86d66..fb4a7d9fee 100644 --- a/lib/B/Deparse.pm +++ b/lib/B/Deparse.pm @@ -16,6 +16,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY OPpEXISTS_SUB OPpSORT_NUMERIC OPpSORT_INTEGER OPpREPEAT_DOLIST OPpSORT_REVERSE OPpMULTIDEREF_EXISTS OPpMULTIDEREF_DELETE + OPpSPLIT_ASSIGN OPpSPLIT_LEX SVf_IOK SVf_NOK SVf_ROK SVf_POK SVpad_OUR SVf_FAKE SVs_RMG SVs_SMG SVs_PADTMP SVpad_TYPED CVf_METHOD CVf_LVALUE @@ -46,7 +47,7 @@ use B qw(class main_root main_start main_cv svref_2object opnumber perlstring MDEREF_SHIFT ); -$VERSION = '1.38'; +$VERSION = '1.39'; use strict; use vars qw/$AUTOLOAD/; use warnings (); @@ -5630,7 +5631,7 @@ sub matchop { my($op, $cx, $name, $delim) = @_; my $kid = $op->first; my ($binop, $var, $re) = ("", "", ""); - if ($op->flags & OPf_STACKED) { + if ($op->name ne 'split' && $op->flags & OPf_STACKED) { $binop = 1; $var = $self->deparse($kid, 20); $kid = $kid->sibling; @@ -5669,7 +5670,13 @@ sub matchop { } elsif (!$have_kid) { $re = re_uninterp(escape_re(re_unback($op->precomp))); } elsif ($kid->name ne 'regcomp') { - carp("found ".$kid->name." where regcomp expected"); + if ($op->name eq 'split') { + # split has other kids, not just regcomp + $re = re_uninterp(escape_re(re_unback($op->precomp))); + } + else { + carp("found ".$kid->name." where regcomp expected"); + } } else { ($re, $quote) = $self->regcomp($kid, 21); } @@ -5709,64 +5716,55 @@ sub matchop { } sub pp_match { matchop(@_, "m", "/") } -sub pp_pushre { matchop(@_, "m", "/") } sub pp_qr { matchop(@_, "qr", "") } sub pp_runcv { unop(@_, "__SUB__"); } sub pp_split { - maybe_targmy(@_, \&split); -} -sub split { my $self = shift; my($op, $cx) = @_; my($kid, @exprs, $ary, $expr); + my $stacked = $op->flags & OPf_STACKED; + $kid = $op->first; + $kid = $kid->sibling if $kid->name eq 'regcomp'; + for (; !null($kid); $kid = $kid->sibling) { + push @exprs, $self->deparse($kid, 6); + } - # For our kid (an OP_PUSHRE), pmreplroot is never actually the - # root of a replacement; it's either empty, or abused to point to - # the GV for an array we split into (an optimization to save - # assignment overhead). Depending on whether we're using ithreads, - # this OP* holds either a GV* or a PADOFFSET. Luckily, B.xs - # figures out for us which it is. - my $replroot = $kid->pmreplroot; - my $gv = 0; - my $stacked = $op->flags & OPf_STACKED; - if (ref($replroot) eq "B::GV") { - $gv = $replroot; - } elsif (!ref($replroot) and $replroot > 0) { - $gv = $self->padval($replroot); - } elsif ($kid->targ) { - $ary = $self->padname($kid->targ) - } elsif ($stacked) { - $ary = $self->deparse($op->last, 7); - } - $ary = $self->maybe_local(@_, + unshift @exprs, $self->matchop($op, $cx, "m", "/"); + + if ($op->private & OPpSPLIT_ASSIGN) { + # With C<@array = split(/pat/, str);>, + # array is stored in split's pmreplroot; either + # as an integer index into the pad (for a lexical array) + # or as GV for a package array (which will be a pad index + # on threaded builds) + # With my/our @array = split(/pat/, str), the array is instead + # accessed via an extra padav/rv2av op at the end of the + # split's kid ops. + + if ($stacked) { + $ary = pop @exprs; + } + else { + if ($op->private & OPpSPLIT_LEX) { + $ary = $self->padname($op->pmreplroot); + } + else { + # union with op_pmtargetoff, op_pmtargetgv + my $gv = $op->pmreplroot; + $gv = $self->padval($gv) if !ref($gv); + $ary = $self->maybe_local(@_, $self->stash_variable('@', $self->gv_name($gv), $cx)) - if $gv; - - # Skip the last kid when OPf_STACKED is set, since it is the array - # on the left. - for (; !null($stacked ? $kid->sibling : $kid); $kid = $kid->sibling) { - push @exprs, $self->deparse($kid, 6); + } + } } # handle special case of split(), and split(' ') that compiles to /\s+/ - # Under 5.10, the reflags may be undef if the split regexp isn't a constant - # Under 5.17.5-5.17.9, the special flag is on split itself. - $kid = $op->first; - if ( $op->flags & OPf_SPECIAL - or ( - $kid->flags & OPf_SPECIAL - and ( $] < 5.009 ? $kid->pmflags & PMf_SKIPWHITE() - : ($kid->reflags || 0) & RXf_SKIPWHITE() - ) - ) - ) { - $exprs[0] = "' '"; - } + $exprs[0] = q{' '} if ($op->reflags // 0) & RXf_SKIPWHITE(); $expr = "split(" . join(", ", @exprs) . ")"; if ($ary) { diff --git a/lib/B/Deparse.t b/lib/B/Deparse.t index 7d65d74581..c378fec15a 100644 --- a/lib/B/Deparse.t +++ b/lib/B/Deparse.t @@ -785,12 +785,38 @@ print $_ foreach (reverse 1, 2..5); our @ary; @ary = split(' ', 'foo', 0); #### +my @ary; +@ary = split(' ', 'foo', 0); +#### # Split to our array our @array = split(//, 'foo', 0); #### # Split to my array my @array = split(//, 'foo', 0); #### +our @array; +my $c; +@array = split(/x(?{ $c++; })y/, 'foo', 0); +#### +my($x, $y, $p); +our $c; +($x, $y) = split(/$p(?{ $c++; })y/, 'foo', 2); +#### +our @ary; +my $pat; +@ary = split(/$pat/, 'foo', 0); +#### +my @ary; +our $pat; +@ary = split(/$pat/, 'foo', 0); +#### +our @array; +my $pat; +local @array = split(/$pat/, 'foo', 0); +#### +our $pat; +my @array = split(/$pat/, 'foo', 0); +#### # bug #40055 do { () }; #### diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm index 8a25ec6763..1732b04f63 100644 --- a/lib/B/Op_private.pm +++ b/lib/B/Op_private.pm @@ -147,7 +147,7 @@ $bits{$_}{6} = 'OPpOUR_INTRO' for qw(enteriter gvsv rv2av rv2hv rv2sv split); $bits{$_}{6} = 'OPpPAD_STATE' for qw(lvavref lvref padav padhv padsv pushmark refassign); $bits{$_}{7} = 'OPpPV_IS_UTF8' for qw(dump goto last next redo); $bits{$_}{6} = 'OPpREFCOUNTED' for qw(leave leaveeval leavesub leavesublv leavewrite); -$bits{$_}{6} = 'OPpRUNTIME' for qw(match pushre qr subst substcont); +$bits{$_}{5} = 'OPpRUNTIME' for qw(match qr split subst substcont); $bits{$_}{2} = 'OPpSLICEWARNING' for qw(aslice hslice padav padhv rv2av rv2hv); $bits{$_}{4} = 'OPpTARGET_MY' for qw(abs add atan2 chdir chmod chomp chown chr chroot concat cos crypt divide exec exp flock getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_subtract index int kill left_shift length link log mkdir modulo multiply nbit_and nbit_or nbit_xor ncomplement oct ord pow push rand rename right_shift rindex rmdir schomp scomplement setpgrp setpriority sin sleep sqrt srand stringify subtract symlink system time unlink unshift utime wait waitpid); $bits{$_}{5} = 'OPpTRANS_COMPLEMENT' for qw(trans transr); @@ -538,7 +538,7 @@ $bits{snetent}{0} = $bf[0]; @{$bits{sockpair}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); @{$bits{sort}}{6,5,4,3,2,1,0} = ('OPpSORT_STABLE', 'OPpSORT_QSORT', 'OPpSORT_DESCEND', 'OPpSORT_INPLACE', 'OPpSORT_REVERSE', 'OPpSORT_INTEGER', 'OPpSORT_NUMERIC'); @{$bits{splice}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); -$bits{split}{7} = 'OPpSPLIT_IMPLIM'; +@{$bits{split}}{7,4,3} = ('OPpSPLIT_IMPLIM', 'OPpSPLIT_ASSIGN', 'OPpSPLIT_LEX'); @{$bits{sprintf}}{3,2,1,0} = ($bf[4], $bf[4], $bf[4], $bf[4]); $bits{sprotoent}{0} = $bf[0]; $bits{sqrt}{0} = $bf[0]; @@ -661,7 +661,7 @@ our %defines = ( OPpREFCOUNTED => 64, OPpREPEAT_DOLIST => 64, OPpREVERSE_INPLACE => 8, - OPpRUNTIME => 64, + OPpRUNTIME => 32, OPpSLICE => 64, OPpSLICEWARNING => 4, OPpSORT_DESCEND => 16, @@ -671,7 +671,9 @@ our %defines = ( OPpSORT_QSORT => 32, OPpSORT_REVERSE => 4, OPpSORT_STABLE => 64, + OPpSPLIT_ASSIGN => 16, OPpSPLIT_IMPLIM => 128, + OPpSPLIT_LEX => 8, OPpSUBSTR_REPL_FIRST => 16, OPpTARGET_MY => 16, OPpTRANS_COMPLEMENT => 32, @@ -764,7 +766,9 @@ our %labels = ( OPpSORT_QSORT => 'QSORT', OPpSORT_REVERSE => 'REV', OPpSORT_STABLE => 'STABLE', + OPpSPLIT_ASSIGN => 'ASSIGN', OPpSPLIT_IMPLIM => 'IMPLIM', + OPpSPLIT_LEX => 'LEX', OPpSUBSTR_REPL_FIRST => 'REPL1ST', OPpTARGET_MY => 'TARGMY', OPpTRANS_COMPLEMENT => 'COMPL', @@ -813,11 +817,11 @@ our %ops_using = ( OPpREFCOUNTED => [qw(leave leaveeval leavesub leavesublv leavewrite)], OPpREPEAT_DOLIST => [qw(repeat)], OPpREVERSE_INPLACE => [qw(reverse)], - OPpRUNTIME => [qw(match pushre qr subst substcont)], + OPpRUNTIME => [qw(match qr split subst substcont)], OPpSLICE => [qw(delete)], OPpSLICEWARNING => [qw(aslice hslice padav padhv rv2av rv2hv)], OPpSORT_DESCEND => [qw(sort)], - OPpSPLIT_IMPLIM => [qw(split)], + OPpSPLIT_ASSIGN => [qw(split)], OPpSUBSTR_REPL_FIRST => [qw(substr)], OPpTARGET_MY => [qw(abs add atan2 chdir chmod chomp chown chr chroot concat cos crypt divide exec exp flock getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_subtract index int kill left_shift length link log mkdir modulo multiply nbit_and nbit_or nbit_xor ncomplement oct ord pow push rand rename right_shift rindex rmdir schomp scomplement setpgrp setpriority sin sleep sqrt srand stringify subtract symlink system time unlink unshift utime wait waitpid)], OPpTRANS_COMPLEMENT => [qw(trans transr)], @@ -854,6 +858,8 @@ $ops_using{OPpSORT_NUMERIC} = $ops_using{OPpSORT_DESCEND}; $ops_using{OPpSORT_QSORT} = $ops_using{OPpSORT_DESCEND}; $ops_using{OPpSORT_REVERSE} = $ops_using{OPpSORT_DESCEND}; $ops_using{OPpSORT_STABLE} = $ops_using{OPpSORT_DESCEND}; +$ops_using{OPpSPLIT_IMPLIM} = $ops_using{OPpSPLIT_ASSIGN}; +$ops_using{OPpSPLIT_LEX} = $ops_using{OPpSPLIT_ASSIGN}; $ops_using{OPpTRANS_DELETE} = $ops_using{OPpTRANS_COMPLEMENT}; $ops_using{OPpTRANS_FROM_UTF} = $ops_using{OPpTRANS_COMPLEMENT}; $ops_using{OPpTRANS_GROWS} = $ops_using{OPpTRANS_COMPLEMENT}; @@ -1015,14 +1015,20 @@ Perl_op_clear(pTHX_ OP *o) case OP_SUBST: op_free(cPMOPo->op_pmreplrootu.op_pmreplroot); goto clear_pmop; - case OP_PUSHRE: + + case OP_SPLIT: + if ( (o->op_private & OPpSPLIT_ASSIGN) + && !(o->op_flags & OPf_STACKED)) + { + if (o->op_private & OPpSPLIT_LEX) + pad_free(cPMOPo->op_pmreplrootu.op_pmtargetoff); + else #ifdef USE_ITHREADS - if (cPMOPo->op_pmreplrootu.op_pmtargetoff) { - pad_swipe(cPMOPo->op_pmreplrootu.op_pmtargetoff, TRUE); - } + pad_swipe(cPMOPo->op_pmreplrootu.op_pmtargetoff, TRUE); #else - SvREFCNT_dec(MUTABLE_SV(cPMOPo->op_pmreplrootu.op_pmtargetgv)); + SvREFCNT_dec(MUTABLE_SV(cPMOPo->op_pmreplrootu.op_pmtargetgv)); #endif + } /* FALLTHROUGH */ case OP_MATCH: case OP_QR: @@ -1226,7 +1232,7 @@ S_find_and_forget_pmops(pTHX_ OP *o) while (kid) { switch (kid->op_type) { case OP_SUBST: - case OP_PUSHRE: + case OP_SPLIT: case OP_MATCH: case OP_QR: forget_pmop((PMOP*)kid); @@ -1992,16 +1998,7 @@ Perl_scalarvoid(pTHX_ OP *arg) break; case OP_SPLIT: - kid = cLISTOPo->op_first; - if (kid && kid->op_type == OP_PUSHRE - && !kid->op_targ - && !(o->op_flags & OPf_STACKED) -#ifdef USE_ITHREADS - && !((PMOP*)kid)->op_pmreplrootu.op_pmtargetoff -#else - && !((PMOP*)kid)->op_pmreplrootu.op_pmtargetgv -#endif - ) + if (!(o->op_private & OPpSPLIT_ASSIGN)) useless = OP_DESC(o); break; @@ -3238,16 +3235,7 @@ Perl_op_lvalue_flags(pTHX_ OP *o, I32 type, U32 flags) return o; case OP_SPLIT: - kid = cLISTOPo->op_first; - if (kid && kid->op_type == OP_PUSHRE && - ( kid->op_targ - || o->op_flags & OPf_STACKED -#ifdef USE_ITHREADS - || ((PMOP*)kid)->op_pmreplrootu.op_pmtargetoff -#else - || ((PMOP*)kid)->op_pmreplrootu.op_pmtargetgv -#endif - )) { + if ((o->op_private & OPpSPLIT_ASSIGN)) { /* This is actually @array = split. */ PL_modcount = RETURN_UNLIMITED_NUMBER; break; @@ -4772,7 +4760,13 @@ Perl_op_convert_list(pTHX_ I32 type, I32 flags, OP *o) } } - OpTYPE_set(o, type); + if (type != OP_SPLIT) + /* At this point o is a LISTOP, but OP_SPLIT is a PMOP; let + * ck_split() create a real PMOP and leave the op's type as listop + * for for now. Otherwise op_free() etc will crash. + */ + OpTYPE_set(o, type); + o->op_flags |= flags; if (flags & OPf_FOLDED) o->op_folded = 1; @@ -5600,10 +5594,12 @@ S_set_haseval(pTHX) * constant), or convert expr into a runtime regcomp op sequence (if it's * not) * - * isreg indicates that the pattern is part of a regex construct, eg + * Flags currently has 2 bits or meaning: + * 1: isreg indicates that the pattern is part of a regex construct, eg * $x =~ /pattern/ or split /pattern/, as opposed to $x =~ $pattern or * split "pattern", which aren't. In the former case, expr will be a list * if the pattern contains more than one term (eg /a$b/). + * 2: The pattern is for a split. * * When the pattern has been compiled within a new anon CV (for * qr/(?{...})/ ), then floor indicates the savestack level just before @@ -5611,7 +5607,7 @@ S_set_haseval(pTHX) */ OP * -Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, bool isreg, I32 floor) +Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor) { PMOP *pm; LOGOP *rcop; @@ -5619,6 +5615,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, bool isreg, I32 floor) bool is_trans = (o->op_type == OP_TRANS || o->op_type == OP_TRANSR); bool is_compiletime; bool has_code; + bool isreg = cBOOL(flags & 1); + bool is_split = cBOOL(flags & 2); PERL_ARGS_ASSERT_PMRUNTIME; @@ -5723,8 +5721,11 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, bool isreg, I32 floor) U32 rx_flags = pm->op_pmflags & RXf_PMf_COMPILETIME; regexp_engine const *eng = current_re_engine(); - if (o->op_flags & OPf_SPECIAL) + if (is_split) { + /* make engine handle split ' ' specially */ + pm->op_pmflags |= PMf_SPLIT; rx_flags |= RXf_SPLIT; + } if (!has_code || !eng->op_comp) { /* compile-time simple constant pattern */ @@ -5813,7 +5814,8 @@ Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, bool isreg, I32 floor) pm->op_pmflags |= PMf_CODELIST_PRIVATE; } - if (o->op_flags & OPf_SPECIAL) + if (is_split) + /* make engine handle split ' ' specially */ pm->op_pmflags |= PMf_SPLIT; /* the OP_REGCMAYBE is a placeholder in the non-threaded case @@ -6565,48 +6567,57 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) yyerror(no_list_state); } - if (right && right->op_type == OP_SPLIT - && !(right->op_flags & OPf_STACKED)) { - OP* tmpop = ((LISTOP*)right)->op_first; - PMOP * const pm = (PMOP*)tmpop; - assert (tmpop && (tmpop->op_type == OP_PUSHRE)); - if ( -#ifdef USE_ITHREADS - !pm->op_pmreplrootu.op_pmtargetoff -#else - !pm->op_pmreplrootu.op_pmtargetgv -#endif - && !pm->op_targ - ) { + /* optimise @a = split(...) into: + * local/my @a: split(..., @a), where @a is not flattened + * other arrays: split(...) where @a is attached to + * the split op itself + */ + + if ( right + && right->op_type == OP_SPLIT + /* don't do twice, e.g. @b = (@a = split) */ + && !(right->op_private & OPpSPLIT_ASSIGN)) + { + OP *gvop = NULL; + if (!(left->op_private & OPpLVAL_INTRO) && ( (left->op_type == OP_RV2AV && - (tmpop=((UNOP*)left)->op_first)->op_type==OP_GV) + (gvop=((UNOP*)left)->op_first)->op_type==OP_GV) || left->op_type == OP_PADAV ) - ) { - if (tmpop != (OP *)pm) { + ) + { + /* @pkg or @lex, but not 'local @pkg' nor 'my @lex' */ + OP *tmpop; + PMOP * const pm = (PMOP*)right; + if (gvop) { #ifdef USE_ITHREADS - pm->op_pmreplrootu.op_pmtargetoff - = cPADOPx(tmpop)->op_padix; - cPADOPx(tmpop)->op_padix = 0; /* steal it */ + pm->op_pmreplrootu.op_pmtargetoff + = cPADOPx(gvop)->op_padix; + cPADOPx(gvop)->op_padix = 0; /* steal it */ #else - pm->op_pmreplrootu.op_pmtargetgv - = MUTABLE_GV(cSVOPx(tmpop)->op_sv); - cSVOPx(tmpop)->op_sv = NULL; /* steal it */ + pm->op_pmreplrootu.op_pmtargetgv + = MUTABLE_GV(cSVOPx(gvop)->op_sv); + cSVOPx(gvop)->op_sv = NULL; /* steal it */ #endif - right->op_private |= - left->op_private & OPpOUR_INTRO; + right->op_private |= + left->op_private & OPpOUR_INTRO; } else { - pm->op_targ = left->op_targ; - left->op_targ = 0; /* filch it */ + pm->op_pmreplrootu.op_pmtargetoff = left->op_targ; + left->op_targ = 0; /* steal it */ + right->op_private |= OPpSPLIT_LEX; } + detach_split: tmpop = cUNOPo->op_first; /* to list (nulled) */ tmpop = ((UNOP*)tmpop)->op_first; /* to pushmark */ - /* detach rest of siblings from o subtree, - * and free subtree */ - op_sibling_splice(cUNOPo->op_first, tmpop, -1, NULL); + assert(OpSIBLING(tmpop) == right); + assert(!OpHAS_SIBLING(right)); + /* detach the split subtreee from the o tree, + * then free the residual o tree */ + op_sibling_splice(cUNOPo->op_first, tmpop, 1, NULL); op_free(o); /* blow off assign */ + right->op_private |= OPpSPLIT_ASSIGN; right->op_flags &= ~OPf_WANT; /* "I don't know and I don't care." */ return right; @@ -6614,15 +6625,13 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) else if (left->op_type == OP_RV2AV || left->op_type == OP_PADAV) { - /* Detach the array. */ -#ifdef DEBUGGING - OP * const ary = -#endif - op_sibling_splice(cBINOPo->op_last, - cUNOPx(cBINOPo->op_last) - ->op_first, 1, NULL); - assert(ary == left); - /* Attach it to the split. */ + /* 'local @pkg' or 'my @lex' */ + + OP *pushop = cUNOPx(cBINOPo->op_last)->op_first; + assert(OpSIBLING(pushop) == left); + /* Detach the array ... */ + op_sibling_splice(cBINOPo->op_last, pushop, 1, NULL); + /* ... and attach it to the split. */ op_sibling_splice(right, cLISTOPx(right)->op_last, 0, left); right->op_flags |= OPf_STACKED; @@ -6632,6 +6641,7 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) else if (PL_modcount < RETURN_UNLIMITED_NUMBER && ((LISTOP*)right)->op_last->op_type == OP_CONST) { + /* convert split(...,0) to split(..., PL_modcount+1) */ SV ** const svp = &((SVOP*)((LISTOP*)right)->op_last)->op_sv; SV * const sv = *svp; @@ -6649,7 +6659,6 @@ Perl_newASSIGNOP(pTHX_ I32 flags, OP *left, I32 optype, OP *right) } } } - } } return o; } @@ -11127,52 +11136,76 @@ Perl_ck_split(pTHX_ OP *o) { dVAR; OP *kid; + OP *sibs; PERL_ARGS_ASSERT_CK_SPLIT; + assert(o->op_type == OP_LIST); + if (o->op_flags & OPf_STACKED) return no_fh_allowed(o); kid = cLISTOPo->op_first; - if (kid->op_type != OP_NULL) - Perl_croak(aTHX_ "panic: ck_split, type=%u", (unsigned) kid->op_type); /* delete leading NULL node, then add a CONST if no other nodes */ + assert(kid->op_type == OP_NULL); op_sibling_splice(o, NULL, 1, OpHAS_SIBLING(kid) ? NULL : newSVOP(OP_CONST, 0, newSVpvs(" "))); op_free(kid); kid = cLISTOPo->op_first; if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) { - /* remove kid, and replace with new optree */ + /* remove match expression, and replace with new optree with + * a match op at its head */ op_sibling_splice(o, NULL, 1, NULL); - /* OPf_SPECIAL is used to trigger split " " behavior */ - kid = pmruntime( newPMOP(OP_MATCH, OPf_SPECIAL), kid, NULL, 0, 0); + /* pmruntime will handle split " " behavior with flag==2 */ + kid = pmruntime(newPMOP(OP_MATCH, 0), kid, NULL, 2, 0); op_sibling_splice(o, NULL, 0, kid); } - OpTYPE_set(kid, OP_PUSHRE); - /* target implies @ary=..., so wipe it */ - kid->op_targ = 0; - scalar(kid); + + assert(kid->op_type == OP_MATCH || kid->op_type == OP_SPLIT); + if (((PMOP *)kid)->op_pmflags & PMf_GLOBAL) { Perl_ck_warner(aTHX_ packWARN(WARN_REGEXP), "Use of /g modifier is meaningless in split"); } - if (!OpHAS_SIBLING(kid)) - op_append_elem(OP_SPLIT, o, newDEFSVOP()); + /* eliminate the split op, and move the match op (plus any children) + * into its place, then convert the match op into a split op. i.e. + * + * SPLIT MATCH SPLIT(ex-MATCH) + * | | | + * MATCH - A - B - C => R - A - B - C => R - A - B - C + * | | | + * R X - Y X - Y + * | + * X - Y + * + * (R, if it exists, will be a regcomp op) + */ - kid = OpSIBLING(kid); - assert(kid); - scalar(kid); + op_sibling_splice(o, NULL, 1, NULL); /* detach match op from o */ + sibs = op_sibling_splice(o, NULL, -1, NULL); /* detach any other sibs */ + op_sibling_splice(kid, cLISTOPx(kid)->op_last, 0, sibs); /* and reattach */ + OpTYPE_set(kid, OP_SPLIT); + kid->op_flags = (o->op_flags | (kid->op_flags & OPf_KIDS)); + assert(!(kid->op_private & ~OPpRUNTIME)); + kid->op_private = (o->op_private | (kid->op_private & OPpRUNTIME)); + op_free(o); + o = kid; + kid = sibs; /* kid is now the string arg of the split */ - if (!OpHAS_SIBLING(kid)) - { - op_append_elem(OP_SPLIT, o, newSVOP(OP_CONST, 0, newSViv(0))); - o->op_private |= OPpSPLIT_IMPLIM; + if (!kid) { + kid = newDEFSVOP(); + op_append_elem(OP_SPLIT, o, kid); } - assert(OpHAS_SIBLING(kid)); + scalar(kid); kid = OpSIBLING(kid); + if (!kid) { + kid = newSVOP(OP_CONST, 0, newSViv(0)); + op_append_elem(OP_SPLIT, o, kid); + o->op_private |= OPpSPLIT_IMPLIM; + } scalar(kid); if (OpHAS_SIBLING(kid)) @@ -12523,7 +12556,9 @@ S_aassign_scan(pTHX_ OP* o, bool rhs, bool top, int *scalars_p) return AAS_PKG_SCALAR; /* $pkg */ case OP_SPLIT: + if (1) { /* XXX this condition is wrong - fix later if (cLISTOPo->op_first->op_type == OP_PUSHRE) { + */ /* "@foo = split... " optimises away the aassign and stores its * destination array in the OP_PUSHRE that precedes it. * A flattened array is always dangerous. @@ -123,7 +123,6 @@ Deprecated. Use C<GIMME_V> instead. /* On OP_NULL, saw a "do". */ /* On OP_EXISTS, treat av as av, not avhv. */ /* On OP_(ENTER|LEAVE)EVAL, don't clear $@ */ - /* On pushre, rx is used as part of split, e.g. split " " */ /* On regcomp, "use re 'eval'" was in scope */ /* On RV2[ACGHS]V, don't create GV--in defined()*/ @@ -261,11 +260,8 @@ struct pmop { U32 op_pmflags; union { OP * op_pmreplroot; /* For OP_SUBST */ -#ifdef USE_ITHREADS - PADOFFSET op_pmtargetoff; /* For OP_PUSHRE */ -#else - GV * op_pmtargetgv; -#endif + PADOFFSET op_pmtargetoff; /* For OP_SPLIT lex ary or thr GV */ + GV * op_pmtargetgv; /* For OP_SPLIT non-threaded GV */ } op_pmreplrootu; union { OP * op_pmreplstart; /* Only used in OP_SUBST */ @@ -159,7 +159,6 @@ EXTCONST char* const PL_op_name[] = { "padav", "padhv", "padany", - "pushre", "rv2gv", "rv2sv", "av2arylen", @@ -564,7 +563,6 @@ EXTCONST char* const PL_op_desc[] = { "private array", "private hash", "private value", - "push regexp", "ref-to-glob cast", "scalar dereference", "array length", @@ -983,7 +981,6 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */ Perl_pp_padav, Perl_pp_padhv, Perl_pp_padany, /* implemented by Perl_unimplemented_op */ - Perl_pp_pushre, Perl_pp_rv2gv, Perl_pp_rv2sv, Perl_pp_av2arylen, @@ -1398,7 +1395,6 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */ Perl_ck_null, /* padav */ Perl_ck_null, /* padhv */ Perl_ck_null, /* padany */ - Perl_ck_null, /* pushre */ Perl_ck_rvconst, /* rv2gv */ Perl_ck_rvconst, /* rv2sv */ Perl_ck_null, /* av2arylen */ @@ -1807,7 +1803,6 @@ EXTCONST U32 PL_opargs[] = { 0x00000040, /* padav */ 0x00000040, /* padhv */ 0x00000040, /* padany */ - 0x00000540, /* pushre */ 0x00000144, /* rv2gv */ 0x00000144, /* rv2sv */ 0x00000104, /* av2arylen */ @@ -1950,7 +1945,7 @@ EXTCONST U32 PL_opargs[] = { 0x00000f44, /* multideref */ 0x00091480, /* unpack */ 0x0002140f, /* pack */ - 0x00111408, /* split */ + 0x00111508, /* split */ 0x0002140f, /* join */ 0x00002401, /* list */ 0x00224200, /* lslice */ @@ -2239,6 +2234,7 @@ END_EXTERN_C #define OPpMAYBE_LVSUB 0x08 #define OPpREVERSE_INPLACE 0x08 #define OPpSORT_INPLACE 0x08 +#define OPpSPLIT_LEX 0x08 #define OPpTRANS_SQUASH 0x08 #define OPpARG4_MASK 0x0f #define OPpASSIGN_COMMON_AGG 0x10 @@ -2251,6 +2247,7 @@ END_EXTERN_C #define OPpMULTIDEREF_EXISTS 0x10 #define OPpOPEN_IN_RAW 0x10 #define OPpSORT_DESCEND 0x10 +#define OPpSPLIT_ASSIGN 0x10 #define OPpSUBSTR_REPL_FIRST 0x10 #define OPpTARGET_MY 0x10 #define OPpASSIGN_COMMON_RC1 0x20 @@ -2262,6 +2259,7 @@ END_EXTERN_C #define OPpMAY_RETURN_CONSTANT 0x20 #define OPpMULTIDEREF_DELETE 0x20 #define OPpOPEN_IN_CRLF 0x20 +#define OPpRUNTIME 0x20 #define OPpSORT_QSORT 0x20 #define OPpTRANS_COMPLEMENT 0x20 #define OPpTRUEBOOL 0x20 @@ -2284,7 +2282,6 @@ END_EXTERN_C #define OPpPAD_STATE 0x40 #define OPpREFCOUNTED 0x40 #define OPpREPEAT_DOLIST 0x40 -#define OPpRUNTIME 0x40 #define OPpSLICE 0x40 #define OPpSORT_STABLE 0x40 #define OPpTRANS_GROWS 0x40 @@ -2328,6 +2325,7 @@ EXTCONST char PL_op_private_labels[] = { '<','U','T','F','\0', '>','U','T','F','\0', 'A','M','P','E','R','\0', + 'A','S','S','I','G','N','\0', 'A','V','\0', 'B','A','R','E','\0', 'B','K','W','A','R','D','\0', @@ -2375,6 +2373,7 @@ EXTCONST char PL_op_private_labels[] = { 'I','N','P','L','A','C','E','\0', 'I','N','T','\0', 'I','T','E','R','\0', + 'L','E','X','\0', 'L','I','N','E','N','U','M','\0', 'L','V','\0', 'L','V','D','E','F','E','R','\0', @@ -2429,14 +2428,14 @@ EXTCONST char PL_op_private_labels[] = { EXTCONST I16 PL_op_private_bitfields[] = { 0, 8, -1, 0, 8, -1, - 0, 534, -1, + 0, 545, -1, 0, 8, -1, 0, 8, -1, + 0, 552, -1, 0, 541, -1, - 0, 530, -1, - 1, -1, 0, 507, 1, 26, 2, 276, -1, - 4, -1, 1, 157, 2, 164, 3, 171, -1, - 4, -1, 0, 507, 1, 26, 2, 276, 3, 103, -1, + 1, -1, 0, 518, 1, 33, 2, 283, -1, + 4, -1, 1, 164, 2, 171, 3, 178, -1, + 4, -1, 0, 518, 1, 33, 2, 283, 3, 110, -1, }; @@ -2458,27 +2457,26 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 16, /* padav */ 20, /* padhv */ -1, /* padany */ - 26, /* pushre */ - 27, /* rv2gv */ - 34, /* rv2sv */ - 39, /* av2arylen */ - 41, /* rv2cv */ + 26, /* rv2gv */ + 33, /* rv2sv */ + 38, /* av2arylen */ + 40, /* rv2cv */ -1, /* anoncode */ 0, /* prototype */ 0, /* refgen */ 0, /* srefgen */ 0, /* ref */ - 48, /* bless */ - 49, /* backtick */ - 48, /* glob */ + 47, /* bless */ + 48, /* backtick */ + 47, /* glob */ 0, /* readline */ -1, /* rcatline */ 0, /* regcmaybe */ 0, /* regcreset */ 0, /* regcomp */ - 26, /* match */ - 26, /* qr */ - 26, /* subst */ + 53, /* match */ + 53, /* qr */ + 53, /* subst */ 54, /* substcont */ 56, /* trans */ 56, /* transr */ @@ -2491,7 +2489,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* defined */ 0, /* undef */ 0, /* study */ - 39, /* pos */ + 38, /* pos */ 0, /* preinc */ 0, /* i_preinc */ 0, /* predec */ @@ -2570,8 +2568,8 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 82, /* vec */ 77, /* index */ 77, /* rindex */ - 48, /* sprintf */ - 48, /* formline */ + 47, /* sprintf */ + 47, /* formline */ 71, /* ord */ 71, /* chr */ 77, /* crypt */ @@ -2588,10 +2586,10 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 99, /* kvaslice */ 0, /* aeach */ 0, /* avalues */ - 39, /* akeys */ + 38, /* akeys */ 0, /* each */ 0, /* values */ - 39, /* keys */ + 38, /* keys */ 100, /* delete */ 103, /* exists */ 105, /* rv2hv */ @@ -2599,65 +2597,65 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 96, /* hslice */ 99, /* kvhslice */ 113, /* multideref */ - 48, /* unpack */ - 48, /* pack */ + 47, /* unpack */ + 47, /* pack */ 120, /* split */ - 48, /* join */ - 122, /* list */ + 47, /* join */ + 125, /* list */ 12, /* lslice */ - 48, /* anonlist */ - 48, /* anonhash */ - 48, /* splice */ + 47, /* anonlist */ + 47, /* anonhash */ + 47, /* splice */ 77, /* push */ 0, /* pop */ 0, /* shift */ 77, /* unshift */ - 124, /* sort */ - 131, /* reverse */ + 127, /* sort */ + 134, /* reverse */ 0, /* grepstart */ 0, /* grepwhile */ 0, /* mapstart */ 0, /* mapwhile */ 0, /* range */ - 133, /* flip */ - 133, /* flop */ + 136, /* flip */ + 136, /* flop */ 0, /* and */ 0, /* or */ 12, /* xor */ 0, /* dor */ - 135, /* cond_expr */ + 138, /* cond_expr */ 0, /* andassign */ 0, /* orassign */ 0, /* dorassign */ 0, /* method */ - 137, /* entersub */ - 144, /* leavesub */ - 144, /* leavesublv */ + 140, /* entersub */ + 147, /* leavesub */ + 147, /* leavesublv */ 0, /* argcheck */ - 146, /* argelem */ + 149, /* argelem */ 0, /* argdefelem */ - 148, /* caller */ - 48, /* warn */ - 48, /* die */ - 48, /* reset */ + 151, /* caller */ + 47, /* warn */ + 47, /* die */ + 47, /* reset */ -1, /* lineseq */ - 150, /* nextstate */ - 150, /* dbstate */ + 153, /* nextstate */ + 153, /* dbstate */ -1, /* unstack */ -1, /* enter */ - 151, /* leave */ + 154, /* leave */ -1, /* scope */ - 153, /* enteriter */ - 157, /* iter */ + 156, /* enteriter */ + 160, /* iter */ -1, /* enterloop */ - 158, /* leaveloop */ + 161, /* leaveloop */ -1, /* return */ - 160, /* last */ - 160, /* next */ - 160, /* redo */ - 160, /* dump */ - 160, /* goto */ - 48, /* exit */ + 163, /* last */ + 163, /* next */ + 163, /* redo */ + 163, /* dump */ + 163, /* goto */ + 47, /* exit */ 0, /* method_named */ 0, /* method_super */ 0, /* method_redir */ @@ -2668,79 +2666,79 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* leavewhen */ -1, /* break */ -1, /* continue */ - 162, /* open */ - 48, /* close */ - 48, /* pipe_op */ - 48, /* fileno */ - 48, /* umask */ - 48, /* binmode */ - 48, /* tie */ + 165, /* open */ + 47, /* close */ + 47, /* pipe_op */ + 47, /* fileno */ + 47, /* umask */ + 47, /* binmode */ + 47, /* tie */ 0, /* untie */ 0, /* tied */ - 48, /* dbmopen */ + 47, /* dbmopen */ 0, /* dbmclose */ - 48, /* sselect */ - 48, /* select */ - 48, /* getc */ - 48, /* read */ - 48, /* enterwrite */ - 144, /* leavewrite */ + 47, /* sselect */ + 47, /* select */ + 47, /* getc */ + 47, /* read */ + 47, /* enterwrite */ + 147, /* leavewrite */ -1, /* prtf */ -1, /* print */ -1, /* say */ - 48, /* sysopen */ - 48, /* sysseek */ - 48, /* sysread */ - 48, /* syswrite */ - 48, /* eof */ - 48, /* tell */ - 48, /* seek */ - 48, /* truncate */ - 48, /* fcntl */ - 48, /* ioctl */ + 47, /* sysopen */ + 47, /* sysseek */ + 47, /* sysread */ + 47, /* syswrite */ + 47, /* eof */ + 47, /* tell */ + 47, /* seek */ + 47, /* truncate */ + 47, /* fcntl */ + 47, /* ioctl */ 77, /* flock */ - 48, /* send */ - 48, /* recv */ - 48, /* socket */ - 48, /* sockpair */ - 48, /* bind */ - 48, /* connect */ - 48, /* listen */ - 48, /* accept */ - 48, /* shutdown */ - 48, /* gsockopt */ - 48, /* ssockopt */ + 47, /* send */ + 47, /* recv */ + 47, /* socket */ + 47, /* sockpair */ + 47, /* bind */ + 47, /* connect */ + 47, /* listen */ + 47, /* accept */ + 47, /* shutdown */ + 47, /* gsockopt */ + 47, /* ssockopt */ 0, /* getsockname */ 0, /* getpeername */ 0, /* lstat */ 0, /* stat */ - 167, /* ftrread */ - 167, /* ftrwrite */ - 167, /* ftrexec */ - 167, /* fteread */ - 167, /* ftewrite */ - 167, /* fteexec */ - 172, /* ftis */ - 172, /* ftsize */ - 172, /* ftmtime */ - 172, /* ftatime */ - 172, /* ftctime */ - 172, /* ftrowned */ - 172, /* fteowned */ - 172, /* ftzero */ - 172, /* ftsock */ - 172, /* ftchr */ - 172, /* ftblk */ - 172, /* ftfile */ - 172, /* ftdir */ - 172, /* ftpipe */ - 172, /* ftsuid */ - 172, /* ftsgid */ - 172, /* ftsvtx */ - 172, /* ftlink */ - 172, /* fttty */ - 172, /* fttext */ - 172, /* ftbinary */ + 170, /* ftrread */ + 170, /* ftrwrite */ + 170, /* ftrexec */ + 170, /* fteread */ + 170, /* ftewrite */ + 170, /* fteexec */ + 175, /* ftis */ + 175, /* ftsize */ + 175, /* ftmtime */ + 175, /* ftatime */ + 175, /* ftctime */ + 175, /* ftrowned */ + 175, /* fteowned */ + 175, /* ftzero */ + 175, /* ftsock */ + 175, /* ftchr */ + 175, /* ftblk */ + 175, /* ftfile */ + 175, /* ftdir */ + 175, /* ftpipe */ + 175, /* ftsuid */ + 175, /* ftsgid */ + 175, /* ftsvtx */ + 175, /* ftlink */ + 175, /* fttty */ + 175, /* fttext */ + 175, /* ftbinary */ 77, /* chdir */ 77, /* chown */ 71, /* chroot */ @@ -2753,58 +2751,58 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { 0, /* readlink */ 77, /* mkdir */ 71, /* rmdir */ - 48, /* open_dir */ + 47, /* open_dir */ 0, /* readdir */ 0, /* telldir */ - 48, /* seekdir */ + 47, /* seekdir */ 0, /* rewinddir */ 0, /* closedir */ -1, /* fork */ - 176, /* wait */ + 179, /* wait */ 77, /* waitpid */ 77, /* system */ 77, /* exec */ 77, /* kill */ - 176, /* getppid */ + 179, /* getppid */ 77, /* getpgrp */ 77, /* setpgrp */ 77, /* getpriority */ 77, /* setpriority */ - 176, /* time */ + 179, /* time */ -1, /* tms */ 0, /* localtime */ - 48, /* gmtime */ + 47, /* gmtime */ 0, /* alarm */ 77, /* sleep */ - 48, /* shmget */ - 48, /* shmctl */ - 48, /* shmread */ - 48, /* shmwrite */ - 48, /* msgget */ - 48, /* msgctl */ - 48, /* msgsnd */ - 48, /* msgrcv */ - 48, /* semop */ - 48, /* semget */ - 48, /* semctl */ + 47, /* shmget */ + 47, /* shmctl */ + 47, /* shmread */ + 47, /* shmwrite */ + 47, /* msgget */ + 47, /* msgctl */ + 47, /* msgsnd */ + 47, /* msgrcv */ + 47, /* semop */ + 47, /* semget */ + 47, /* semctl */ 0, /* require */ 0, /* dofile */ -1, /* hintseval */ - 177, /* entereval */ - 144, /* leaveeval */ + 180, /* entereval */ + 147, /* leaveeval */ 0, /* entertry */ -1, /* leavetry */ 0, /* ghbyname */ - 48, /* ghbyaddr */ + 47, /* ghbyaddr */ -1, /* ghostent */ 0, /* gnbyname */ - 48, /* gnbyaddr */ + 47, /* gnbyaddr */ -1, /* gnetent */ 0, /* gpbyname */ - 48, /* gpbynumber */ + 47, /* gpbynumber */ -1, /* gprotoent */ - 48, /* gsbyname */ - 48, /* gsbyport */ + 47, /* gsbyname */ + 47, /* gsbyport */ -1, /* gservent */ 0, /* shostent */ 0, /* snetent */ @@ -2825,22 +2823,22 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { -1, /* sgrent */ -1, /* egrent */ -1, /* getlogin */ - 48, /* syscall */ + 47, /* syscall */ 0, /* lock */ 0, /* once */ -1, /* custom */ - 183, /* coreargs */ - 187, /* avhvswitch */ + 186, /* coreargs */ + 190, /* avhvswitch */ 3, /* runcv */ 0, /* fc */ -1, /* padcv */ -1, /* introcv */ -1, /* clonecv */ - 189, /* padrange */ - 191, /* refassign */ - 197, /* lvref */ - 203, /* lvrefslice */ - 204, /* lvavref */ + 192, /* padrange */ + 194, /* refassign */ + 200, /* lvref */ + 206, /* lvrefslice */ + 207, /* lvavref */ 0, /* anonconst */ }; @@ -2861,69 +2859,69 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = { EXTCONST U16 PL_op_private_bitdefs[] = { 0x0003, /* scalar, prototype, refgen, srefgen, ref, readline, regcmaybe, regcreset, regcomp, chop, schop, defined, undef, study, preinc, i_preinc, predec, i_predec, postinc, i_postinc, postdec, i_postdec, negate, i_negate, not, complement, ucfirst, lcfirst, uc, lc, quotemeta, aeach, avalues, each, values, pop, shift, grepstart, grepwhile, mapstart, mapwhile, range, and, or, dor, andassign, orassign, dorassign, method, argcheck, argdefelem, method_named, method_super, method_redir, method_redir_super, entergiven, leavegiven, enterwhen, leavewhen, untie, tied, dbmclose, getsockname, getpeername, lstat, stat, readlink, readdir, telldir, rewinddir, closedir, localtime, alarm, require, dofile, entertry, ghbyname, gnbyname, gpbyname, shostent, snetent, sprotoent, sservent, gpwnam, gpwuid, ggrnam, ggrgid, lock, once, fc, anonconst */ - 0x2b5c, 0x3d59, /* pushmark */ + 0x2cbc, 0x3eb9, /* pushmark */ 0x00bd, /* wantarray, runcv */ - 0x03b8, 0x17f0, 0x3e0c, 0x38c8, 0x2f25, /* const */ - 0x2b5c, 0x3079, /* gvsv */ - 0x1655, /* gv */ + 0x0498, 0x18d0, 0x3f6c, 0x3a28, 0x3085, /* const */ + 0x2cbc, 0x31d9, /* gvsv */ + 0x1735, /* gv */ 0x0067, /* gelem, lt, i_lt, gt, i_gt, le, i_le, ge, i_ge, eq, i_eq, ne, i_ne, ncmp, i_ncmp, slt, sgt, sle, sge, seq, sne, scmp, bit_and, bit_xor, bit_or, sbit_and, sbit_xor, sbit_or, smartmatch, lslice, xor */ - 0x2b5c, 0x3d58, 0x03d7, /* padsv */ - 0x2b5c, 0x3d58, 0x2c4c, 0x3a49, /* padav */ - 0x2b5c, 0x3d58, 0x0534, 0x05d0, 0x2c4c, 0x3a49, /* padhv */ - 0x3819, /* pushre, match, qr, subst */ - 0x2b5c, 0x19d8, 0x03d6, 0x2c4c, 0x2e48, 0x3e04, 0x0003, /* rv2gv */ - 0x2b5c, 0x3078, 0x03d6, 0x3e04, 0x0003, /* rv2sv */ - 0x2c4c, 0x0003, /* av2arylen, pos, akeys, keys */ - 0x2dbc, 0x0e18, 0x0b74, 0x028c, 0x3fc8, 0x3e04, 0x0003, /* rv2cv */ + 0x2cbc, 0x3eb8, 0x03d7, /* padsv */ + 0x2cbc, 0x3eb8, 0x2dac, 0x3ba9, /* padav */ + 0x2cbc, 0x3eb8, 0x0614, 0x06b0, 0x2dac, 0x3ba9, /* padhv */ + 0x2cbc, 0x1ab8, 0x03d6, 0x2dac, 0x2fa8, 0x3f64, 0x0003, /* rv2gv */ + 0x2cbc, 0x31d8, 0x03d6, 0x3f64, 0x0003, /* rv2sv */ + 0x2dac, 0x0003, /* av2arylen, pos, akeys, keys */ + 0x2f1c, 0x0ef8, 0x0c54, 0x028c, 0x4128, 0x3f64, 0x0003, /* rv2cv */ 0x018f, /* bless, glob, sprintf, formline, unpack, pack, join, anonlist, anonhash, splice, warn, die, reset, exit, close, pipe_op, fileno, umask, binmode, tie, dbmopen, sselect, select, getc, read, enterwrite, sysopen, sysseek, sysread, syswrite, eof, tell, seek, truncate, fcntl, ioctl, send, recv, socket, sockpair, bind, connect, listen, accept, shutdown, gsockopt, ssockopt, open_dir, seekdir, gmtime, shmget, shmctl, shmread, shmwrite, msgget, msgctl, msgsnd, msgrcv, semop, semget, semctl, ghbyaddr, gnbyaddr, gpbynumber, gsbyname, gsbyport, syscall */ - 0x325c, 0x3178, 0x2634, 0x2570, 0x0003, /* backtick */ - 0x3818, 0x0003, /* substcont */ - 0x0f1c, 0x1f58, 0x0754, 0x3b8c, 0x22e8, 0x01e4, 0x0141, /* trans, transr */ - 0x0d5c, 0x0458, 0x0067, /* sassign */ - 0x0a18, 0x0914, 0x0810, 0x2c4c, 0x0067, /* aassign */ - 0x4070, 0x0003, /* chomp, schomp, ncomplement, scomplement, sin, cos, exp, log, sqrt, int, hex, oct, abs, length, ord, chr, chroot, rmdir */ - 0x4070, 0x0067, /* pow, multiply, i_multiply, divide, i_divide, modulo, i_modulo, add, i_add, subtract, i_subtract, concat, left_shift, right_shift, nbit_and, nbit_xor, nbit_or */ - 0x12d8, 0x0067, /* repeat */ - 0x4070, 0x018f, /* stringify, atan2, rand, srand, index, rindex, crypt, push, unshift, flock, chdir, chown, unlink, chmod, utime, rename, link, symlink, mkdir, waitpid, system, exec, kill, getpgrp, setpgrp, getpriority, setpriority, sleep */ - 0x3570, 0x2c4c, 0x012b, /* substr */ - 0x2c4c, 0x0067, /* vec */ - 0x2b5c, 0x3078, 0x2c4c, 0x3a48, 0x3e04, 0x0003, /* rv2av */ + 0x33bc, 0x32d8, 0x2714, 0x2650, 0x0003, /* backtick */ + 0x3975, /* match, qr, subst */ + 0x3974, 0x0003, /* substcont */ + 0x0ffc, 0x2038, 0x0834, 0x3cec, 0x23c8, 0x01e4, 0x0141, /* trans, transr */ + 0x0e3c, 0x0538, 0x0067, /* sassign */ + 0x0af8, 0x09f4, 0x08f0, 0x2dac, 0x0067, /* aassign */ + 0x41d0, 0x0003, /* chomp, schomp, ncomplement, scomplement, sin, cos, exp, log, sqrt, int, hex, oct, abs, length, ord, chr, chroot, rmdir */ + 0x41d0, 0x0067, /* pow, multiply, i_multiply, divide, i_divide, modulo, i_modulo, add, i_add, subtract, i_subtract, concat, left_shift, right_shift, nbit_and, nbit_xor, nbit_or */ + 0x13b8, 0x0067, /* repeat */ + 0x41d0, 0x018f, /* stringify, atan2, rand, srand, index, rindex, crypt, push, unshift, flock, chdir, chown, unlink, chmod, utime, rename, link, symlink, mkdir, waitpid, system, exec, kill, getpgrp, setpgrp, getpriority, setpriority, sleep */ + 0x36d0, 0x2dac, 0x012b, /* substr */ + 0x2dac, 0x0067, /* vec */ + 0x2cbc, 0x31d8, 0x2dac, 0x3ba8, 0x3f64, 0x0003, /* rv2av */ 0x025f, /* aelemfast, aelemfast_lex */ - 0x2b5c, 0x2a58, 0x03d6, 0x2c4c, 0x0067, /* aelem, helem */ - 0x2b5c, 0x2c4c, 0x3a49, /* aslice, hslice */ - 0x2c4d, /* kvaslice, kvhslice */ - 0x2b5c, 0x3998, 0x0003, /* delete */ - 0x3ef8, 0x0003, /* exists */ - 0x2b5c, 0x3078, 0x0534, 0x05d0, 0x2c4c, 0x3a48, 0x3e04, 0x0003, /* rv2hv */ - 0x2b5c, 0x2a58, 0x0f94, 0x18f0, 0x2c4c, 0x3e04, 0x0003, /* multideref */ - 0x23bc, 0x3079, /* split */ - 0x2b5c, 0x2019, /* list */ - 0x3c78, 0x3314, 0x1230, 0x26cc, 0x3668, 0x27c4, 0x2fe1, /* sort */ - 0x26cc, 0x0003, /* reverse */ - 0x28f8, 0x0003, /* flip, flop */ - 0x2b5c, 0x0003, /* cond_expr */ - 0x2b5c, 0x0e18, 0x03d6, 0x028c, 0x3fc8, 0x3e04, 0x2481, /* entersub */ - 0x33d8, 0x0003, /* leavesub, leavesublv, leavewrite, leaveeval */ + 0x2cbc, 0x2bb8, 0x03d6, 0x2dac, 0x0067, /* aelem, helem */ + 0x2cbc, 0x2dac, 0x3ba9, /* aslice, hslice */ + 0x2dad, /* kvaslice, kvhslice */ + 0x2cbc, 0x3af8, 0x0003, /* delete */ + 0x4058, 0x0003, /* exists */ + 0x2cbc, 0x31d8, 0x0614, 0x06b0, 0x2dac, 0x3ba8, 0x3f64, 0x0003, /* rv2hv */ + 0x2cbc, 0x2bb8, 0x1074, 0x19d0, 0x2dac, 0x3f64, 0x0003, /* multideref */ + 0x249c, 0x31d8, 0x3974, 0x0350, 0x29cd, /* split */ + 0x2cbc, 0x20f9, /* list */ + 0x3dd8, 0x3474, 0x1310, 0x27ac, 0x37c8, 0x28a4, 0x3141, /* sort */ + 0x27ac, 0x0003, /* reverse */ + 0x2a58, 0x0003, /* flip, flop */ + 0x2cbc, 0x0003, /* cond_expr */ + 0x2cbc, 0x0ef8, 0x03d6, 0x028c, 0x4128, 0x3f64, 0x2561, /* entersub */ + 0x3538, 0x0003, /* leavesub, leavesublv, leavewrite, leaveeval */ 0x02aa, 0x0003, /* argelem */ 0x00bc, 0x018f, /* caller */ - 0x21f5, /* nextstate, dbstate */ - 0x29fc, 0x33d9, /* leave */ - 0x2b5c, 0x3078, 0x0e8c, 0x36e5, /* enteriter */ - 0x36e5, /* iter */ - 0x29fc, 0x0067, /* leaveloop */ - 0x41dc, 0x0003, /* last, next, redo, dump, goto */ - 0x325c, 0x3178, 0x2634, 0x2570, 0x018f, /* open */ - 0x1b90, 0x1dec, 0x1ca8, 0x1a64, 0x0003, /* ftrread, ftrwrite, ftrexec, fteread, ftewrite, fteexec */ - 0x1b90, 0x1dec, 0x1ca8, 0x0003, /* ftis, ftsize, ftmtime, ftatime, ftctime, ftrowned, fteowned, ftzero, ftsock, ftchr, ftblk, ftfile, ftdir, ftpipe, ftsuid, ftsgid, ftsvtx, ftlink, fttty, fttext, ftbinary */ - 0x4071, /* wait, getppid, time */ - 0x3474, 0x0c30, 0x068c, 0x4148, 0x2104, 0x0003, /* entereval */ - 0x2d1c, 0x0018, 0x1144, 0x1061, /* coreargs */ - 0x2c4c, 0x00c7, /* avhvswitch */ - 0x2b5c, 0x01fb, /* padrange */ - 0x2b5c, 0x3d58, 0x04f6, 0x284c, 0x1748, 0x0067, /* refassign */ - 0x2b5c, 0x3d58, 0x04f6, 0x284c, 0x1748, 0x0003, /* lvref */ - 0x2b5d, /* lvrefslice */ - 0x2b5c, 0x3d58, 0x0003, /* lvavref */ + 0x22d5, /* nextstate, dbstate */ + 0x2b5c, 0x3539, /* leave */ + 0x2cbc, 0x31d8, 0x0f6c, 0x3845, /* enteriter */ + 0x3845, /* iter */ + 0x2b5c, 0x0067, /* leaveloop */ + 0x433c, 0x0003, /* last, next, redo, dump, goto */ + 0x33bc, 0x32d8, 0x2714, 0x2650, 0x018f, /* open */ + 0x1c70, 0x1ecc, 0x1d88, 0x1b44, 0x0003, /* ftrread, ftrwrite, ftrexec, fteread, ftewrite, fteexec */ + 0x1c70, 0x1ecc, 0x1d88, 0x0003, /* ftis, ftsize, ftmtime, ftatime, ftctime, ftrowned, fteowned, ftzero, ftsock, ftchr, ftblk, ftfile, ftdir, ftpipe, ftsuid, ftsgid, ftsvtx, ftlink, fttty, fttext, ftbinary */ + 0x41d1, /* wait, getppid, time */ + 0x35d4, 0x0d10, 0x076c, 0x42a8, 0x21e4, 0x0003, /* entereval */ + 0x2e7c, 0x0018, 0x1224, 0x1141, /* coreargs */ + 0x2dac, 0x00c7, /* avhvswitch */ + 0x2cbc, 0x01fb, /* padrange */ + 0x2cbc, 0x3eb8, 0x04f6, 0x292c, 0x1828, 0x0067, /* refassign */ + 0x2cbc, 0x3eb8, 0x04f6, 0x292c, 0x1828, 0x0003, /* lvref */ + 0x2cbd, /* lvrefslice */ + 0x2cbc, 0x3eb8, 0x0003, /* lvavref */ }; @@ -2945,7 +2943,6 @@ EXTCONST U8 PL_op_private_valid[] = { /* PADAV */ (OPpSLICEWARNING|OPpMAYBE_LVSUB|OPpPAD_STATE|OPpLVAL_INTRO), /* PADHV */ (OPpSLICEWARNING|OPpMAYBE_LVSUB|OPpMAYBE_TRUEBOOL|OPpTRUEBOOL|OPpPAD_STATE|OPpLVAL_INTRO), /* PADANY */ (0), - /* PUSHRE */ (OPpRUNTIME), /* RV2GV */ (OPpARG1_MASK|OPpHINT_STRICT_REFS|OPpDONT_INIT_GV|OPpMAYBE_LVSUB|OPpDEREF|OPpALLOW_FAKE|OPpLVAL_INTRO), /* RV2SV */ (OPpARG1_MASK|OPpHINT_STRICT_REFS|OPpDEREF|OPpOUR_INTRO|OPpLVAL_INTRO), /* AV2ARYLEN */ (OPpARG1_MASK|OPpMAYBE_LVSUB), @@ -3088,7 +3085,7 @@ EXTCONST U8 PL_op_private_valid[] = { /* MULTIDEREF */ (OPpARG1_MASK|OPpHINT_STRICT_REFS|OPpMAYBE_LVSUB|OPpMULTIDEREF_EXISTS|OPpMULTIDEREF_DELETE|OPpLVAL_DEFER|OPpLVAL_INTRO), /* UNPACK */ (OPpARG4_MASK), /* PACK */ (OPpARG4_MASK), - /* SPLIT */ (OPpOUR_INTRO|OPpSPLIT_IMPLIM), + /* SPLIT */ (OPpSPLIT_LEX|OPpSPLIT_ASSIGN|OPpRUNTIME|OPpOUR_INTRO|OPpSPLIT_IMPLIM), /* JOIN */ (OPpARG4_MASK), /* LIST */ (OPpLIST_GUESSED|OPpLVAL_INTRO), /* LSLICE */ (OPpARG2_MASK), @@ -27,394 +27,393 @@ typedef enum opcode { OP_PADAV = 10, OP_PADHV = 11, OP_PADANY = 12, - OP_PUSHRE = 13, - OP_RV2GV = 14, - OP_RV2SV = 15, - OP_AV2ARYLEN = 16, - OP_RV2CV = 17, - OP_ANONCODE = 18, - OP_PROTOTYPE = 19, - OP_REFGEN = 20, - OP_SREFGEN = 21, - OP_REF = 22, - OP_BLESS = 23, - OP_BACKTICK = 24, - OP_GLOB = 25, - OP_READLINE = 26, - OP_RCATLINE = 27, - OP_REGCMAYBE = 28, - OP_REGCRESET = 29, - OP_REGCOMP = 30, - OP_MATCH = 31, - OP_QR = 32, - OP_SUBST = 33, - OP_SUBSTCONT = 34, - OP_TRANS = 35, - OP_TRANSR = 36, - OP_SASSIGN = 37, - OP_AASSIGN = 38, - OP_CHOP = 39, - OP_SCHOP = 40, - OP_CHOMP = 41, - OP_SCHOMP = 42, - OP_DEFINED = 43, - OP_UNDEF = 44, - OP_STUDY = 45, - OP_POS = 46, - OP_PREINC = 47, - OP_I_PREINC = 48, - OP_PREDEC = 49, - OP_I_PREDEC = 50, - OP_POSTINC = 51, - OP_I_POSTINC = 52, - OP_POSTDEC = 53, - OP_I_POSTDEC = 54, - OP_POW = 55, - OP_MULTIPLY = 56, - OP_I_MULTIPLY = 57, - OP_DIVIDE = 58, - OP_I_DIVIDE = 59, - OP_MODULO = 60, - OP_I_MODULO = 61, - OP_REPEAT = 62, - OP_ADD = 63, - OP_I_ADD = 64, - OP_SUBTRACT = 65, - OP_I_SUBTRACT = 66, - OP_CONCAT = 67, - OP_STRINGIFY = 68, - OP_LEFT_SHIFT = 69, - OP_RIGHT_SHIFT = 70, - OP_LT = 71, - OP_I_LT = 72, - OP_GT = 73, - OP_I_GT = 74, - OP_LE = 75, - OP_I_LE = 76, - OP_GE = 77, - OP_I_GE = 78, - OP_EQ = 79, - OP_I_EQ = 80, - OP_NE = 81, - OP_I_NE = 82, - OP_NCMP = 83, - OP_I_NCMP = 84, - OP_SLT = 85, - OP_SGT = 86, - OP_SLE = 87, - OP_SGE = 88, - OP_SEQ = 89, - OP_SNE = 90, - OP_SCMP = 91, - OP_BIT_AND = 92, - OP_BIT_XOR = 93, - OP_BIT_OR = 94, - OP_NBIT_AND = 95, - OP_NBIT_XOR = 96, - OP_NBIT_OR = 97, - OP_SBIT_AND = 98, - OP_SBIT_XOR = 99, - OP_SBIT_OR = 100, - OP_NEGATE = 101, - OP_I_NEGATE = 102, - OP_NOT = 103, - OP_COMPLEMENT = 104, - OP_NCOMPLEMENT = 105, - OP_SCOMPLEMENT = 106, - OP_SMARTMATCH = 107, - OP_ATAN2 = 108, - OP_SIN = 109, - OP_COS = 110, - OP_RAND = 111, - OP_SRAND = 112, - OP_EXP = 113, - OP_LOG = 114, - OP_SQRT = 115, - OP_INT = 116, - OP_HEX = 117, - OP_OCT = 118, - OP_ABS = 119, - OP_LENGTH = 120, - OP_SUBSTR = 121, - OP_VEC = 122, - OP_INDEX = 123, - OP_RINDEX = 124, - OP_SPRINTF = 125, - OP_FORMLINE = 126, - OP_ORD = 127, - OP_CHR = 128, - OP_CRYPT = 129, - OP_UCFIRST = 130, - OP_LCFIRST = 131, - OP_UC = 132, - OP_LC = 133, - OP_QUOTEMETA = 134, - OP_RV2AV = 135, - OP_AELEMFAST = 136, - OP_AELEMFAST_LEX = 137, - OP_AELEM = 138, - OP_ASLICE = 139, - OP_KVASLICE = 140, - OP_AEACH = 141, - OP_AVALUES = 142, - OP_AKEYS = 143, - OP_EACH = 144, - OP_VALUES = 145, - OP_KEYS = 146, - OP_DELETE = 147, - OP_EXISTS = 148, - OP_RV2HV = 149, - OP_HELEM = 150, - OP_HSLICE = 151, - OP_KVHSLICE = 152, - OP_MULTIDEREF = 153, - OP_UNPACK = 154, - OP_PACK = 155, - OP_SPLIT = 156, - OP_JOIN = 157, - OP_LIST = 158, - OP_LSLICE = 159, - OP_ANONLIST = 160, - OP_ANONHASH = 161, - OP_SPLICE = 162, - OP_PUSH = 163, - OP_POP = 164, - OP_SHIFT = 165, - OP_UNSHIFT = 166, - OP_SORT = 167, - OP_REVERSE = 168, - OP_GREPSTART = 169, - OP_GREPWHILE = 170, - OP_MAPSTART = 171, - OP_MAPWHILE = 172, - OP_RANGE = 173, - OP_FLIP = 174, - OP_FLOP = 175, - OP_AND = 176, - OP_OR = 177, - OP_XOR = 178, - OP_DOR = 179, - OP_COND_EXPR = 180, - OP_ANDASSIGN = 181, - OP_ORASSIGN = 182, - OP_DORASSIGN = 183, - OP_METHOD = 184, - OP_ENTERSUB = 185, - OP_LEAVESUB = 186, - OP_LEAVESUBLV = 187, - OP_ARGCHECK = 188, - OP_ARGELEM = 189, - OP_ARGDEFELEM = 190, - OP_CALLER = 191, - OP_WARN = 192, - OP_DIE = 193, - OP_RESET = 194, - OP_LINESEQ = 195, - OP_NEXTSTATE = 196, - OP_DBSTATE = 197, - OP_UNSTACK = 198, - OP_ENTER = 199, - OP_LEAVE = 200, - OP_SCOPE = 201, - OP_ENTERITER = 202, - OP_ITER = 203, - OP_ENTERLOOP = 204, - OP_LEAVELOOP = 205, - OP_RETURN = 206, - OP_LAST = 207, - OP_NEXT = 208, - OP_REDO = 209, - OP_DUMP = 210, - OP_GOTO = 211, - OP_EXIT = 212, - OP_METHOD_NAMED = 213, - OP_METHOD_SUPER = 214, - OP_METHOD_REDIR = 215, - OP_METHOD_REDIR_SUPER = 216, - OP_ENTERGIVEN = 217, - OP_LEAVEGIVEN = 218, - OP_ENTERWHEN = 219, - OP_LEAVEWHEN = 220, - OP_BREAK = 221, - OP_CONTINUE = 222, - OP_OPEN = 223, - OP_CLOSE = 224, - OP_PIPE_OP = 225, - OP_FILENO = 226, - OP_UMASK = 227, - OP_BINMODE = 228, - OP_TIE = 229, - OP_UNTIE = 230, - OP_TIED = 231, - OP_DBMOPEN = 232, - OP_DBMCLOSE = 233, - OP_SSELECT = 234, - OP_SELECT = 235, - OP_GETC = 236, - OP_READ = 237, - OP_ENTERWRITE = 238, - OP_LEAVEWRITE = 239, - OP_PRTF = 240, - OP_PRINT = 241, - OP_SAY = 242, - OP_SYSOPEN = 243, - OP_SYSSEEK = 244, - OP_SYSREAD = 245, - OP_SYSWRITE = 246, - OP_EOF = 247, - OP_TELL = 248, - OP_SEEK = 249, - OP_TRUNCATE = 250, - OP_FCNTL = 251, - OP_IOCTL = 252, - OP_FLOCK = 253, - OP_SEND = 254, - OP_RECV = 255, - OP_SOCKET = 256, - OP_SOCKPAIR = 257, - OP_BIND = 258, - OP_CONNECT = 259, - OP_LISTEN = 260, - OP_ACCEPT = 261, - OP_SHUTDOWN = 262, - OP_GSOCKOPT = 263, - OP_SSOCKOPT = 264, - OP_GETSOCKNAME = 265, - OP_GETPEERNAME = 266, - OP_LSTAT = 267, - OP_STAT = 268, - OP_FTRREAD = 269, - OP_FTRWRITE = 270, - OP_FTREXEC = 271, - OP_FTEREAD = 272, - OP_FTEWRITE = 273, - OP_FTEEXEC = 274, - OP_FTIS = 275, - OP_FTSIZE = 276, - OP_FTMTIME = 277, - OP_FTATIME = 278, - OP_FTCTIME = 279, - OP_FTROWNED = 280, - OP_FTEOWNED = 281, - OP_FTZERO = 282, - OP_FTSOCK = 283, - OP_FTCHR = 284, - OP_FTBLK = 285, - OP_FTFILE = 286, - OP_FTDIR = 287, - OP_FTPIPE = 288, - OP_FTSUID = 289, - OP_FTSGID = 290, - OP_FTSVTX = 291, - OP_FTLINK = 292, - OP_FTTTY = 293, - OP_FTTEXT = 294, - OP_FTBINARY = 295, - OP_CHDIR = 296, - OP_CHOWN = 297, - OP_CHROOT = 298, - OP_UNLINK = 299, - OP_CHMOD = 300, - OP_UTIME = 301, - OP_RENAME = 302, - OP_LINK = 303, - OP_SYMLINK = 304, - OP_READLINK = 305, - OP_MKDIR = 306, - OP_RMDIR = 307, - OP_OPEN_DIR = 308, - OP_READDIR = 309, - OP_TELLDIR = 310, - OP_SEEKDIR = 311, - OP_REWINDDIR = 312, - OP_CLOSEDIR = 313, - OP_FORK = 314, - OP_WAIT = 315, - OP_WAITPID = 316, - OP_SYSTEM = 317, - OP_EXEC = 318, - OP_KILL = 319, - OP_GETPPID = 320, - OP_GETPGRP = 321, - OP_SETPGRP = 322, - OP_GETPRIORITY = 323, - OP_SETPRIORITY = 324, - OP_TIME = 325, - OP_TMS = 326, - OP_LOCALTIME = 327, - OP_GMTIME = 328, - OP_ALARM = 329, - OP_SLEEP = 330, - OP_SHMGET = 331, - OP_SHMCTL = 332, - OP_SHMREAD = 333, - OP_SHMWRITE = 334, - OP_MSGGET = 335, - OP_MSGCTL = 336, - OP_MSGSND = 337, - OP_MSGRCV = 338, - OP_SEMOP = 339, - OP_SEMGET = 340, - OP_SEMCTL = 341, - OP_REQUIRE = 342, - OP_DOFILE = 343, - OP_HINTSEVAL = 344, - OP_ENTEREVAL = 345, - OP_LEAVEEVAL = 346, - OP_ENTERTRY = 347, - OP_LEAVETRY = 348, - OP_GHBYNAME = 349, - OP_GHBYADDR = 350, - OP_GHOSTENT = 351, - OP_GNBYNAME = 352, - OP_GNBYADDR = 353, - OP_GNETENT = 354, - OP_GPBYNAME = 355, - OP_GPBYNUMBER = 356, - OP_GPROTOENT = 357, - OP_GSBYNAME = 358, - OP_GSBYPORT = 359, - OP_GSERVENT = 360, - OP_SHOSTENT = 361, - OP_SNETENT = 362, - OP_SPROTOENT = 363, - OP_SSERVENT = 364, - OP_EHOSTENT = 365, - OP_ENETENT = 366, - OP_EPROTOENT = 367, - OP_ESERVENT = 368, - OP_GPWNAM = 369, - OP_GPWUID = 370, - OP_GPWENT = 371, - OP_SPWENT = 372, - OP_EPWENT = 373, - OP_GGRNAM = 374, - OP_GGRGID = 375, - OP_GGRENT = 376, - OP_SGRENT = 377, - OP_EGRENT = 378, - OP_GETLOGIN = 379, - OP_SYSCALL = 380, - OP_LOCK = 381, - OP_ONCE = 382, - OP_CUSTOM = 383, - OP_COREARGS = 384, - OP_AVHVSWITCH = 385, - OP_RUNCV = 386, - OP_FC = 387, - OP_PADCV = 388, - OP_INTROCV = 389, - OP_CLONECV = 390, - OP_PADRANGE = 391, - OP_REFASSIGN = 392, - OP_LVREF = 393, - OP_LVREFSLICE = 394, - OP_LVAVREF = 395, - OP_ANONCONST = 396, + OP_RV2GV = 13, + OP_RV2SV = 14, + OP_AV2ARYLEN = 15, + OP_RV2CV = 16, + OP_ANONCODE = 17, + OP_PROTOTYPE = 18, + OP_REFGEN = 19, + OP_SREFGEN = 20, + OP_REF = 21, + OP_BLESS = 22, + OP_BACKTICK = 23, + OP_GLOB = 24, + OP_READLINE = 25, + OP_RCATLINE = 26, + OP_REGCMAYBE = 27, + OP_REGCRESET = 28, + OP_REGCOMP = 29, + OP_MATCH = 30, + OP_QR = 31, + OP_SUBST = 32, + OP_SUBSTCONT = 33, + OP_TRANS = 34, + OP_TRANSR = 35, + OP_SASSIGN = 36, + OP_AASSIGN = 37, + OP_CHOP = 38, + OP_SCHOP = 39, + OP_CHOMP = 40, + OP_SCHOMP = 41, + OP_DEFINED = 42, + OP_UNDEF = 43, + OP_STUDY = 44, + OP_POS = 45, + OP_PREINC = 46, + OP_I_PREINC = 47, + OP_PREDEC = 48, + OP_I_PREDEC = 49, + OP_POSTINC = 50, + OP_I_POSTINC = 51, + OP_POSTDEC = 52, + OP_I_POSTDEC = 53, + OP_POW = 54, + OP_MULTIPLY = 55, + OP_I_MULTIPLY = 56, + OP_DIVIDE = 57, + OP_I_DIVIDE = 58, + OP_MODULO = 59, + OP_I_MODULO = 60, + OP_REPEAT = 61, + OP_ADD = 62, + OP_I_ADD = 63, + OP_SUBTRACT = 64, + OP_I_SUBTRACT = 65, + OP_CONCAT = 66, + OP_STRINGIFY = 67, + OP_LEFT_SHIFT = 68, + OP_RIGHT_SHIFT = 69, + OP_LT = 70, + OP_I_LT = 71, + OP_GT = 72, + OP_I_GT = 73, + OP_LE = 74, + OP_I_LE = 75, + OP_GE = 76, + OP_I_GE = 77, + OP_EQ = 78, + OP_I_EQ = 79, + OP_NE = 80, + OP_I_NE = 81, + OP_NCMP = 82, + OP_I_NCMP = 83, + OP_SLT = 84, + OP_SGT = 85, + OP_SLE = 86, + OP_SGE = 87, + OP_SEQ = 88, + OP_SNE = 89, + OP_SCMP = 90, + OP_BIT_AND = 91, + OP_BIT_XOR = 92, + OP_BIT_OR = 93, + OP_NBIT_AND = 94, + OP_NBIT_XOR = 95, + OP_NBIT_OR = 96, + OP_SBIT_AND = 97, + OP_SBIT_XOR = 98, + OP_SBIT_OR = 99, + OP_NEGATE = 100, + OP_I_NEGATE = 101, + OP_NOT = 102, + OP_COMPLEMENT = 103, + OP_NCOMPLEMENT = 104, + OP_SCOMPLEMENT = 105, + OP_SMARTMATCH = 106, + OP_ATAN2 = 107, + OP_SIN = 108, + OP_COS = 109, + OP_RAND = 110, + OP_SRAND = 111, + OP_EXP = 112, + OP_LOG = 113, + OP_SQRT = 114, + OP_INT = 115, + OP_HEX = 116, + OP_OCT = 117, + OP_ABS = 118, + OP_LENGTH = 119, + OP_SUBSTR = 120, + OP_VEC = 121, + OP_INDEX = 122, + OP_RINDEX = 123, + OP_SPRINTF = 124, + OP_FORMLINE = 125, + OP_ORD = 126, + OP_CHR = 127, + OP_CRYPT = 128, + OP_UCFIRST = 129, + OP_LCFIRST = 130, + OP_UC = 131, + OP_LC = 132, + OP_QUOTEMETA = 133, + OP_RV2AV = 134, + OP_AELEMFAST = 135, + OP_AELEMFAST_LEX = 136, + OP_AELEM = 137, + OP_ASLICE = 138, + OP_KVASLICE = 139, + OP_AEACH = 140, + OP_AVALUES = 141, + OP_AKEYS = 142, + OP_EACH = 143, + OP_VALUES = 144, + OP_KEYS = 145, + OP_DELETE = 146, + OP_EXISTS = 147, + OP_RV2HV = 148, + OP_HELEM = 149, + OP_HSLICE = 150, + OP_KVHSLICE = 151, + OP_MULTIDEREF = 152, + OP_UNPACK = 153, + OP_PACK = 154, + OP_SPLIT = 155, + OP_JOIN = 156, + OP_LIST = 157, + OP_LSLICE = 158, + OP_ANONLIST = 159, + OP_ANONHASH = 160, + OP_SPLICE = 161, + OP_PUSH = 162, + OP_POP = 163, + OP_SHIFT = 164, + OP_UNSHIFT = 165, + OP_SORT = 166, + OP_REVERSE = 167, + OP_GREPSTART = 168, + OP_GREPWHILE = 169, + OP_MAPSTART = 170, + OP_MAPWHILE = 171, + OP_RANGE = 172, + OP_FLIP = 173, + OP_FLOP = 174, + OP_AND = 175, + OP_OR = 176, + OP_XOR = 177, + OP_DOR = 178, + OP_COND_EXPR = 179, + OP_ANDASSIGN = 180, + OP_ORASSIGN = 181, + OP_DORASSIGN = 182, + OP_METHOD = 183, + OP_ENTERSUB = 184, + OP_LEAVESUB = 185, + OP_LEAVESUBLV = 186, + OP_ARGCHECK = 187, + OP_ARGELEM = 188, + OP_ARGDEFELEM = 189, + OP_CALLER = 190, + OP_WARN = 191, + OP_DIE = 192, + OP_RESET = 193, + OP_LINESEQ = 194, + OP_NEXTSTATE = 195, + OP_DBSTATE = 196, + OP_UNSTACK = 197, + OP_ENTER = 198, + OP_LEAVE = 199, + OP_SCOPE = 200, + OP_ENTERITER = 201, + OP_ITER = 202, + OP_ENTERLOOP = 203, + OP_LEAVELOOP = 204, + OP_RETURN = 205, + OP_LAST = 206, + OP_NEXT = 207, + OP_REDO = 208, + OP_DUMP = 209, + OP_GOTO = 210, + OP_EXIT = 211, + OP_METHOD_NAMED = 212, + OP_METHOD_SUPER = 213, + OP_METHOD_REDIR = 214, + OP_METHOD_REDIR_SUPER = 215, + OP_ENTERGIVEN = 216, + OP_LEAVEGIVEN = 217, + OP_ENTERWHEN = 218, + OP_LEAVEWHEN = 219, + OP_BREAK = 220, + OP_CONTINUE = 221, + OP_OPEN = 222, + OP_CLOSE = 223, + OP_PIPE_OP = 224, + OP_FILENO = 225, + OP_UMASK = 226, + OP_BINMODE = 227, + OP_TIE = 228, + OP_UNTIE = 229, + OP_TIED = 230, + OP_DBMOPEN = 231, + OP_DBMCLOSE = 232, + OP_SSELECT = 233, + OP_SELECT = 234, + OP_GETC = 235, + OP_READ = 236, + OP_ENTERWRITE = 237, + OP_LEAVEWRITE = 238, + OP_PRTF = 239, + OP_PRINT = 240, + OP_SAY = 241, + OP_SYSOPEN = 242, + OP_SYSSEEK = 243, + OP_SYSREAD = 244, + OP_SYSWRITE = 245, + OP_EOF = 246, + OP_TELL = 247, + OP_SEEK = 248, + OP_TRUNCATE = 249, + OP_FCNTL = 250, + OP_IOCTL = 251, + OP_FLOCK = 252, + OP_SEND = 253, + OP_RECV = 254, + OP_SOCKET = 255, + OP_SOCKPAIR = 256, + OP_BIND = 257, + OP_CONNECT = 258, + OP_LISTEN = 259, + OP_ACCEPT = 260, + OP_SHUTDOWN = 261, + OP_GSOCKOPT = 262, + OP_SSOCKOPT = 263, + OP_GETSOCKNAME = 264, + OP_GETPEERNAME = 265, + OP_LSTAT = 266, + OP_STAT = 267, + OP_FTRREAD = 268, + OP_FTRWRITE = 269, + OP_FTREXEC = 270, + OP_FTEREAD = 271, + OP_FTEWRITE = 272, + OP_FTEEXEC = 273, + OP_FTIS = 274, + OP_FTSIZE = 275, + OP_FTMTIME = 276, + OP_FTATIME = 277, + OP_FTCTIME = 278, + OP_FTROWNED = 279, + OP_FTEOWNED = 280, + OP_FTZERO = 281, + OP_FTSOCK = 282, + OP_FTCHR = 283, + OP_FTBLK = 284, + OP_FTFILE = 285, + OP_FTDIR = 286, + OP_FTPIPE = 287, + OP_FTSUID = 288, + OP_FTSGID = 289, + OP_FTSVTX = 290, + OP_FTLINK = 291, + OP_FTTTY = 292, + OP_FTTEXT = 293, + OP_FTBINARY = 294, + OP_CHDIR = 295, + OP_CHOWN = 296, + OP_CHROOT = 297, + OP_UNLINK = 298, + OP_CHMOD = 299, + OP_UTIME = 300, + OP_RENAME = 301, + OP_LINK = 302, + OP_SYMLINK = 303, + OP_READLINK = 304, + OP_MKDIR = 305, + OP_RMDIR = 306, + OP_OPEN_DIR = 307, + OP_READDIR = 308, + OP_TELLDIR = 309, + OP_SEEKDIR = 310, + OP_REWINDDIR = 311, + OP_CLOSEDIR = 312, + OP_FORK = 313, + OP_WAIT = 314, + OP_WAITPID = 315, + OP_SYSTEM = 316, + OP_EXEC = 317, + OP_KILL = 318, + OP_GETPPID = 319, + OP_GETPGRP = 320, + OP_SETPGRP = 321, + OP_GETPRIORITY = 322, + OP_SETPRIORITY = 323, + OP_TIME = 324, + OP_TMS = 325, + OP_LOCALTIME = 326, + OP_GMTIME = 327, + OP_ALARM = 328, + OP_SLEEP = 329, + OP_SHMGET = 330, + OP_SHMCTL = 331, + OP_SHMREAD = 332, + OP_SHMWRITE = 333, + OP_MSGGET = 334, + OP_MSGCTL = 335, + OP_MSGSND = 336, + OP_MSGRCV = 337, + OP_SEMOP = 338, + OP_SEMGET = 339, + OP_SEMCTL = 340, + OP_REQUIRE = 341, + OP_DOFILE = 342, + OP_HINTSEVAL = 343, + OP_ENTEREVAL = 344, + OP_LEAVEEVAL = 345, + OP_ENTERTRY = 346, + OP_LEAVETRY = 347, + OP_GHBYNAME = 348, + OP_GHBYADDR = 349, + OP_GHOSTENT = 350, + OP_GNBYNAME = 351, + OP_GNBYADDR = 352, + OP_GNETENT = 353, + OP_GPBYNAME = 354, + OP_GPBYNUMBER = 355, + OP_GPROTOENT = 356, + OP_GSBYNAME = 357, + OP_GSBYPORT = 358, + OP_GSERVENT = 359, + OP_SHOSTENT = 360, + OP_SNETENT = 361, + OP_SPROTOENT = 362, + OP_SSERVENT = 363, + OP_EHOSTENT = 364, + OP_ENETENT = 365, + OP_EPROTOENT = 366, + OP_ESERVENT = 367, + OP_GPWNAM = 368, + OP_GPWUID = 369, + OP_GPWENT = 370, + OP_SPWENT = 371, + OP_EPWENT = 372, + OP_GGRNAM = 373, + OP_GGRGID = 374, + OP_GGRENT = 375, + OP_SGRENT = 376, + OP_EGRENT = 377, + OP_GETLOGIN = 378, + OP_SYSCALL = 379, + OP_LOCK = 380, + OP_ONCE = 381, + OP_CUSTOM = 382, + OP_COREARGS = 383, + OP_AVHVSWITCH = 384, + OP_RUNCV = 385, + OP_FC = 386, + OP_PADCV = 387, + OP_INTROCV = 388, + OP_CLONECV = 389, + OP_PADRANGE = 390, + OP_REFASSIGN = 391, + OP_LVREF = 392, + OP_LVREFSLICE = 393, + OP_LVAVREF = 394, + OP_ANONCONST = 395, OP_max } opcode; -#define MAXO 397 +#define MAXO 396 #define OP_FREED MAXO /* the OP_IS_* macros are optimized to a simple range check because diff --git a/pod/perldiag.pod b/pod/perldiag.pod index 6d82cded39..8348663e1d 100644 --- a/pod/perldiag.pod +++ b/pod/perldiag.pod @@ -4430,10 +4430,6 @@ able to initialize properly. (P) Failed an internal consistency check trying to compile a grep. -=item panic: ck_split, type=%u - -(P) Failed an internal consistency check trying to compile a split. - =item panic: corrupt saved stack index %ld (P) The savestack was requested to restore more localized values than @@ -4560,10 +4556,6 @@ and freeing temporaries and lexicals from. (P) The internal pp_match() routine was called with invalid operational data. -=item panic: pp_split, pm=%p, s=%p - -(P) Something terrible went wrong in setting up for the split. - =item panic: realloc, %s (P) Something requested a negative number of bytes of realloc. @@ -5708,14 +5708,16 @@ PP(pp_reverse) PP(pp_split) { dSP; dTARG; - AV *ary = PL_op->op_flags & OPf_STACKED ? (AV *)POPs : NULL; + AV *ary = ( (PL_op->op_private & OPpSPLIT_ASSIGN) + && (PL_op->op_flags & OPf_STACKED)) + ? (AV *)POPs : NULL; IV limit = POPi; /* note, negative is forever */ SV * const sv = POPs; STRLEN len; const char *s = SvPV_const(sv, len); const bool do_utf8 = DO_UTF8(sv); const char *strend = s + len; - PMOP *pm; + PMOP *pm = cPMOPx(PL_op); REGEXP *rx; SV *dstr; const char *m; @@ -5736,33 +5738,26 @@ PP(pp_split) bool multiline = 0; MAGIC *mg = NULL; -#ifdef DEBUGGING - Copy(&LvTARGOFF(POPs), &pm, 1, PMOP*); -#else - pm = (PMOP*)POPs; -#endif - if (!pm) - DIE(aTHX_ "panic: pp_split, pm=%p, s=%p", pm, s); rx = PM_GETRE(pm); TAINT_IF(get_regex_charset(RX_EXTFLAGS(rx)) == REGEX_LOCALE_CHARSET && (RX_EXTFLAGS(rx) & (RXf_WHITE | RXf_SKIPWHITE))); + if (PL_op->op_private & OPpSPLIT_ASSIGN) { + if (!(PL_op->op_flags & OPf_STACKED)) { + if (PL_op->op_private & OPpSPLIT_LEX) + ary = (AV *)PAD_SVl(pm->op_pmreplrootu.op_pmtargetoff); + else { + GV *gv = #ifdef USE_ITHREADS - if (pm->op_pmreplrootu.op_pmtargetoff) { - ary = GvAVn(MUTABLE_GV(PAD_SVl(pm->op_pmreplrootu.op_pmtargetoff))); - goto have_av; - } + MUTABLE_GV(PAD_SVl(pm->op_pmreplrootu.op_pmtargetoff)); #else - if (pm->op_pmreplrootu.op_pmtargetgv) { - ary = GvAVn(pm->op_pmreplrootu.op_pmtargetgv); - goto have_av; - } + pm->op_pmreplrootu.op_pmtargetgv; #endif - else if (pm->op_targ) - ary = (AV *)PAD_SVl(pm->op_targ); - if (ary) { - have_av: + ary = GvAVn(gv); + } + } + realarray = 1; PUTBACK; av_extend(ary,0); @@ -5786,6 +5781,7 @@ PP(pp_split) make_mortal = 0; } } + base = SP - PL_stack_base; orig = s; if (RX_EXTFLAGS(rx) & RXf_SKIPWHITE) { @@ -104,18 +104,6 @@ PP(pp_regcomp) assert (re != (REGEXP*) &PL_sv_undef); eng = re ? RX_ENGINE(re) : current_re_engine(); - /* - In the below logic: these are basically the same - check if this regcomp is part of a split. - - (PL_op->op_pmflags & PMf_split ) - (PL_op->op_next->op_type == OP_PUSHRE) - - We could add a new mask for this and copy the PMf_split, if we did - some bit definition fiddling first. - - For now we leave this - */ - new_re = (eng->op_comp ? eng->op_comp : &Perl_re_op_compile @@ -860,25 +860,6 @@ PP(pp_join) RETURN; } -PP(pp_pushre) -{ - dSP; -#ifdef DEBUGGING - /* - * We ass_u_me that LvTARGOFF() comes first, and that two STRLENs - * will be enough to hold an OP*. - */ - SV* const sv = sv_newmortal(); - sv_upgrade(sv, SVt_PVLV); - LvTYPE(sv) = '/'; - Copy(&PL_op, &LvTARGOFF(sv), 1, OP*); - XPUSHs(sv); -#else - XPUSHs(MUTABLE_SV(PL_op)); -#endif - RETURN; -} - /* Oversized hot code. */ /* also used for: pp_say() */ diff --git a/pp_proto.h b/pp_proto.h index 16b1729348..e931546799 100644 --- a/pp_proto.h +++ b/pp_proto.h @@ -198,7 +198,6 @@ PERL_CALLCONV OP *Perl_pp_prototype(pTHX); PERL_CALLCONV OP *Perl_pp_prtf(pTHX); PERL_CALLCONV OP *Perl_pp_push(pTHX); PERL_CALLCONV OP *Perl_pp_pushmark(pTHX); -PERL_CALLCONV OP *Perl_pp_pushre(pTHX); PERL_CALLCONV OP *Perl_pp_qr(pTHX); PERL_CALLCONV OP *Perl_pp_quotemeta(pTHX); PERL_CALLCONV OP *Perl_pp_rand(pTHX); @@ -2473,7 +2473,7 @@ PERL_CALLCONV int perl_run(PerlInterpreter *my_perl); #define PERL_ARGS_ASSERT_PERL_RUN \ assert(my_perl) PERL_CALLCONV void Perl_pmop_dump(pTHX_ PMOP* pm); -PERL_CALLCONV OP* Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, bool isreg, I32 floor); +PERL_CALLCONV OP* Perl_pmruntime(pTHX_ OP *o, OP *expr, OP *repl, UV flags, I32 floor); #define PERL_ARGS_ASSERT_PMRUNTIME \ assert(o); assert(expr) PERL_CALLCONV void Perl_pop_scope(pTHX); diff --git a/regen/op_private b/regen/op_private index 4adedbf75e..e511ce145b 100644 --- a/regen/op_private +++ b/regen/op_private @@ -397,8 +397,8 @@ addbits($_, 7 => qw(OPpLVALUE LV)) for qw(leave leaveloop); # Pattern coming in on the stack -addbits($_, 6 => qw(OPpRUNTIME RTIME)) - for qw(match subst substcont qr pushre); +addbits($_, 5 => qw(OPpRUNTIME RTIME)) + for qw(match subst substcont qr split); @@ -731,8 +731,13 @@ addbits('coreargs', -addbits('split', 7 => qw(OPpSPLIT_IMPLIM IMPLIM)); # implicit limit - +addbits('split', + 7 => qw(OPpSPLIT_IMPLIM IMPLIM), # implicit limit + # @a = split() has been replaced with split() where split itself + # does the array assign + 4 => qw(OPpSPLIT_ASSIGN ASSIGN), + 3 => qw(OPpSPLIT_LEX LEX), # the OPpSPLIT_ASSIGN is a lexical array +); addbits($_, diff --git a/regen/opcodes b/regen/opcodes index 6ad9c62fc1..23c8cdc439 100644 --- a/regen/opcodes +++ b/regen/opcodes @@ -57,8 +57,6 @@ padav private array ck_null d0 padhv private hash ck_null d0 padany private value ck_null d0 -pushre push regexp ck_null d/ - # References and stuff. rv2gv ref-to-glob cast ck_rvconst ds1 @@ -253,7 +251,7 @@ multideref array or hash lookup ck_null ds+ unpack unpack ck_fun u@ S S? pack pack ck_fun fmst@ S L -split split ck_split t@ S S S +split split ck_split t/ S S S join join or string ck_join fmst@ S L # List operators. @@ -351,9 +351,8 @@ and check for NULL. */ /* - Set in Perl_pmruntime if op_flags & OPf_SPECIAL, i.e. split. Will - be used by regex engines to check whether they should set - RXf_SKIPWHITE + Set in Perl_pmruntime for a split. Will be used by regex engines to + check whether they should set RXf_SKIPWHITE */ #define RXf_SPLIT RXf_PMf_SPLIT diff --git a/t/op/split.t b/t/op/split.t index 9c19365cc8..6a138b9ed9 100644 --- a/t/op/split.t +++ b/t/op/split.t @@ -7,7 +7,7 @@ BEGIN { set_up_inc('../lib'); } -plan tests => 131; +plan tests => 135; $FS = ':'; @@ -523,3 +523,18 @@ is "@a", '1 2 3', 'assignment to split-to-array (pmtarget/package array)'; } (@{\@a} = split //, "abc") = 1..10; is "@a", '1 2 3', 'assignment to split-to-array (stacked)'; + +# check that re-evals work + +{ + my $c = 0; + @a = split /-(?{ $c++ })/, "a-b-c"; + is "@a", "a b c", "compile-time re-eval"; + is $c, 2, "compile-time re-eval count"; + + my $sep = '-'; + $c = 0; + @a = split /$sep(?{ $c++ })/, "a-b-c"; + is "@a", "a b c", "run-time re-eval"; + is $c, 2, "run-time re-eval count"; +} diff --git a/t/perf/benchmarks b/t/perf/benchmarks index 6c15523488..3daa27d0b7 100644 --- a/t/perf/benchmarks +++ b/t/perf/benchmarks @@ -908,6 +908,7 @@ }, + 'func::sort::num' => { desc => 'plain numeric sort', setup => 'my (@a, @b); @a = reverse 1..10;', @@ -971,6 +972,25 @@ }, + 'func::split::vars' => { + desc => 'split into two lexical vars', + setup => 'my $s = "abc:def";', + code => 'my ($x, $y) = split /:/, $s, 2;', + }, + + 'func::split::array' => { + desc => 'split into a lexical array', + setup => 'my @a; my $s = "abc:def";', + code => '@a = split /:/, $s, 2;', + }, + + 'func::split::myarray' => { + desc => 'split into a lexical array declared in the assign', + setup => 'my $s = "abc:def";', + code => 'my @a = split /:/, $s, 2;', + }, + + 'loop::block' => { desc => 'empty basic loop', setup => '', |