summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/Opcode/Opcode.pm1
-rw-r--r--lib/B/Deparse.pm19
-rw-r--r--lib/B/Op_private.pm16
-rw-r--r--opcode.h282
-rw-r--r--opnames.h509
-rw-r--r--peep.c56
-rw-r--r--pp.c45
-rw-r--r--pp_proto.h1
-rw-r--r--regen/op_private11
-rw-r--r--regen/opcodes1
-rw-r--r--t/perf/benchmarks29
-rw-r--r--t/perf/opcount.t96
12 files changed, 665 insertions, 401 deletions
diff --git a/ext/Opcode/Opcode.pm b/ext/Opcode/Opcode.pm
index f81a6a2216..f8615eef0f 100644
--- a/ext/Opcode/Opcode.pm
+++ b/ext/Opcode/Opcode.pm
@@ -336,6 +336,7 @@ invert_opset function.
warn die lineseq nextstate scope enter leave
rv2cv anoncode prototype coreargs avhvswitch anonconst
+ emptyavhv
entersub leavesub leavesublv return method method_named
method_super method_redir method_redir_super
diff --git a/lib/B/Deparse.pm b/lib/B/Deparse.pm
index 3afaba25cd..d84d2a2709 100644
--- a/lib/B/Deparse.pm
+++ b/lib/B/Deparse.pm
@@ -7,14 +7,14 @@
# This is based on the module of the same name by Malcolm Beattie,
# but essentially none of his code remains.
-package B::Deparse 1.70;
+package B::Deparse 1.71;
use strict;
use Carp;
use B qw(class main_root main_start main_cv svref_2object opnumber perlstring
OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST
OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL OPf_MOD OPf_PARENS
OPpLVAL_INTRO OPpOUR_INTRO OPpENTERSUB_AMPER OPpSLICE OPpKVSLICE
- OPpCONST_BARE
+ OPpCONST_BARE OPpEMPTYAVHV_IS_HV
OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY
OPpEXISTS_SUB OPpSORT_NUMERIC OPpSORT_INTEGER OPpREPEAT_DOLIST
OPpSORT_REVERSE OPpMULTIDEREF_EXISTS OPpMULTIDEREF_DELETE
@@ -2785,6 +2785,21 @@ sub pp_anonlist {
*pp_anonhash = \&pp_anonlist;
+sub pp_emptyavhv {
+ my $self = shift;
+ my ($op, $cx, $forbid_parens) = @_;
+ my $val = ($op->private & OPpEMPTYAVHV_IS_HV) ? '{}' : '[]';
+ if ($op->private & OPpTARGET_MY) {
+ my $targ = $op->targ;
+ my $var = $self->maybe_my($op, $cx, $self->padname($targ),
+ $self->padname_sv($targ),
+ $forbid_parens);
+ return $self->maybe_parens("$var = $val", $cx, 7);
+ } else {
+ return $val;
+ }
+}
+
sub pp_refgen {
my $self = shift;
my($op, $cx) = @_;
diff --git a/lib/B/Op_private.pm b/lib/B/Op_private.pm
index 8dc37a2614..bf7528fd1c 100644
--- a/lib/B/Op_private.pm
+++ b/lib/B/Op_private.pm
@@ -134,7 +134,7 @@ $bits{$_}{6} = 'OPpINDEX_BOOLNEG' for qw(index rindex);
$bits{$_}{1} = 'OPpITER_REVERSED' for qw(enteriter iter);
$bits{$_}{7} = 'OPpLVALUE' for qw(leave leaveloop);
$bits{$_}{6} = 'OPpLVAL_DEFER' for qw(aelem helem multideref);
-$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv padsv_store pushmark refassign rv2av rv2gv rv2hv rv2sv split undef);
+$bits{$_}{7} = 'OPpLVAL_INTRO' for qw(aelem aslice cond_expr delete emptyavhv enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv padsv_store pushmark refassign rv2av rv2gv rv2hv rv2sv split undef);
$bits{$_}{2} = 'OPpLVREF_ELEM' for qw(lvref refassign);
$bits{$_}{3} = 'OPpLVREF_ITER' for qw(lvref refassign);
$bits{$_}{3} = 'OPpMAYBE_LVSUB' for qw(aassign aelem akeys aslice av2arylen avhvswitch helem hslice keys kvaslice kvhslice multideref padav padhv pos rv2av rv2gv rv2hv substr values vec);
@@ -145,11 +145,11 @@ $bits{$_}{4} = 'OPpOPEN_IN_RAW' for qw(backtick open);
$bits{$_}{7} = 'OPpOPEN_OUT_CRLF' for qw(backtick open);
$bits{$_}{6} = 'OPpOPEN_OUT_RAW' for qw(backtick open);
$bits{$_}{6} = 'OPpOUR_INTRO' for qw(enteriter gvsv rv2av rv2hv rv2sv split);
-$bits{$_}{6} = 'OPpPAD_STATE' for qw(lvavref lvref padav padhv padsv padsv_store pushmark refassign undef);
+$bits{$_}{6} = 'OPpPAD_STATE' for qw(emptyavhv lvavref lvref padav padhv padsv padsv_store pushmark refassign undef);
$bits{$_}{7} = 'OPpPV_IS_UTF8' for qw(dump goto last next redo);
$bits{$_}{6} = 'OPpREFCOUNTED' for qw(leave leaveeval leavesub leavesublv leavewrite);
$bits{$_}{2} = 'OPpSLICEWARNING' for qw(aslice hslice padav padhv rv2av rv2hv);
-$bits{$_}{4} = 'OPpTARGET_MY' for qw(abs add atan2 ceil chdir chmod chomp chown chr chroot concat cos crypt divide exec exp flock floor getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_subtract index int kill left_shift length link log mkdir modulo multiconcat multiply nbit_and nbit_or nbit_xor ncomplement oct ord pow push rand refaddr reftype rename right_shift rindex rmdir schomp scomplement setpgrp setpriority sin sleep sqrt srand stringify subtract symlink system time undef unlink unshift utime wait waitpid);
+$bits{$_}{4} = 'OPpTARGET_MY' for qw(abs add atan2 ceil chdir chmod chomp chown chr chroot concat cos crypt divide emptyavhv exec exp flock floor getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_subtract index int kill left_shift length link log mkdir modulo multiconcat multiply nbit_and nbit_or nbit_xor ncomplement oct ord pow push rand refaddr reftype rename right_shift rindex rmdir schomp scomplement setpgrp setpriority sin sleep sqrt srand stringify subtract symlink system time undef unlink unshift utime wait waitpid);
$bits{$_}{0} = 'OPpTRANS_CAN_FORCE_UTF8' for qw(trans transr);
$bits{$_}{5} = 'OPpTRANS_COMPLEMENT' for qw(trans transr);
$bits{$_}{7} = 'OPpTRANS_DELETE' for qw(trans transr);
@@ -306,6 +306,7 @@ $bits{dor}{0} = $bf[0];
$bits{dorassign}{0} = $bf[0];
$bits{dump}{0} = $bf[0];
$bits{each}{0} = $bf[0];
+@{$bits{emptyavhv}}{5,3,2,1,0} = ('OPpEMPTYAVHV_IS_HV', $bf[4], $bf[4], $bf[4], $bf[4]);
@{$bits{entereval}}{5,4,3,2,1,0} = ('OPpEVAL_RE_REPARSING', 'OPpEVAL_COPHH', 'OPpEVAL_BYTES', 'OPpEVAL_UNICODE', 'OPpEVAL_HAS_HH', $bf[0]);
$bits{entergiven}{0} = $bf[0];
$bits{enteriter}{3} = 'OPpITER_DEF';
@@ -623,6 +624,7 @@ our %defines = (
OPpDEREF_SV => 48,
OPpDONT_INIT_GV => 4,
OPpEARLY_CV => 32,
+ OPpEMPTYAVHV_IS_HV => 32,
OPpENTERSUB_AMPER => 8,
OPpENTERSUB_DB => 64,
OPpENTERSUB_HASTARG => 4,
@@ -730,6 +732,7 @@ our %labels = (
OPpDEREF_SV => 'DREFSV',
OPpDONT_INIT_GV => 'NOINIT',
OPpEARLY_CV => 'EARLYCV',
+ OPpEMPTYAVHV_IS_HV => 'ANONHASH',
OPpENTERSUB_AMPER => 'AMPER',
OPpENTERSUB_DB => 'DBG',
OPpENTERSUB_HASTARG => 'TARG',
@@ -817,6 +820,7 @@ our %ops_using = (
OPpCOREARGS_DEREF1 => [qw(coreargs)],
OPpDEFER_FINALLY => [qw(pushdefer)],
OPpEARLY_CV => [qw(gv)],
+ OPpEMPTYAVHV_IS_HV => [qw(emptyavhv)],
OPpENTERSUB_AMPER => [qw(entersub rv2cv)],
OPpENTERSUB_INARGS => [qw(entersub)],
OPpENTERSUB_NOPAREN => [qw(rv2cv)],
@@ -834,7 +838,7 @@ our %ops_using = (
OPpLIST_GUESSED => [qw(list)],
OPpLVALUE => [qw(leave leaveloop)],
OPpLVAL_DEFER => [qw(aelem helem multideref)],
- OPpLVAL_INTRO => [qw(aelem aslice cond_expr delete enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv padsv_store pushmark refassign rv2av rv2gv rv2hv rv2sv split undef)],
+ OPpLVAL_INTRO => [qw(aelem aslice cond_expr delete emptyavhv enteriter entersub gvsv helem hslice list lvavref lvref lvrefslice multiconcat multideref padav padhv padrange padsv padsv_store pushmark refassign rv2av rv2gv rv2hv rv2sv split undef)],
OPpLVREF_ELEM => [qw(lvref refassign)],
OPpMAYBE_LVSUB => [qw(aassign aelem akeys aslice av2arylen avhvswitch helem hslice keys kvaslice kvhslice multideref padav padhv pos rv2av rv2gv rv2hv substr values vec)],
OPpMAYBE_TRUEBOOL => [qw(blessed padhv ref rv2hv)],
@@ -844,7 +848,7 @@ our %ops_using = (
OPpOPEN_IN_CRLF => [qw(backtick open)],
OPpOUR_INTRO => [qw(enteriter gvsv rv2av rv2hv rv2sv split)],
OPpPADHV_ISKEYS => [qw(padhv)],
- OPpPAD_STATE => [qw(lvavref lvref padav padhv padsv padsv_store pushmark refassign undef)],
+ OPpPAD_STATE => [qw(emptyavhv lvavref lvref padav padhv padsv padsv_store pushmark refassign undef)],
OPpPV_IS_UTF8 => [qw(dump goto last next redo)],
OPpREFCOUNTED => [qw(leave leaveeval leavesub leavesublv leavewrite)],
OPpREPEAT_DOLIST => [qw(repeat)],
@@ -854,7 +858,7 @@ our %ops_using = (
OPpSORT_DESCEND => [qw(sort)],
OPpSPLIT_ASSIGN => [qw(split)],
OPpSUBSTR_REPL_FIRST => [qw(substr)],
- OPpTARGET_MY => [qw(abs add atan2 ceil chdir chmod chomp chown chr chroot concat cos crypt divide exec exp flock floor getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_subtract index int kill left_shift length link log mkdir modulo multiconcat multiply nbit_and nbit_or nbit_xor ncomplement oct ord pow push rand refaddr reftype rename right_shift rindex rmdir schomp scomplement setpgrp setpriority sin sleep sqrt srand stringify subtract symlink system time undef unlink unshift utime wait waitpid)],
+ OPpTARGET_MY => [qw(abs add atan2 ceil chdir chmod chomp chown chr chroot concat cos crypt divide emptyavhv exec exp flock floor getpgrp getppid getpriority hex i_add i_divide i_modulo i_multiply i_subtract index int kill left_shift length link log mkdir modulo multiconcat multiply nbit_and nbit_or nbit_xor ncomplement oct ord pow push rand refaddr reftype rename right_shift rindex rmdir schomp scomplement setpgrp setpriority sin sleep sqrt srand stringify subtract symlink system time undef unlink unshift utime wait waitpid)],
OPpTRANS_CAN_FORCE_UTF8 => [qw(trans transr)],
OPpTRUEBOOL => [qw(blessed grepwhile index length padav padhv pos ref rindex rv2av rv2hv subst)],
OPpUNDEF_KEEP_PV => [qw(undef)],
diff --git a/opcode.h b/opcode.h
index 616d0c9eea..55b44de68c 100644
--- a/opcode.h
+++ b/opcode.h
@@ -313,6 +313,7 @@ EXTCONST char* const PL_op_name[] = {
"lslice",
"anonlist",
"anonhash",
+ "emptyavhv",
"splice",
"push",
"pop",
@@ -738,6 +739,7 @@ EXTCONST char* const PL_op_desc[] = {
"list slice",
"anonymous array ([])",
"anonymous hash ({})",
+ "empty anon hash/array",
"splice",
"push",
"pop",
@@ -1166,6 +1168,7 @@ EXT Perl_ppaddr_t PL_ppaddr[] /* or perlvars.h */
Perl_pp_lslice,
Perl_pp_anonlist,
Perl_pp_anonhash,
+ Perl_pp_emptyavhv,
Perl_pp_splice,
Perl_pp_push,
Perl_pp_pop, /* implemented by Perl_pp_shift */
@@ -1590,6 +1593,7 @@ EXT Perl_check_t PL_check[] /* or perlvars.h */
Perl_ck_null, /* lslice */
Perl_ck_fun, /* anonlist */
Perl_ck_fun, /* anonhash */
+ Perl_ck_fun, /* emptyavhv */
Perl_ck_fun, /* splice */
Perl_ck_fun, /* push */
Perl_ck_shift, /* pop */
@@ -2015,6 +2019,7 @@ EXTCONST U32 PL_opargs[] = {
0x00224200, /* lslice */
0x00002405, /* anonlist */
0x00002405, /* anonhash */
+ 0x0000241c, /* emptyavhv */
0x02993401, /* splice */
0x0002341d, /* push */
0x0000bb04, /* pop */
@@ -2339,6 +2344,7 @@ END_EXTERN_C
#define OPpASSIGN_COMMON_RC1 0x20
#define OPpDEREF_HV 0x20
#define OPpEARLY_CV 0x20
+#define OPpEMPTYAVHV_IS_HV 0x20
#define OPpEVAL_RE_REPARSING 0x20
#define OPpHUSH_VMSISH 0x20
#define OPpKVSLICE 0x20
@@ -2410,6 +2416,7 @@ EXTCONST char PL_op_private_labels[] = {
'+','1','\0',
'-','\0',
'A','M','P','E','R','\0',
+ 'A','N','O','N','H','A','S','H','\0',
'A','P','P','E','N','D','\0',
'A','S','S','I','G','N','\0',
'A','V','\0',
@@ -2521,14 +2528,14 @@ EXTCONST char PL_op_private_labels[] = {
EXTCONST I16 PL_op_private_bitfields[] = {
0, 8, -1,
0, 8, -1,
- 0, 604, -1,
+ 0, 613, -1,
0, 8, -1,
0, 8, -1,
- 0, 611, -1,
- 0, 600, -1,
- 1, -1, 0, 561, 1, 30, 2, 303, -1,
- 4, -1, 1, 176, 2, 183, 3, 190, -1,
- 4, -1, 0, 561, 1, 30, 2, 303, 3, 122, -1,
+ 0, 620, -1,
+ 0, 609, -1,
+ 1, -1, 0, 570, 1, 39, 2, 312, -1,
+ 4, -1, 1, 185, 2, 192, 3, 199, -1,
+ 4, -1, 0, 570, 1, 39, 2, 312, 3, 131, -1,
};
@@ -2701,55 +2708,56 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
12, /* lslice */
55, /* anonlist */
55, /* anonhash */
+ 163, /* emptyavhv */
55, /* splice */
101, /* push */
0, /* pop */
0, /* shift */
101, /* unshift */
- 163, /* sort */
- 168, /* reverse */
+ 168, /* sort */
+ 173, /* reverse */
0, /* grepstart */
- 170, /* grepwhile */
+ 175, /* grepwhile */
0, /* mapstart */
0, /* mapwhile */
0, /* range */
- 172, /* flip */
- 172, /* flop */
+ 177, /* flip */
+ 177, /* flop */
0, /* and */
0, /* or */
12, /* xor */
0, /* dor */
- 174, /* cond_expr */
+ 179, /* cond_expr */
0, /* andassign */
0, /* orassign */
0, /* dorassign */
- 176, /* entersub */
- 183, /* leavesub */
- 183, /* leavesublv */
+ 181, /* entersub */
+ 188, /* leavesub */
+ 188, /* leavesublv */
0, /* argcheck */
- 185, /* argelem */
+ 190, /* argelem */
0, /* argdefelem */
- 187, /* caller */
+ 192, /* caller */
55, /* warn */
55, /* die */
55, /* reset */
-1, /* lineseq */
- 189, /* nextstate */
- 189, /* dbstate */
+ 194, /* nextstate */
+ 194, /* dbstate */
-1, /* unstack */
-1, /* enter */
- 190, /* leave */
+ 195, /* leave */
-1, /* scope */
- 192, /* enteriter */
- 196, /* iter */
+ 197, /* enteriter */
+ 201, /* iter */
-1, /* enterloop */
- 197, /* leaveloop */
+ 202, /* leaveloop */
-1, /* return */
- 199, /* last */
- 199, /* next */
- 199, /* redo */
- 199, /* dump */
- 199, /* goto */
+ 204, /* last */
+ 204, /* next */
+ 204, /* redo */
+ 204, /* dump */
+ 204, /* goto */
55, /* exit */
0, /* method */
0, /* method_named */
@@ -2762,7 +2770,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* leavewhen */
-1, /* break */
-1, /* continue */
- 201, /* open */
+ 206, /* open */
55, /* close */
55, /* pipe_op */
55, /* fileno */
@@ -2778,7 +2786,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
55, /* getc */
55, /* read */
55, /* enterwrite */
- 183, /* leavewrite */
+ 188, /* leavewrite */
-1, /* prtf */
-1, /* print */
-1, /* say */
@@ -2808,33 +2816,33 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* getpeername */
0, /* lstat */
0, /* stat */
- 206, /* ftrread */
- 206, /* ftrwrite */
- 206, /* ftrexec */
- 206, /* fteread */
- 206, /* ftewrite */
- 206, /* fteexec */
- 211, /* ftis */
- 211, /* ftsize */
- 211, /* ftmtime */
- 211, /* ftatime */
- 211, /* ftctime */
- 211, /* ftrowned */
- 211, /* fteowned */
- 211, /* ftzero */
- 211, /* ftsock */
- 211, /* ftchr */
- 211, /* ftblk */
- 211, /* ftfile */
- 211, /* ftdir */
- 211, /* ftpipe */
- 211, /* ftsuid */
- 211, /* ftsgid */
- 211, /* ftsvtx */
- 211, /* ftlink */
- 211, /* fttty */
- 211, /* fttext */
- 211, /* ftbinary */
+ 211, /* ftrread */
+ 211, /* ftrwrite */
+ 211, /* ftrexec */
+ 211, /* fteread */
+ 211, /* ftewrite */
+ 211, /* fteexec */
+ 216, /* ftis */
+ 216, /* ftsize */
+ 216, /* ftmtime */
+ 216, /* ftatime */
+ 216, /* ftctime */
+ 216, /* ftrowned */
+ 216, /* fteowned */
+ 216, /* ftzero */
+ 216, /* ftsock */
+ 216, /* ftchr */
+ 216, /* ftblk */
+ 216, /* ftfile */
+ 216, /* ftdir */
+ 216, /* ftpipe */
+ 216, /* ftsuid */
+ 216, /* ftsgid */
+ 216, /* ftsvtx */
+ 216, /* ftlink */
+ 216, /* fttty */
+ 216, /* fttext */
+ 216, /* ftbinary */
101, /* chdir */
101, /* chown */
78, /* chroot */
@@ -2854,17 +2862,17 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* rewinddir */
0, /* closedir */
-1, /* fork */
- 215, /* wait */
+ 220, /* wait */
101, /* waitpid */
101, /* system */
101, /* exec */
101, /* kill */
- 215, /* getppid */
+ 220, /* getppid */
101, /* getpgrp */
101, /* setpgrp */
101, /* getpriority */
101, /* setpriority */
- 215, /* time */
+ 220, /* time */
-1, /* tms */
0, /* localtime */
55, /* gmtime */
@@ -2884,8 +2892,8 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* require */
0, /* dofile */
-1, /* hintseval */
- 216, /* entereval */
- 183, /* leaveeval */
+ 221, /* entereval */
+ 188, /* leaveeval */
0, /* entertry */
-1, /* leavetry */
0, /* ghbyname */
@@ -2923,17 +2931,17 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
0, /* lock */
0, /* once */
-1, /* custom */
- 222, /* coreargs */
- 226, /* avhvswitch */
+ 227, /* coreargs */
+ 231, /* avhvswitch */
3, /* runcv */
0, /* fc */
-1, /* padcv */
-1, /* introcv */
-1, /* clonecv */
- 228, /* padrange */
- 230, /* refassign */
- 236, /* lvref */
- 242, /* lvrefslice */
+ 233, /* padrange */
+ 235, /* refassign */
+ 241, /* lvref */
+ 247, /* lvrefslice */
16, /* lvavref */
0, /* anonconst */
12, /* isa */
@@ -2943,7 +2951,7 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
-1, /* leavetrycatch */
-1, /* poptry */
0, /* catch */
- 243, /* pushdefer */
+ 248, /* pushdefer */
0, /* is_bool */
0, /* is_weak */
0, /* weaken */
@@ -2973,79 +2981,80 @@ EXTCONST I16 PL_op_private_bitdef_ix[] = {
EXTCONST U16 PL_op_private_bitdefs[] = {
0x0003, /* scalar, prototype, refgen, srefgen, readline, regcmaybe, regcreset, regcomp, substcont, chop, schop, defined, study, preinc, i_preinc, predec, i_predec, postinc, i_postinc, postdec, i_postdec, negate, i_negate, not, ucfirst, lcfirst, uc, lc, quotemeta, aeach, avalues, each, pop, shift, grepstart, mapstart, mapwhile, range, and, or, dor, andassign, orassign, dorassign, argcheck, argdefelem, method, 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, cmpchain_and, cmpchain_dup, entertrycatch, catch, is_bool, is_weak, weaken, unweaken, is_tainted */
- 0x31dc, 0x42d9, /* pushmark */
+ 0x32fc, 0x43f9, /* pushmark */
0x00bd, /* wantarray, runcv */
- 0x0438, 0x1a50, 0x438c, 0x3f28, 0x3705, /* const */
- 0x31dc, 0x3859, /* gvsv */
- 0x18b5, /* gv */
+ 0x0558, 0x1b70, 0x44ac, 0x4048, 0x3825, /* const */
+ 0x32fc, 0x3979, /* gvsv */
+ 0x19d5, /* 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, smartmatch, lslice, xor, isa */
- 0x31dc, 0x42d8, 0x03d7, /* padsv */
- 0x31dc, 0x42d8, 0x0003, /* padsv_store, lvavref */
- 0x31dc, 0x42d8, 0x05b4, 0x32cc, 0x40a9, /* padav */
- 0x31dc, 0x42d8, 0x05b4, 0x0650, 0x32cc, 0x40a8, 0x2d41, /* padhv */
- 0x31dc, 0x1c38, 0x03d6, 0x32cc, 0x3628, 0x4384, 0x0003, /* rv2gv */
- 0x31dc, 0x3858, 0x03d6, 0x4384, 0x0003, /* rv2sv */
- 0x32cc, 0x0003, /* av2arylen, akeys, values, keys */
- 0x359c, 0x1078, 0x0dd4, 0x014c, 0x4688, 0x4384, 0x0003, /* rv2cv */
- 0x05b4, 0x0650, 0x0003, /* ref, blessed */
+ 0x32fc, 0x43f8, 0x03d7, /* padsv */
+ 0x32fc, 0x43f8, 0x0003, /* padsv_store, lvavref */
+ 0x32fc, 0x43f8, 0x06d4, 0x33ec, 0x41c9, /* padav */
+ 0x32fc, 0x43f8, 0x06d4, 0x0770, 0x33ec, 0x41c8, 0x2e61, /* padhv */
+ 0x32fc, 0x1d58, 0x03d6, 0x33ec, 0x3748, 0x44a4, 0x0003, /* rv2gv */
+ 0x32fc, 0x3978, 0x03d6, 0x44a4, 0x0003, /* rv2sv */
+ 0x33ec, 0x0003, /* av2arylen, akeys, values, keys */
+ 0x36bc, 0x1198, 0x0ef4, 0x014c, 0x47a8, 0x44a4, 0x0003, /* rv2cv */
+ 0x06d4, 0x0770, 0x0003, /* ref, blessed */
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 */
- 0x3a3c, 0x3958, 0x2994, 0x28d0, 0x0003, /* backtick */
- 0x05b5, /* subst */
- 0x117c, 0x22b8, 0x09b4, 0x41ec, 0x2648, 0x4964, 0x07c1, /* trans, transr */
- 0x0fbc, 0x04d8, 0x0067, /* sassign */
- 0x0c78, 0x0b74, 0x0a70, 0x32cc, 0x05a8, 0x0067, /* aassign */
- 0x4730, 0x0003, /* chomp, schomp, scomplement, sin, cos, exp, log, sqrt, int, hex, oct, abs, ord, chr, chroot, rmdir, refaddr, reftype, ceil, floor */
- 0x31dc, 0x42d8, 0x2c54, 0x4730, 0x0003, /* undef */
- 0x05b4, 0x32cc, 0x0003, /* pos */
- 0x4730, 0x0067, /* pow, multiply, i_multiply, divide, i_divide, modulo, i_modulo, add, i_add, subtract, i_subtract */
- 0x1538, 0x0067, /* repeat */
- 0x34b8, 0x4730, 0x0067, /* concat */
- 0x31dc, 0x0218, 0x1c34, 0x4730, 0x446c, 0x0003, /* multiconcat */
- 0x4730, 0x018f, /* stringify, atan2, rand, srand, crypt, push, unshift, flock, chdir, chown, unlink, chmod, utime, rename, link, symlink, mkdir, waitpid, system, exec, kill, getpgrp, setpgrp, getpriority, setpriority, sleep */
- 0x4730, 0x4889, /* left_shift, right_shift, nbit_and, nbit_xor, nbit_or, ncomplement */
- 0x4889, /* bit_and, bit_xor, bit_or, sbit_and, sbit_xor, sbit_or, complement */
- 0x05b4, 0x4730, 0x0003, /* length */
- 0x3c90, 0x32cc, 0x012b, /* substr */
- 0x32cc, 0x0067, /* vec */
- 0x3438, 0x05b4, 0x4730, 0x018f, /* index, rindex */
- 0x31dc, 0x3858, 0x05b4, 0x32cc, 0x40a8, 0x4384, 0x0003, /* rv2av */
+ 0x3b5c, 0x3a78, 0x2ab4, 0x29f0, 0x0003, /* backtick */
+ 0x06d5, /* subst */
+ 0x129c, 0x23d8, 0x0ad4, 0x430c, 0x2768, 0x4a84, 0x08e1, /* trans, transr */
+ 0x10dc, 0x05f8, 0x0067, /* sassign */
+ 0x0d98, 0x0c94, 0x0b90, 0x33ec, 0x06c8, 0x0067, /* aassign */
+ 0x4850, 0x0003, /* chomp, schomp, scomplement, sin, cos, exp, log, sqrt, int, hex, oct, abs, ord, chr, chroot, rmdir, refaddr, reftype, ceil, floor */
+ 0x32fc, 0x43f8, 0x2d74, 0x4850, 0x0003, /* undef */
+ 0x06d4, 0x33ec, 0x0003, /* pos */
+ 0x4850, 0x0067, /* pow, multiply, i_multiply, divide, i_divide, modulo, i_modulo, add, i_add, subtract, i_subtract */
+ 0x1658, 0x0067, /* repeat */
+ 0x35d8, 0x4850, 0x0067, /* concat */
+ 0x32fc, 0x0338, 0x1d54, 0x4850, 0x458c, 0x0003, /* multiconcat */
+ 0x4850, 0x018f, /* stringify, atan2, rand, srand, crypt, push, unshift, flock, chdir, chown, unlink, chmod, utime, rename, link, symlink, mkdir, waitpid, system, exec, kill, getpgrp, setpgrp, getpriority, setpriority, sleep */
+ 0x4850, 0x49a9, /* left_shift, right_shift, nbit_and, nbit_xor, nbit_or, ncomplement */
+ 0x49a9, /* bit_and, bit_xor, bit_or, sbit_and, sbit_xor, sbit_or, complement */
+ 0x06d4, 0x4850, 0x0003, /* length */
+ 0x3db0, 0x33ec, 0x012b, /* substr */
+ 0x33ec, 0x0067, /* vec */
+ 0x3558, 0x06d4, 0x4850, 0x018f, /* index, rindex */
+ 0x32fc, 0x3978, 0x06d4, 0x33ec, 0x41c8, 0x44a4, 0x0003, /* rv2av */
0x025f, /* aelemfast, aelemfast_lex, aelemfastlex_store */
- 0x31dc, 0x30d8, 0x03d6, 0x32cc, 0x0067, /* aelem, helem */
- 0x31dc, 0x32cc, 0x40a9, /* aslice, hslice */
- 0x32cd, /* kvaslice, kvhslice */
- 0x31dc, 0x3ff8, 0x2df4, 0x0003, /* delete */
- 0x45b8, 0x0003, /* exists */
- 0x31dc, 0x3858, 0x05b4, 0x0650, 0x32cc, 0x40a8, 0x4384, 0x2d41, /* rv2hv */
- 0x31dc, 0x30d8, 0x11f4, 0x1b50, 0x32cc, 0x4384, 0x0003, /* multideref */
- 0x31dc, 0x3858, 0x02f0, 0x2eec, 0x2709, /* split */
- 0x31dc, 0x2379, /* list */
- 0x1490, 0x2a2c, 0x3d88, 0x2b24, 0x37c1, /* sort */
- 0x2a2c, 0x0003, /* reverse */
- 0x05b4, 0x0003, /* grepwhile */
- 0x2f78, 0x0003, /* flip, flop */
- 0x31dc, 0x0003, /* cond_expr */
- 0x31dc, 0x1078, 0x03d6, 0x014c, 0x4688, 0x4384, 0x27e1, /* entersub */
- 0x3af8, 0x0003, /* leavesub, leavesublv, leavewrite, leaveeval */
+ 0x32fc, 0x31f8, 0x03d6, 0x33ec, 0x0067, /* aelem, helem */
+ 0x32fc, 0x33ec, 0x41c9, /* aslice, hslice */
+ 0x33ed, /* kvaslice, kvhslice */
+ 0x32fc, 0x4118, 0x2f14, 0x0003, /* delete */
+ 0x46d8, 0x0003, /* exists */
+ 0x32fc, 0x3978, 0x06d4, 0x0770, 0x33ec, 0x41c8, 0x44a4, 0x2e61, /* rv2hv */
+ 0x32fc, 0x31f8, 0x1314, 0x1c70, 0x33ec, 0x44a4, 0x0003, /* multideref */
+ 0x32fc, 0x3978, 0x0410, 0x300c, 0x2829, /* split */
+ 0x32fc, 0x2499, /* list */
+ 0x32fc, 0x43f8, 0x0214, 0x4850, 0x018f, /* emptyavhv */
+ 0x15b0, 0x2b4c, 0x3ea8, 0x2c44, 0x38e1, /* sort */
+ 0x2b4c, 0x0003, /* reverse */
+ 0x06d4, 0x0003, /* grepwhile */
+ 0x3098, 0x0003, /* flip, flop */
+ 0x32fc, 0x0003, /* cond_expr */
+ 0x32fc, 0x1198, 0x03d6, 0x014c, 0x47a8, 0x44a4, 0x2901, /* entersub */
+ 0x3c18, 0x0003, /* leavesub, leavesublv, leavewrite, leaveeval */
0x02aa, 0x0003, /* argelem */
0x00bc, 0x018f, /* caller */
- 0x2555, /* nextstate, dbstate */
- 0x307c, 0x3af9, /* leave */
- 0x31dc, 0x3858, 0x10ec, 0x3e05, /* enteriter */
- 0x3e05, /* iter */
- 0x307c, 0x0067, /* leaveloop */
- 0x4a9c, 0x0003, /* last, next, redo, dump, goto */
- 0x3a3c, 0x3958, 0x2994, 0x28d0, 0x018f, /* open */
- 0x1ef0, 0x214c, 0x2008, 0x1dc4, 0x0003, /* ftrread, ftrwrite, ftrexec, fteread, ftewrite, fteexec */
- 0x1ef0, 0x214c, 0x2008, 0x0003, /* ftis, ftsize, ftmtime, ftatime, ftctime, ftrowned, fteowned, ftzero, ftsock, ftchr, ftblk, ftfile, ftdir, ftpipe, ftsuid, ftsgid, ftsvtx, ftlink, fttty, fttext, ftbinary */
- 0x4731, /* wait, getppid, time */
- 0x3b94, 0x0e90, 0x070c, 0x4808, 0x2464, 0x0003, /* entereval */
- 0x339c, 0x0018, 0x13a4, 0x12c1, /* coreargs */
- 0x32cc, 0x00c7, /* avhvswitch */
- 0x31dc, 0x01fb, /* padrange */
- 0x31dc, 0x42d8, 0x04f6, 0x2bac, 0x19a8, 0x0067, /* refassign */
- 0x31dc, 0x42d8, 0x04f6, 0x2bac, 0x19a8, 0x0003, /* lvref */
- 0x31dd, /* lvrefslice */
- 0x1cdc, 0x0003, /* pushdefer */
+ 0x2675, /* nextstate, dbstate */
+ 0x319c, 0x3c19, /* leave */
+ 0x32fc, 0x3978, 0x120c, 0x3f25, /* enteriter */
+ 0x3f25, /* iter */
+ 0x319c, 0x0067, /* leaveloop */
+ 0x4bbc, 0x0003, /* last, next, redo, dump, goto */
+ 0x3b5c, 0x3a78, 0x2ab4, 0x29f0, 0x018f, /* open */
+ 0x2010, 0x226c, 0x2128, 0x1ee4, 0x0003, /* ftrread, ftrwrite, ftrexec, fteread, ftewrite, fteexec */
+ 0x2010, 0x226c, 0x2128, 0x0003, /* ftis, ftsize, ftmtime, ftatime, ftctime, ftrowned, fteowned, ftzero, ftsock, ftchr, ftblk, ftfile, ftdir, ftpipe, ftsuid, ftsgid, ftsvtx, ftlink, fttty, fttext, ftbinary */
+ 0x4851, /* wait, getppid, time */
+ 0x3cb4, 0x0fb0, 0x082c, 0x4928, 0x2584, 0x0003, /* entereval */
+ 0x34bc, 0x0018, 0x14c4, 0x13e1, /* coreargs */
+ 0x33ec, 0x00c7, /* avhvswitch */
+ 0x32fc, 0x01fb, /* padrange */
+ 0x32fc, 0x43f8, 0x04f6, 0x2ccc, 0x1ac8, 0x0067, /* refassign */
+ 0x32fc, 0x43f8, 0x04f6, 0x2ccc, 0x1ac8, 0x0003, /* lvref */
+ 0x32fd, /* lvrefslice */
+ 0x1dfc, 0x0003, /* pushdefer */
};
@@ -3218,6 +3227,7 @@ EXTCONST U8 PL_op_private_valid[] = {
/* LSLICE */ (OPpARG2_MASK),
/* ANONLIST */ (OPpARG4_MASK),
/* ANONHASH */ (OPpARG4_MASK),
+ /* EMPTYAVHV */ (OPpARG4_MASK|OPpTARGET_MY|OPpEMPTYAVHV_IS_HV|OPpPAD_STATE|OPpLVAL_INTRO),
/* SPLICE */ (OPpARG4_MASK),
/* PUSH */ (OPpARG4_MASK|OPpTARGET_MY),
/* POP */ (OPpARG1_MASK),
diff --git a/opnames.h b/opnames.h
index 3e1751006d..b86f00b7f2 100644
--- a/opnames.h
+++ b/opnames.h
@@ -178,263 +178,264 @@ typedef enum opcode {
OP_LSLICE = 161,
OP_ANONLIST = 162,
OP_ANONHASH = 163,
- OP_SPLICE = 164,
- OP_PUSH = 165,
- OP_POP = 166,
- OP_SHIFT = 167,
- OP_UNSHIFT = 168,
- OP_SORT = 169,
- OP_REVERSE = 170,
- OP_GREPSTART = 171,
- OP_GREPWHILE = 172,
- OP_MAPSTART = 173,
- OP_MAPWHILE = 174,
- OP_RANGE = 175,
- OP_FLIP = 176,
- OP_FLOP = 177,
- OP_AND = 178,
- OP_OR = 179,
- OP_XOR = 180,
- OP_DOR = 181,
- OP_COND_EXPR = 182,
- OP_ANDASSIGN = 183,
- OP_ORASSIGN = 184,
- OP_DORASSIGN = 185,
- OP_ENTERSUB = 186,
- OP_LEAVESUB = 187,
- OP_LEAVESUBLV = 188,
- OP_ARGCHECK = 189,
- OP_ARGELEM = 190,
- OP_ARGDEFELEM = 191,
- OP_CALLER = 192,
- OP_WARN = 193,
- OP_DIE = 194,
- OP_RESET = 195,
- OP_LINESEQ = 196,
- OP_NEXTSTATE = 197,
- OP_DBSTATE = 198,
- OP_UNSTACK = 199,
- OP_ENTER = 200,
- OP_LEAVE = 201,
- OP_SCOPE = 202,
- OP_ENTERITER = 203,
- OP_ITER = 204,
- OP_ENTERLOOP = 205,
- OP_LEAVELOOP = 206,
- OP_RETURN = 207,
- OP_LAST = 208,
- OP_NEXT = 209,
- OP_REDO = 210,
- OP_DUMP = 211,
- OP_GOTO = 212,
- OP_EXIT = 213,
- OP_METHOD = 214,
- OP_METHOD_NAMED = 215,
- OP_METHOD_SUPER = 216,
- OP_METHOD_REDIR = 217,
- OP_METHOD_REDIR_SUPER = 218,
- OP_ENTERGIVEN = 219,
- OP_LEAVEGIVEN = 220,
- OP_ENTERWHEN = 221,
- OP_LEAVEWHEN = 222,
- OP_BREAK = 223,
- OP_CONTINUE = 224,
- OP_OPEN = 225,
- OP_CLOSE = 226,
- OP_PIPE_OP = 227,
- OP_FILENO = 228,
- OP_UMASK = 229,
- OP_BINMODE = 230,
- OP_TIE = 231,
- OP_UNTIE = 232,
- OP_TIED = 233,
- OP_DBMOPEN = 234,
- OP_DBMCLOSE = 235,
- OP_SSELECT = 236,
- OP_SELECT = 237,
- OP_GETC = 238,
- OP_READ = 239,
- OP_ENTERWRITE = 240,
- OP_LEAVEWRITE = 241,
- OP_PRTF = 242,
- OP_PRINT = 243,
- OP_SAY = 244,
- OP_SYSOPEN = 245,
- OP_SYSSEEK = 246,
- OP_SYSREAD = 247,
- OP_SYSWRITE = 248,
- OP_EOF = 249,
- OP_TELL = 250,
- OP_SEEK = 251,
- OP_TRUNCATE = 252,
- OP_FCNTL = 253,
- OP_IOCTL = 254,
- OP_FLOCK = 255,
- OP_SEND = 256,
- OP_RECV = 257,
- OP_SOCKET = 258,
- OP_SOCKPAIR = 259,
- OP_BIND = 260,
- OP_CONNECT = 261,
- OP_LISTEN = 262,
- OP_ACCEPT = 263,
- OP_SHUTDOWN = 264,
- OP_GSOCKOPT = 265,
- OP_SSOCKOPT = 266,
- OP_GETSOCKNAME = 267,
- OP_GETPEERNAME = 268,
- OP_LSTAT = 269,
- OP_STAT = 270,
- OP_FTRREAD = 271,
- OP_FTRWRITE = 272,
- OP_FTREXEC = 273,
- OP_FTEREAD = 274,
- OP_FTEWRITE = 275,
- OP_FTEEXEC = 276,
- OP_FTIS = 277,
- OP_FTSIZE = 278,
- OP_FTMTIME = 279,
- OP_FTATIME = 280,
- OP_FTCTIME = 281,
- OP_FTROWNED = 282,
- OP_FTEOWNED = 283,
- OP_FTZERO = 284,
- OP_FTSOCK = 285,
- OP_FTCHR = 286,
- OP_FTBLK = 287,
- OP_FTFILE = 288,
- OP_FTDIR = 289,
- OP_FTPIPE = 290,
- OP_FTSUID = 291,
- OP_FTSGID = 292,
- OP_FTSVTX = 293,
- OP_FTLINK = 294,
- OP_FTTTY = 295,
- OP_FTTEXT = 296,
- OP_FTBINARY = 297,
- OP_CHDIR = 298,
- OP_CHOWN = 299,
- OP_CHROOT = 300,
- OP_UNLINK = 301,
- OP_CHMOD = 302,
- OP_UTIME = 303,
- OP_RENAME = 304,
- OP_LINK = 305,
- OP_SYMLINK = 306,
- OP_READLINK = 307,
- OP_MKDIR = 308,
- OP_RMDIR = 309,
- OP_OPEN_DIR = 310,
- OP_READDIR = 311,
- OP_TELLDIR = 312,
- OP_SEEKDIR = 313,
- OP_REWINDDIR = 314,
- OP_CLOSEDIR = 315,
- OP_FORK = 316,
- OP_WAIT = 317,
- OP_WAITPID = 318,
- OP_SYSTEM = 319,
- OP_EXEC = 320,
- OP_KILL = 321,
- OP_GETPPID = 322,
- OP_GETPGRP = 323,
- OP_SETPGRP = 324,
- OP_GETPRIORITY = 325,
- OP_SETPRIORITY = 326,
- OP_TIME = 327,
- OP_TMS = 328,
- OP_LOCALTIME = 329,
- OP_GMTIME = 330,
- OP_ALARM = 331,
- OP_SLEEP = 332,
- OP_SHMGET = 333,
- OP_SHMCTL = 334,
- OP_SHMREAD = 335,
- OP_SHMWRITE = 336,
- OP_MSGGET = 337,
- OP_MSGCTL = 338,
- OP_MSGSND = 339,
- OP_MSGRCV = 340,
- OP_SEMOP = 341,
- OP_SEMGET = 342,
- OP_SEMCTL = 343,
- OP_REQUIRE = 344,
- OP_DOFILE = 345,
- OP_HINTSEVAL = 346,
- OP_ENTEREVAL = 347,
- OP_LEAVEEVAL = 348,
- OP_ENTERTRY = 349,
- OP_LEAVETRY = 350,
- OP_GHBYNAME = 351,
- OP_GHBYADDR = 352,
- OP_GHOSTENT = 353,
- OP_GNBYNAME = 354,
- OP_GNBYADDR = 355,
- OP_GNETENT = 356,
- OP_GPBYNAME = 357,
- OP_GPBYNUMBER = 358,
- OP_GPROTOENT = 359,
- OP_GSBYNAME = 360,
- OP_GSBYPORT = 361,
- OP_GSERVENT = 362,
- OP_SHOSTENT = 363,
- OP_SNETENT = 364,
- OP_SPROTOENT = 365,
- OP_SSERVENT = 366,
- OP_EHOSTENT = 367,
- OP_ENETENT = 368,
- OP_EPROTOENT = 369,
- OP_ESERVENT = 370,
- OP_GPWNAM = 371,
- OP_GPWUID = 372,
- OP_GPWENT = 373,
- OP_SPWENT = 374,
- OP_EPWENT = 375,
- OP_GGRNAM = 376,
- OP_GGRGID = 377,
- OP_GGRENT = 378,
- OP_SGRENT = 379,
- OP_EGRENT = 380,
- OP_GETLOGIN = 381,
- OP_SYSCALL = 382,
- OP_LOCK = 383,
- OP_ONCE = 384,
- OP_CUSTOM = 385,
- OP_COREARGS = 386,
- OP_AVHVSWITCH = 387,
- OP_RUNCV = 388,
- OP_FC = 389,
- OP_PADCV = 390,
- OP_INTROCV = 391,
- OP_CLONECV = 392,
- OP_PADRANGE = 393,
- OP_REFASSIGN = 394,
- OP_LVREF = 395,
- OP_LVREFSLICE = 396,
- OP_LVAVREF = 397,
- OP_ANONCONST = 398,
- OP_ISA = 399,
- OP_CMPCHAIN_AND = 400,
- OP_CMPCHAIN_DUP = 401,
- OP_ENTERTRYCATCH = 402,
- OP_LEAVETRYCATCH = 403,
- OP_POPTRY = 404,
- OP_CATCH = 405,
- OP_PUSHDEFER = 406,
- OP_IS_BOOL = 407,
- OP_IS_WEAK = 408,
- OP_WEAKEN = 409,
- OP_UNWEAKEN = 410,
- OP_BLESSED = 411,
- OP_REFADDR = 412,
- OP_REFTYPE = 413,
- OP_CEIL = 414,
- OP_FLOOR = 415,
- OP_IS_TAINTED = 416,
+ OP_EMPTYAVHV = 164,
+ OP_SPLICE = 165,
+ OP_PUSH = 166,
+ OP_POP = 167,
+ OP_SHIFT = 168,
+ OP_UNSHIFT = 169,
+ OP_SORT = 170,
+ OP_REVERSE = 171,
+ OP_GREPSTART = 172,
+ OP_GREPWHILE = 173,
+ OP_MAPSTART = 174,
+ OP_MAPWHILE = 175,
+ OP_RANGE = 176,
+ OP_FLIP = 177,
+ OP_FLOP = 178,
+ OP_AND = 179,
+ OP_OR = 180,
+ OP_XOR = 181,
+ OP_DOR = 182,
+ OP_COND_EXPR = 183,
+ OP_ANDASSIGN = 184,
+ OP_ORASSIGN = 185,
+ OP_DORASSIGN = 186,
+ OP_ENTERSUB = 187,
+ OP_LEAVESUB = 188,
+ OP_LEAVESUBLV = 189,
+ OP_ARGCHECK = 190,
+ OP_ARGELEM = 191,
+ OP_ARGDEFELEM = 192,
+ OP_CALLER = 193,
+ OP_WARN = 194,
+ OP_DIE = 195,
+ OP_RESET = 196,
+ OP_LINESEQ = 197,
+ OP_NEXTSTATE = 198,
+ OP_DBSTATE = 199,
+ OP_UNSTACK = 200,
+ OP_ENTER = 201,
+ OP_LEAVE = 202,
+ OP_SCOPE = 203,
+ OP_ENTERITER = 204,
+ OP_ITER = 205,
+ OP_ENTERLOOP = 206,
+ OP_LEAVELOOP = 207,
+ OP_RETURN = 208,
+ OP_LAST = 209,
+ OP_NEXT = 210,
+ OP_REDO = 211,
+ OP_DUMP = 212,
+ OP_GOTO = 213,
+ OP_EXIT = 214,
+ OP_METHOD = 215,
+ OP_METHOD_NAMED = 216,
+ OP_METHOD_SUPER = 217,
+ OP_METHOD_REDIR = 218,
+ OP_METHOD_REDIR_SUPER = 219,
+ OP_ENTERGIVEN = 220,
+ OP_LEAVEGIVEN = 221,
+ OP_ENTERWHEN = 222,
+ OP_LEAVEWHEN = 223,
+ OP_BREAK = 224,
+ OP_CONTINUE = 225,
+ OP_OPEN = 226,
+ OP_CLOSE = 227,
+ OP_PIPE_OP = 228,
+ OP_FILENO = 229,
+ OP_UMASK = 230,
+ OP_BINMODE = 231,
+ OP_TIE = 232,
+ OP_UNTIE = 233,
+ OP_TIED = 234,
+ OP_DBMOPEN = 235,
+ OP_DBMCLOSE = 236,
+ OP_SSELECT = 237,
+ OP_SELECT = 238,
+ OP_GETC = 239,
+ OP_READ = 240,
+ OP_ENTERWRITE = 241,
+ OP_LEAVEWRITE = 242,
+ OP_PRTF = 243,
+ OP_PRINT = 244,
+ OP_SAY = 245,
+ OP_SYSOPEN = 246,
+ OP_SYSSEEK = 247,
+ OP_SYSREAD = 248,
+ OP_SYSWRITE = 249,
+ OP_EOF = 250,
+ OP_TELL = 251,
+ OP_SEEK = 252,
+ OP_TRUNCATE = 253,
+ OP_FCNTL = 254,
+ OP_IOCTL = 255,
+ OP_FLOCK = 256,
+ OP_SEND = 257,
+ OP_RECV = 258,
+ OP_SOCKET = 259,
+ OP_SOCKPAIR = 260,
+ OP_BIND = 261,
+ OP_CONNECT = 262,
+ OP_LISTEN = 263,
+ OP_ACCEPT = 264,
+ OP_SHUTDOWN = 265,
+ OP_GSOCKOPT = 266,
+ OP_SSOCKOPT = 267,
+ OP_GETSOCKNAME = 268,
+ OP_GETPEERNAME = 269,
+ OP_LSTAT = 270,
+ OP_STAT = 271,
+ OP_FTRREAD = 272,
+ OP_FTRWRITE = 273,
+ OP_FTREXEC = 274,
+ OP_FTEREAD = 275,
+ OP_FTEWRITE = 276,
+ OP_FTEEXEC = 277,
+ OP_FTIS = 278,
+ OP_FTSIZE = 279,
+ OP_FTMTIME = 280,
+ OP_FTATIME = 281,
+ OP_FTCTIME = 282,
+ OP_FTROWNED = 283,
+ OP_FTEOWNED = 284,
+ OP_FTZERO = 285,
+ OP_FTSOCK = 286,
+ OP_FTCHR = 287,
+ OP_FTBLK = 288,
+ OP_FTFILE = 289,
+ OP_FTDIR = 290,
+ OP_FTPIPE = 291,
+ OP_FTSUID = 292,
+ OP_FTSGID = 293,
+ OP_FTSVTX = 294,
+ OP_FTLINK = 295,
+ OP_FTTTY = 296,
+ OP_FTTEXT = 297,
+ OP_FTBINARY = 298,
+ OP_CHDIR = 299,
+ OP_CHOWN = 300,
+ OP_CHROOT = 301,
+ OP_UNLINK = 302,
+ OP_CHMOD = 303,
+ OP_UTIME = 304,
+ OP_RENAME = 305,
+ OP_LINK = 306,
+ OP_SYMLINK = 307,
+ OP_READLINK = 308,
+ OP_MKDIR = 309,
+ OP_RMDIR = 310,
+ OP_OPEN_DIR = 311,
+ OP_READDIR = 312,
+ OP_TELLDIR = 313,
+ OP_SEEKDIR = 314,
+ OP_REWINDDIR = 315,
+ OP_CLOSEDIR = 316,
+ OP_FORK = 317,
+ OP_WAIT = 318,
+ OP_WAITPID = 319,
+ OP_SYSTEM = 320,
+ OP_EXEC = 321,
+ OP_KILL = 322,
+ OP_GETPPID = 323,
+ OP_GETPGRP = 324,
+ OP_SETPGRP = 325,
+ OP_GETPRIORITY = 326,
+ OP_SETPRIORITY = 327,
+ OP_TIME = 328,
+ OP_TMS = 329,
+ OP_LOCALTIME = 330,
+ OP_GMTIME = 331,
+ OP_ALARM = 332,
+ OP_SLEEP = 333,
+ OP_SHMGET = 334,
+ OP_SHMCTL = 335,
+ OP_SHMREAD = 336,
+ OP_SHMWRITE = 337,
+ OP_MSGGET = 338,
+ OP_MSGCTL = 339,
+ OP_MSGSND = 340,
+ OP_MSGRCV = 341,
+ OP_SEMOP = 342,
+ OP_SEMGET = 343,
+ OP_SEMCTL = 344,
+ OP_REQUIRE = 345,
+ OP_DOFILE = 346,
+ OP_HINTSEVAL = 347,
+ OP_ENTEREVAL = 348,
+ OP_LEAVEEVAL = 349,
+ OP_ENTERTRY = 350,
+ OP_LEAVETRY = 351,
+ OP_GHBYNAME = 352,
+ OP_GHBYADDR = 353,
+ OP_GHOSTENT = 354,
+ OP_GNBYNAME = 355,
+ OP_GNBYADDR = 356,
+ OP_GNETENT = 357,
+ OP_GPBYNAME = 358,
+ OP_GPBYNUMBER = 359,
+ OP_GPROTOENT = 360,
+ OP_GSBYNAME = 361,
+ OP_GSBYPORT = 362,
+ OP_GSERVENT = 363,
+ OP_SHOSTENT = 364,
+ OP_SNETENT = 365,
+ OP_SPROTOENT = 366,
+ OP_SSERVENT = 367,
+ OP_EHOSTENT = 368,
+ OP_ENETENT = 369,
+ OP_EPROTOENT = 370,
+ OP_ESERVENT = 371,
+ OP_GPWNAM = 372,
+ OP_GPWUID = 373,
+ OP_GPWENT = 374,
+ OP_SPWENT = 375,
+ OP_EPWENT = 376,
+ OP_GGRNAM = 377,
+ OP_GGRGID = 378,
+ OP_GGRENT = 379,
+ OP_SGRENT = 380,
+ OP_EGRENT = 381,
+ OP_GETLOGIN = 382,
+ OP_SYSCALL = 383,
+ OP_LOCK = 384,
+ OP_ONCE = 385,
+ OP_CUSTOM = 386,
+ OP_COREARGS = 387,
+ OP_AVHVSWITCH = 388,
+ OP_RUNCV = 389,
+ OP_FC = 390,
+ OP_PADCV = 391,
+ OP_INTROCV = 392,
+ OP_CLONECV = 393,
+ OP_PADRANGE = 394,
+ OP_REFASSIGN = 395,
+ OP_LVREF = 396,
+ OP_LVREFSLICE = 397,
+ OP_LVAVREF = 398,
+ OP_ANONCONST = 399,
+ OP_ISA = 400,
+ OP_CMPCHAIN_AND = 401,
+ OP_CMPCHAIN_DUP = 402,
+ OP_ENTERTRYCATCH = 403,
+ OP_LEAVETRYCATCH = 404,
+ OP_POPTRY = 405,
+ OP_CATCH = 406,
+ OP_PUSHDEFER = 407,
+ OP_IS_BOOL = 408,
+ OP_IS_WEAK = 409,
+ OP_WEAKEN = 410,
+ OP_UNWEAKEN = 411,
+ OP_BLESSED = 412,
+ OP_REFADDR = 413,
+ OP_REFTYPE = 414,
+ OP_CEIL = 415,
+ OP_FLOOR = 416,
+ OP_IS_TAINTED = 417,
OP_max
} opcode;
-#define MAXO 417
+#define MAXO 418
#define OP_FREED MAXO
/* the OP_IS_* macros are optimized to a simple range check because
diff --git a/peep.c b/peep.c
index 1319745b9a..0e3a81f019 100644
--- a/peep.c
+++ b/peep.c
@@ -3147,6 +3147,62 @@ Perl_rpeep(pTHX_ OP *o)
}
}
+ /* If the pushmark is associated with an empty anonhash
+ * or anonlist, null out the pushmark and swap in a
+ * specialised op for the parent.
+ * 4 <@> anonhash sK* ->5
+ * 3 <0> pushmark s ->4
+ * becomes:
+ * 3 <@> emptyavhv sK* ->4
+ * - <0> pushmark s ->3
+ */
+ if (!OpHAS_SIBLING(o) && (o->op_next == o->op_sibparent) && (
+ (o->op_next->op_type == OP_ANONHASH) ||
+ (o->op_next->op_type == OP_ANONLIST) ) &&
+ (o->op_next->op_flags & OPf_SPECIAL) ) {
+
+ OP* anon = o->op_next;
+ /* These next two are _potentially_ a padsv and an sassign */
+ OP* padsv = anon->op_next;
+ OP* sassign = (padsv) ? padsv->op_next: NULL;
+
+ anon->op_private = (anon->op_type == OP_ANONLIST) ?
+ 0 : OPpEMPTYAVHV_IS_HV;
+ OpTYPE_set(anon, OP_EMPTYAVHV);
+ op_null(o);
+ o = anon;
+ if (oldop) /* A previous optimization may have NULLED it */
+ oldop->op_next = anon;
+
+ /* Further optimise scalar assignment of an empty anonhash
+ * or anonlist by subsuming the padsv & sassign OPs. */
+ if ((padsv->op_type == OP_PADSV) &&
+ !(padsv->op_private & OPpDEREF) &&
+ sassign && (sassign->op_type == OP_SASSIGN) ){
+
+ /* Take some public flags from the sassign */
+ anon->op_flags = OPf_KIDS | OPf_SPECIAL |
+ (anon->op_flags & OPf_PARENS) |
+ (sassign->op_flags & (OPf_WANT|OPf_PARENS));
+
+ /* Take some private flags from the padsv */
+ anon->op_private |= OPpTARGET_MY |
+ (padsv->op_private & (OPpLVAL_INTRO|OPpPAD_STATE));
+
+ /* Take the targ slot from the padsv*/
+ anon->op_targ = padsv->op_targ;
+ padsv->op_targ = 0;
+
+ /* Clean up */
+ anon->op_next = sassign->op_next;
+ op_null(padsv);
+ op_null(sassign);
+ }
+ break;
+
+ }
+
+
/* Convert a series of PAD ops for my vars plus support into a
* single padrange op. Basically
*
diff --git a/pp.c b/pp.c
index f06f282de6..5b4c1efe64 100644
--- a/pp.c
+++ b/pp.c
@@ -5572,6 +5572,51 @@ PP(pp_anonlist)
RETURN;
}
+/* When an anonlist or anonhash will (1) be empty and (2) return an RV
+ * pointing to the new AV/HV, the peephole optimizer can swap in this
+ * simpler function and op_null the originally associated PUSHMARK. */
+PP(pp_emptyavhv)
+{
+ dSP;
+ OP * const op = PL_op;
+ SV * rv;
+ SV * const sv = MUTABLE_SV( newSV_type(
+ (op->op_private & OPpEMPTYAVHV_IS_HV) ?
+ SVt_PVHV :
+ SVt_PVAV ) );
+
+ /* Is it an assignment, just a stack push, or both?*/
+ if (op->op_private & OPpTARGET_MY) {
+ SV** const padentry = &PAD_SVl(op->op_targ);
+ rv = *padentry;
+ /* Since the op_targ is very likely to be an undef SVt_IV from
+ * a previous iteration, converting it to a live RV can
+ * typically be special-cased.*/
+ if (SvTYPE(rv) == SVt_IV && !SvOK(rv)) {
+ SvFLAGS(rv) = (SVt_IV | SVf_ROK);
+ SvRV_set(rv, sv);
+ } else {
+ sv_setrv_noinc_mg(rv, sv);
+ }
+ if ((op->op_private & (OPpLVAL_INTRO|OPpPAD_STATE)) == OPpLVAL_INTRO) {
+ save_clearsv(padentry);
+ }
+ if (GIMME_V == G_VOID) {
+ RETURN; /* skip extending and pushing */
+ }
+ } else {
+ /* Inlined newRV_noinc */
+ SV * refsv = newSV_type_mortal(SVt_IV);
+ SvRV_set(refsv, sv);
+ SvROK_on(refsv);
+
+ rv = refsv;
+ }
+
+ XPUSHs(rv);
+ RETURN;
+}
+
PP(pp_anonhash)
{
dSP; dMARK; dORIGMARK;
diff --git a/pp_proto.h b/pp_proto.h
index 759545152a..7963abb885 100644
--- a/pp_proto.h
+++ b/pp_proto.h
@@ -63,6 +63,7 @@ PERL_CALLCONV OP *Perl_pp_die(pTHX) __attribute__visibility__("hidden");
PERL_CALLCONV OP *Perl_pp_divide(pTHX) __attribute__visibility__("hidden");
PERL_CALLCONV OP *Perl_pp_each(pTHX) __attribute__visibility__("hidden");
PERL_CALLCONV OP *Perl_pp_ehostent(pTHX) __attribute__visibility__("hidden");
+PERL_CALLCONV OP *Perl_pp_emptyavhv(pTHX) __attribute__visibility__("hidden");
PERL_CALLCONV OP *Perl_pp_enter(pTHX) __attribute__visibility__("hidden");
PERL_CALLCONV OP *Perl_pp_entereval(pTHX) __attribute__visibility__("hidden");
PERL_CALLCONV OP *Perl_pp_entergiven(pTHX) __attribute__visibility__("hidden");
diff --git a/regen/op_private b/regen/op_private
index 4f2afe2174..7150f20cc8 100644
--- a/regen/op_private
+++ b/regen/op_private
@@ -318,7 +318,7 @@ addbits($_, 7 => qw(OPpLVAL_INTRO LVINTRO))
for qw(gvsv rv2sv rv2hv rv2gv rv2av aelem helem aslice split
hslice delete padsv padav padhv enteriter entersub padrange
pushmark cond_expr refassign lvref lvrefslice lvavref multideref
- multiconcat padsv_store undef),
+ multiconcat padsv_store undef emptyavhv),
'list', # this gets set in my_attrs() for some reason
;
@@ -500,7 +500,7 @@ addbits($_, 7 => qw(OPpPV_IS_UTF8 UTF)) for qw(last redo next goto dump);
addbits($_, 6 => qw(OPpPAD_STATE STATE)) for qw(padav padhv padsv lvavref
lvref refassign pushmark
- padsv_store undef);
+ padsv_store undef emptyavhv);
# NB: both sassign and aassign use the 'OPpASSIGN' naming convention
# for their private flags
@@ -860,6 +860,13 @@ addbits('undef',
5 => qw(OPpUNDEF_KEEP_PV KEEP_PV),
);
+addbits('emptyavhv',
+ # 7 OPpLVAL_INTRO
+ # 6 OPpPAD_STATE
+ 5 => qw(OPpEMPTYAVHV_IS_HV ANONHASH),
+ # 4 OPpTARGET_MY
+);
+
1;
# ex: set ts=8 sts=4 sw=4 et:
diff --git a/regen/opcodes b/regen/opcodes
index f6b68ec61b..c48c337076 100644
--- a/regen/opcodes
+++ b/regen/opcodes
@@ -261,6 +261,7 @@ list list ck_null m@ L
lslice list slice ck_null 2 H L L
anonlist anonymous array ([]) ck_fun ms@ L
anonhash anonymous hash ({}) ck_fun ms@ L
+emptyavhv empty anon hash/array ck_fun sT@ L
splice splice ck_fun m@ A S? S? L
push push ck_fun imsT@ A L
diff --git a/t/perf/benchmarks b/t/perf/benchmarks
index 7b457abff3..92f946bbce 100644
--- a/t/perf/benchmarks
+++ b/t/perf/benchmarks
@@ -1367,6 +1367,31 @@
code => 'undef my $x',
},
+ 'expr::sassign::anonlist' => {
+ setup => '',
+ code => '$x = []'
+ },
+ 'expr::sassign::anonlist_lex' => {
+ setup => 'my $x',
+ code => '$x = []'
+ },
+ 'expr::sassign::my_anonlist_lex' => {
+ setup => '',
+ code => 'my $x = []'
+ },
+ 'expr::sassign::anonhash' => {
+ setup => '',
+ code => '$x = {}'
+ },
+ 'expr::sassign::anonhash_lex' => {
+ setup => 'my $x',
+ code => '$x = {}'
+ },
+ 'expr::sassign::my_anonhash_lex' => {
+ setup => '',
+ code => 'my $x = {}'
+ },
+
'expr::sassign::my_conststr' => {
setup => '',
code => 'my $x = "abc"',
@@ -1418,6 +1443,10 @@
code => '$x[0][1] = 1',
},
+ 'expr::sassign::bless_lex' => {
+ setup => 'my $x',
+ code => '$x = bless {}, "X"'
+ },
'func::grep::bool0' => {
desc => 'grep returning 0 items in boolean context',
diff --git a/t/perf/opcount.t b/t/perf/opcount.t
index cca8dec397..4651f2442e 100644
--- a/t/perf/opcount.t
+++ b/t/perf/opcount.t
@@ -868,9 +868,10 @@ test_opcount(0, 'my $h= {}; my @k= keys %{($h=undef)||{}};',
{
undef => 1,
aassign => 1,
+ emptyavhv => 2,
padav => 1,
padsv => 0,
- padsv_store => 1,
+ padsv_store => 0,
sassign => 0,
});
@@ -918,4 +919,97 @@ test_opcount(0, "no aelemfast_lex + sassign replacement with multideref",
sassign => 1,
});
+# emptyavhv optimizations
+
+test_opcount(0, "Empty anonlist",
+ sub { [] },
+ {
+ anonlist => 0,
+ emptyavhv => 1,
+ sassign => 0,
+ });
+test_opcount(0, "Empty anonlist with global assignment",
+ sub { our $x; $x = [] },
+ {
+ anonlist => 0,
+ emptyavhv => 1,
+ gvsv => 1,
+ pushmark => 0,
+ sassign => 1,
+ });
+test_opcount(0, "Empty anonlist and lexical assignment",
+ sub { my $x; $x = [] },
+ {
+ anonlist => 0,
+ emptyavhv => 1,
+ padsv => 1,
+ pushmark => 0,
+ sassign => 0,
+ });
+test_opcount(0, "Empty anonlist and direct lexical assignment",
+ sub { my $x = [] },
+ {
+ anonlist => 0,
+ emptyavhv => 1,
+ padsv => 0,
+ pushmark => 0,
+ sassign => 0,
+ });
+test_opcount(0, "Empty anonlist ref and direct lexical assignment",
+ sub { my $x = \[] },
+ {
+ anonlist => 0,
+ emptyavhv => 1,
+ padsv => 0,
+ padsv_store => 1,
+ pushmark => 0,
+ sassign => 0,
+ srefgen => 1,
+ });
+test_opcount(0, "Empty anonhash",
+ sub { {} },
+ {
+ anonhash => 0,
+ emptyavhv => 1,
+ sassign => 0,
+ });
+test_opcount(0, "Empty anonhash with global assignment",
+ sub { our $x; $x = {} },
+ {
+ anonhash => 0,
+ emptyavhv => 1,
+ gvsv => 1,
+ pushmark => 0,
+ sassign => 1,
+ });
+test_opcount(0, "Empty anonhash and lexical assignment",
+ sub { my $x; $x = {} },
+ {
+ anonhash => 0,
+ emptyavhv => 1,
+ padsv => 1,
+ pushmark => 0,
+ sassign => 0,
+ });
+test_opcount(0, "Empty anonhash and direct lexical assignment",
+ sub { my $x = {} },
+ {
+ anonhash => 0,
+ emptyavhv => 1,
+ padsv => 0,
+ pushmark => 0,
+ sassign => 0,
+ });
+test_opcount(0, "Empty anonhash ref and direct lexical assignment",
+ sub { my $x = \{} },
+ {
+ anonhash => 0,
+ emptyavhv => 1,
+ padsv => 0,
+ padsv_store => 1,
+ pushmark => 0,
+ sassign => 0,
+ srefgen => 1,
+ });
+
done_testing();