diff options
-rw-r--r-- | ext/Opcode/Opcode.pm | 1 | ||||
-rw-r--r-- | lib/B/Deparse.pm | 19 | ||||
-rw-r--r-- | lib/B/Op_private.pm | 16 | ||||
-rw-r--r-- | opcode.h | 282 | ||||
-rw-r--r-- | opnames.h | 509 | ||||
-rw-r--r-- | peep.c | 56 | ||||
-rw-r--r-- | pp.c | 45 | ||||
-rw-r--r-- | pp_proto.h | 1 | ||||
-rw-r--r-- | regen/op_private | 11 | ||||
-rw-r--r-- | regen/opcodes | 1 | ||||
-rw-r--r-- | t/perf/benchmarks | 29 | ||||
-rw-r--r-- | t/perf/opcount.t | 96 |
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)], @@ -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), @@ -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 @@ -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 * @@ -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(); |