Most ops that execute a regex, such as match and subst, are of type PMOP.
A PMOP allows the actual regex to be attached directly to that op, due
to its extra fields.
OP_SPLIT is different; it is just a plain LISTOP, but it always has an
OP_PUSHRE as its first child, which *is* a PMOP and which has the regex
attached.
At runtime, pp_pushre()'s only job is to push itself (i.e. the current
PL_op) onto the stack. Later pp_split() pops this to get access to the
regex it wants to execute.
This is a bit unpleasant, because we're pushing an OP* onto the stack,
which is supposed to be an array of SV*'s. As a bit of a hack, on
DEBUGGING builds we push a PVLV with the PL_op address embedded instead,
but this still isn't very satisfactory.
Now that regexes are first-class SVs, we could push a REGEXP onto the
stack rather than PL_op. However, there is an optimisation of @array =
split which eliminates the assign and embeds the array's GV/padix directly
in the PUSHRE op. So split still needs access to that op. But the pushre
op will always be splitop->op_first anyway, so one possibility is to just
skip executing the pushre altogether, and make pp_split just directly
access op_first instead to get the regex and @array info.
But if we're doing that, then why not just go the full hog and make
OP_SPLIT into a PMOP, and eliminate the OP_PUSHRE op entirely: with the
data that was spread across the two ops now combined into just the one
split op.
That is exactly what this commit does.
For a simple compile-time pattern like split(/foo/, $s, 1), the optree
looks like:
before:
<@> split[t2] lK
</> pushre(/"foo"/) s/RTIME
<0> padsv[$s:1,2] s
<$> const(IV 1) s
after:
</> split(/"foo"/)[t2] lK/RTIME
<0> padsv[$s:1,2] s
<$> const[IV 1] s
while for a run-time expression like split(/$pat/, $s, 1),
before:
<@> split[t3] lK
</> pushre() sK/RTIME
<|> regcomp(other->8) sK
<0> padsv[$pat:2,3] s
<0> padsv[$s:1,3] s
<$> const(IV 1)s
after:
</> split()[t3] lK/RTIME
<|> regcomp(other->8) sK
<0> padsv[$pat:2,3] s
<0> padsv[$s:1,3] s
<$> const[IV 1] s
This makes the code faster and simpler.
At the same time, two new private flags have been added for OP_SPLIT -
OPpSPLIT_ASSIGN and OPpSPLIT_LEX - which make it explicit that the
assign op has been optimised away, and if so, whether the array is
lexical.
Also, deparsing of split has been improved, to the extent that
perl TEST -deparse op/split.t
now passes.
Also, a couple of panic messages in pp_split() have been replaced with
asserts().
op/postfixderef.t
op/range.t
op/readline.t
-op/split.t
op/srand.t
op/sub.t
op/sub_lval.t
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
}
padav SKIP my @x
padhv SKIP my %x
padany SKIP (not implemented)
-pushre SKIP split /foo/
rv2gv *x
rv2sv $x
av2arylen $#x
(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");
else
PerlIO_printf(file, "DONE\n");
break;
- case OP_PUSHRE:
+ case OP_SPLIT:
case OP_MATCH:
case OP_QR:
case OP_SUBST:
#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
# 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.
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);
}
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 {
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
# 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 =
$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') {
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';
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
$_[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');
%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');
our($VERSION, @ISA, @EXPORT_OK);
-$VERSION = "1.37";
+$VERSION = "1.38";
use Carp;
use Exporter ();
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
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
MDEREF_SHIFT
);
-$VERSION = '1.38';
+$VERSION = '1.39';
use strict;
use vars qw/$AUTOLOAD/;
use warnings ();
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;
} 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);
}
}
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) {
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 { () };
####
$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);
@{$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];
OPpREFCOUNTED => 64,
OPpREPEAT_DOLIST => 64,
OPpREVERSE_INPLACE => 8,
- OPpRUNTIME => 64,
+ OPpRUNTIME => 32,
OPpSLICE => 64,
OPpSLICEWARNING => 4,
OPpSORT_DESCEND => 16,
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,
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',
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)],
$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};
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:
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);
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;
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;
}
}
- 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;
* 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
*/
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;
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;
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 */
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
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;
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;
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;
}
}
}
- }
}
return 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))
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.
/* 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()*/
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 */
"padav",
"padhv",
"padany",
- "pushre",
"rv2gv",
"rv2sv",
"av2arylen",
"private array",
"private hash",
"private value",
- "push regexp",
"ref-to-glob cast",
"scalar dereference",
"array length",
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,
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 */
0x00000040, /* padav */
0x00000040, /* padhv */
0x00000040, /* padany */
- 0x00000540, /* pushre */
0x00000144, /* rv2gv */
0x00000144, /* rv2sv */
0x00000104, /* av2arylen */
0x00000f44, /* multideref */
0x00091480, /* unpack */
0x0002140f, /* pack */
- 0x00111408, /* split */
+ 0x00111508, /* split */
0x0002140f, /* join */
0x00002401, /* list */
0x00224200, /* lslice */
#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
#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
#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
#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
'<','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',
'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',
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,
};
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 */
0, /* defined */
0, /* undef */
0, /* study */
- 39, /* pos */
+ 38, /* pos */
0, /* preinc */
0, /* i_preinc */
0, /* predec */
82, /* vec */
77, /* index */
77, /* rindex */
- 48, /* sprintf */
- 48, /* formline */
+ 47, /* sprintf */
+ 47, /* formline */
71, /* ord */
71, /* chr */
77, /* crypt */
99, /* kvaslice */
0, /* aeach */
0, /* avalues */
- 39, /* akeys */
+ 38, /* akeys */
0, /* each */
0, /* values */
- 39, /* keys */
+ 38, /* keys */
100, /* delete */
103, /* exists */
105, /* rv2hv */
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 */
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 */
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 */
-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 */
};
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 */
};
/* 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),
/* 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),
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
(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
(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.
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;
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);
make_mortal = 0;
}
}
+
base = SP - PL_stack_base;
orig = s;
if (RX_EXTFLAGS(rx) & RXf_SKIPWHITE) {
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
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() */
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);
#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);
# 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);
-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($_,
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
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.
*/
/*
- 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
set_up_inc('../lib');
}
-plan tests => 131;
+plan tests => 135;
$FS = ':';
}
(@{\@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";
+}
},
+
'func::sort::num' => {
desc => 'plain numeric sort',
setup => 'my (@a, @b); @a = reverse 1..10;',
},
+ '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 => '',