Skip to content

Commit cd80cda

Browse files
tonycozap
authored andcommitted
Revert "switch removal: remove given/when/break/continue"
This reverts commit dff5181.
1 parent a215a77 commit cd80cda

40 files changed

+5354
-2373
lines changed

MANIFEST

+2
Original file line numberDiff line numberDiff line change
@@ -6131,6 +6131,7 @@ t/lib/feature/multidimensional Tests for enabling/disabling $foo{$x, $y} => $fo
61316131
t/lib/feature/nonesuch Tests for enabling/disabling nonexistent feature
61326132
t/lib/feature/removed Tests for enabling/disabling removed feature
61336133
t/lib/feature/say Tests for enabling/disabling say feature
6134+
t/lib/feature/switch Tests for enabling/disabling switch feature
61346135
t/lib/h2ph.h Test header file for h2ph
61356136
t/lib/h2ph.pht Generated output from h2ph.h by h2ph, for comparison
61366137
t/lib/locale/latin1 Part of locale.t in Latin 1
@@ -6456,6 +6457,7 @@ t/op/substr_thr.t See if substr works in another thread
64566457
t/op/svflags.t See if POK is set as expected.
64576458
t/op/svleak.pl Test file for svleak.t
64586459
t/op/svleak.t See if stuff leaks SVs
6460+
t/op/switch.t See if switches (given/when) work
64596461
t/op/symbolcache.t See if undef/delete works on stashes with functions
64606462
t/op/sysio.t See if sysread and syswrite work
64616463
t/op/taint.t See if tainting works

cop.h

+17-11
Original file line numberDiff line numberDiff line change
@@ -1127,21 +1127,27 @@ struct context {
11271127
and a static array of context names in pp_ctl.c */
11281128
#define CXTYPEMASK 0xf
11291129
#define CXt_NULL 0 /* currently only used for sort BLOCK */
1130-
#define CXt_BLOCK 1
1130+
#define CXt_WHEN 1
1131+
#define CXt_BLOCK 2
1132+
/* When micro-optimising :-) keep GIVEN next to the LOOPs, as these 5 share a
1133+
jump table in pp_ctl.c
1134+
The first 4 don't have a 'case' in at least one switch statement in pp_ctl.c
1135+
*/
1136+
#define CXt_GIVEN 3
11311137

11321138
/* be careful of the ordering of these five. Macros like CxTYPE_is_LOOP,
11331139
* CxFOREACH compare ranges */
1134-
#define CXt_LOOP_ARY 2 /* for (@ary) { ...; } */
1135-
#define CXt_LOOP_LAZYSV 3 /* for ('a'..'z') { ...; } */
1136-
#define CXt_LOOP_LAZYIV 4 /* for (1..9) { ...; } */
1137-
#define CXt_LOOP_LIST 5 /* for (1,2,3) { ...; } */
1138-
#define CXt_LOOP_PLAIN 6 /* while (...) { ...; }
1140+
#define CXt_LOOP_ARY 4 /* for (@ary) { ...; } */
1141+
#define CXt_LOOP_LAZYSV 5 /* for ('a'..'z') { ...; } */
1142+
#define CXt_LOOP_LAZYIV 6 /* for (1..9) { ...; } */
1143+
#define CXt_LOOP_LIST 7 /* for (1,2,3) { ...; } */
1144+
#define CXt_LOOP_PLAIN 8 /* while (...) { ...; }
11391145
or plain block { ...; } */
1140-
#define CXt_SUB 7
1141-
#define CXt_FORMAT 8
1142-
#define CXt_EVAL 9 /* eval'', eval{}, try{} */
1143-
#define CXt_SUBST 10
1144-
#define CXt_DEFER 11
1146+
#define CXt_SUB 9
1147+
#define CXt_FORMAT 10
1148+
#define CXt_EVAL 11 /* eval'', eval{}, try{} */
1149+
#define CXt_SUBST 12
1150+
#define CXt_DEFER 13
11451151
/* SUBST doesn't feature in all switch statements. */
11461152

11471153
/* private flags for CXt_SUB and CXt_FORMAT */

dump.c

+2
Original file line numberDiff line numberDiff line change
@@ -1448,6 +1448,8 @@ S_do_op_dump_bar(pTHX_ I32 level, UV bar, PerlIO *file, const OP *o)
14481448
case OP_DORASSIGN:
14491449
case OP_ANDASSIGN:
14501450
case OP_ARGDEFELEM:
1451+
case OP_ENTERGIVEN:
1452+
case OP_ENTERWHEN:
14511453
case OP_ENTERTRY:
14521454
case OP_ONCE:
14531455
S_opdump_indent(aTHX_ o, level, bar, file, "OTHER");

embed.fnc

+18
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,9 @@ ARdp |OP * |newFOROP |I32 flags \
22132213
|NN OP *expr \
22142214
|NULLOK OP *block \
22152215
|NULLOK OP *cont
2216+
ARdp |OP * |newGIVENOP |NN OP *cond \
2217+
|NN OP *block \
2218+
|PADOFFSET defsv_off
22162219
: Used in scope.c
22172220
eopx |GP * |newGP |NN GV * const gv
22182221
Adm |GV * |newGVgen |NN const char *pack
@@ -2357,6 +2360,8 @@ ERXopx |char * |new_warnings_bitfield \
23572360
|NULLOK char *buffer \
23582361
|NN const char * const bits \
23592362
|STRLEN size
2363+
ARdp |OP * |newWHENOP |NULLOK OP *cond \
2364+
|NN OP *block
23602365
ARdp |OP * |newWHILEOP |I32 flags \
23612366
|I32 debuggable \
23622367
|NULLOK LOOP *loop \
@@ -4861,6 +4866,7 @@ RST |bool |is_handle_constructor \
48614866
Ti |bool |is_standard_filehandle_name \
48624867
|NN const char *fhname
48634868
S |OP * |listkids |NULLOK OP *o
4869+
S |bool |looks_like_bool|NN const OP *o
48644870
S |OP * |modkids |NULLOK OP *o \
48654871
|I32 type
48664872
S |void |move_proto_attr|NN OP **proto \
@@ -4870,6 +4876,11 @@ S |void |move_proto_attr|NN OP **proto \
48704876
S |OP * |my_kid |NULLOK OP *o \
48714877
|NULLOK OP *attrs \
48724878
|NN OP **imopsp
4879+
S |OP * |newGIVWHENOP |NULLOK OP *cond \
4880+
|NN OP *block \
4881+
|I32 enter_opcode \
4882+
|I32 leave_opcode \
4883+
|PADOFFSET entertarg
48734884
RS |OP * |new_logop |I32 type \
48744885
|I32 flags \
48754886
|NN OP **firstp \
@@ -5087,12 +5098,14 @@ RS |OP * |dofindlabel |NN OP *o \
50875098
|NN OP **oplimit
50885099
S |MAGIC *|doparseform |NN SV *sv
50895100
RS |I32 |dopoptoeval |I32 startingblock
5101+
RS |I32 |dopoptogivenfor|I32 startingblock
50905102
RS |I32 |dopoptolabel |NN const char *label \
50915103
|STRLEN len \
50925104
|U32 flags
50935105
RS |I32 |dopoptoloop |I32 startingblock
50945106
RS |I32 |dopoptosub_at |NN const PERL_CONTEXT *cxstk \
50955107
|I32 startingblock
5108+
RS |I32 |dopoptowhen |I32 startingblock
50965109
S |OP * |do_smartmatch |NULLOK HV *seen_this \
50975110
|NULLOK HV *seen_other \
50985111
|const bool copied
@@ -6204,11 +6217,13 @@ CTp |Malloc_t|mem_log_realloc \
62046217
Cipx |void |cx_popblock |NN PERL_CONTEXT *cx
62056218
Cipx |void |cx_popeval |NN PERL_CONTEXT *cx
62066219
Cipx |void |cx_popformat |NN PERL_CONTEXT *cx
6220+
Cipx |void |cx_popgiven |NN PERL_CONTEXT *cx
62076221
Cipx |void |cx_poploop |NN PERL_CONTEXT *cx
62086222
Cipx |void |cx_popsub |NN PERL_CONTEXT *cx
62096223
Cipx |void |cx_popsub_args |NN PERL_CONTEXT *cx
62106224
Cipx |void |cx_popsub_common \
62116225
|NN PERL_CONTEXT *cx
6226+
Cipx |void |cx_popwhen |NN PERL_CONTEXT *cx
62126227
Cipx |PERL_CONTEXT *|cx_pushblock \
62136228
|U8 type \
62146229
|U8 gimme \
@@ -6221,6 +6236,8 @@ Cipx |void |cx_pushformat |NN PERL_CONTEXT *cx \
62216236
|NN CV *cv \
62226237
|NULLOK OP *retop \
62236238
|NULLOK GV *gv
6239+
Cipx |void |cx_pushgiven |NN PERL_CONTEXT *cx \
6240+
|NULLOK SV *orig_defsv
62246241
Cipx |void |cx_pushloop_for|NN PERL_CONTEXT *cx \
62256242
|NN void *itervarp \
62266243
|NULLOK SV *itersave
@@ -6232,6 +6249,7 @@ Cipx |void |cx_pushsub |NN PERL_CONTEXT *cx \
62326249
|bool hasargs
62336250
Cipx |void |cx_pushtry |NN PERL_CONTEXT *cx \
62346251
|NULLOK OP *retop
6252+
Cipx |void |cx_pushwhen |NN PERL_CONTEXT *cx
62356253
Cipx |void |cx_topblock |NN PERL_CONTEXT *cx
62366254
Cipx |U8 |gimme_V
62376255
#endif /* !defined(PERL_NO_INLINE_FUNCTIONS) */

embed.h

+10
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,7 @@
425425
# define newDEFSVOP() Perl_newDEFSVOP(aTHX)
426426
# define newFORM(a,b,c) Perl_newFORM(aTHX_ a,b,c)
427427
# define newFOROP(a,b,c,d,e) Perl_newFOROP(aTHX_ a,b,c,d,e)
428+
# define newGIVENOP(a,b,c) Perl_newGIVENOP(aTHX_ a,b,c)
428429
# define newGVOP(a,b,c) Perl_newGVOP(aTHX_ a,b,c)
429430
# define newGVREF(a,b) Perl_newGVREF(aTHX_ a,b)
430431
# define newGVgen_flags(a,b) Perl_newGVgen_flags(aTHX_ a,b)
@@ -480,6 +481,7 @@
480481
# define newTRYCATCHOP(a,b,c,d) Perl_newTRYCATCHOP(aTHX_ a,b,c,d)
481482
# define newUNOP(a,b,c) Perl_newUNOP(aTHX_ a,b,c)
482483
# define newUNOP_AUX(a,b,c,d) Perl_newUNOP_AUX(aTHX_ a,b,c,d)
484+
# define newWHENOP(a,b) Perl_newWHENOP(aTHX_ a,b)
483485
# define newWHILEOP(a,b,c,d,e,f,g) Perl_newWHILEOP(aTHX_ a,b,c,d,e,f,g)
484486
# define newXS(a,b,c) Perl_newXS(aTHX_ a,b,c)
485487
# define newXS_flags(a,b,c,d,e) Perl_newXS_flags(aTHX_ a,b,c,d,e)
@@ -1546,9 +1548,11 @@
15461548
# define is_handle_constructor S_is_handle_constructor
15471549
# define is_standard_filehandle_name S_is_standard_filehandle_name
15481550
# define listkids(a) S_listkids(aTHX_ a)
1551+
# define looks_like_bool(a) S_looks_like_bool(aTHX_ a)
15491552
# define modkids(a,b) S_modkids(aTHX_ a,b)
15501553
# define move_proto_attr(a,b,c,d) S_move_proto_attr(aTHX_ a,b,c,d)
15511554
# define my_kid(a,b,c) S_my_kid(aTHX_ a,b,c)
1555+
# define newGIVWHENOP(a,b,c,d,e) S_newGIVWHENOP(aTHX_ a,b,c,d,e)
15521556
# define newMETHOP_internal(a,b,c,d) S_newMETHOP_internal(aTHX_ a,b,c,d)
15531557
# define new_logop(a,b,c,d) S_new_logop(aTHX_ a,b,c,d)
15541558
# define no_fh_allowed(a) S_no_fh_allowed(aTHX_ a)
@@ -1640,9 +1644,11 @@
16401644
# define dofindlabel(a,b,c,d,e,f) S_dofindlabel(aTHX_ a,b,c,d,e,f)
16411645
# define doparseform(a) S_doparseform(aTHX_ a)
16421646
# define dopoptoeval(a) S_dopoptoeval(aTHX_ a)
1647+
# define dopoptogivenfor(a) S_dopoptogivenfor(aTHX_ a)
16431648
# define dopoptolabel(a,b,c) S_dopoptolabel(aTHX_ a,b,c)
16441649
# define dopoptoloop(a) S_dopoptoloop(aTHX_ a)
16451650
# define dopoptosub_at(a,b) S_dopoptosub_at(aTHX_ a,b)
1651+
# define dopoptowhen(a) S_dopoptowhen(aTHX_ a)
16461652
# define make_matcher(a) S_make_matcher(aTHX_ a)
16471653
# define matcher_matches_sv(a,b) S_matcher_matches_sv(aTHX_ a,b)
16481654
# define num_overflow S_num_overflow
@@ -2229,17 +2235,21 @@
22292235
# define cx_popblock(a) Perl_cx_popblock(aTHX_ a)
22302236
# define cx_popeval(a) Perl_cx_popeval(aTHX_ a)
22312237
# define cx_popformat(a) Perl_cx_popformat(aTHX_ a)
2238+
# define cx_popgiven(a) Perl_cx_popgiven(aTHX_ a)
22322239
# define cx_poploop(a) Perl_cx_poploop(aTHX_ a)
22332240
# define cx_popsub(a) Perl_cx_popsub(aTHX_ a)
22342241
# define cx_popsub_args(a) Perl_cx_popsub_args(aTHX_ a)
22352242
# define cx_popsub_common(a) Perl_cx_popsub_common(aTHX_ a)
2243+
# define cx_popwhen(a) Perl_cx_popwhen(aTHX_ a)
22362244
# define cx_pushblock(a,b,c,d) Perl_cx_pushblock(aTHX_ a,b,c,d)
22372245
# define cx_pusheval(a,b,c) Perl_cx_pusheval(aTHX_ a,b,c)
22382246
# define cx_pushformat(a,b,c,d) Perl_cx_pushformat(aTHX_ a,b,c,d)
2247+
# define cx_pushgiven(a,b) Perl_cx_pushgiven(aTHX_ a,b)
22392248
# define cx_pushloop_for(a,b,c) Perl_cx_pushloop_for(aTHX_ a,b,c)
22402249
# define cx_pushloop_plain(a) Perl_cx_pushloop_plain(aTHX_ a)
22412250
# define cx_pushsub(a,b,c,d) Perl_cx_pushsub(aTHX_ a,b,c,d)
22422251
# define cx_pushtry(a,b) Perl_cx_pushtry(aTHX_ a,b)
2252+
# define cx_pushwhen(a) Perl_cx_pushwhen(aTHX_ a)
22432253
# define cx_topblock(a) Perl_cx_topblock(aTHX_ a)
22442254
# define gimme_V() Perl_gimme_V(aTHX)
22452255
# endif /* !defined(PERL_NO_INLINE_FUNCTIONS) */

ext/Opcode/Opcode.pm

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package Opcode 1.68;
1+
package Opcode 1.69;
22

33
use strict;
44

@@ -436,6 +436,9 @@ These are a hotchpotch of opcodes still waiting to be considered
436436
entertry leavetry -- can be used to 'hide' fatal errors
437437
entertrycatch poptry catch leavetrycatch -- similar
438438
439+
entergiven leavegiven
440+
enterwhen leavewhen
441+
break continue
439442
smartmatch
440443
441444
pushdefer

gv.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -612,12 +612,12 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
612612
case KEY_DESTROY : case KEY_END : case KEY_INIT : case KEY_UNITCHECK:
613613
case KEY_all : case KEY_and : case KEY_any :
614614
case KEY_catch : case KEY_class :
615-
case KEY_continue: case KEY_cmp : case KEY_defer :
615+
case KEY_cmp : case KEY_default : case KEY_defer :
616616
case KEY_do : case KEY_dump : case KEY_else : case KEY_elsif :
617617
case KEY_eq : case KEY_eval : case KEY_field :
618618
case KEY_finally:
619619
case KEY_for : case KEY_foreach: case KEY_format: case KEY_ge :
620-
case KEY_goto : case KEY_grep : case KEY_gt :
620+
case KEY_given : case KEY_goto : case KEY_grep : case KEY_gt :
621621
case KEY_if : case KEY_isa :
622622
case KEY_last :
623623
case KEY_le : case KEY_local : case KEY_lt : case KEY_m :
@@ -630,7 +630,7 @@ S_maybe_add_coresub(pTHX_ HV * const stash, GV *gv,
630630
case KEY_state: case KEY_sub :
631631
case KEY_tr : case KEY_try :
632632
case KEY_unless:
633-
case KEY_until: case KEY_use : case KEY_while :
633+
case KEY_until: case KEY_use : case KEY_when : case KEY_while :
634634
case KEY_x : case KEY_xor : case KEY_y :
635635
return NULL;
636636
case KEY_chomp: case KEY_chop: case KEY_defined: case KEY_delete:

inline.h

+46
Original file line numberDiff line numberDiff line change
@@ -3791,6 +3791,52 @@ Perl_cx_poploop(pTHX_ PERL_CONTEXT *cx)
37913791
}
37923792

37933793

3794+
PERL_STATIC_INLINE void
3795+
Perl_cx_pushwhen(pTHX_ PERL_CONTEXT *cx)
3796+
{
3797+
PERL_ARGS_ASSERT_CX_PUSHWHEN;
3798+
3799+
cx->blk_givwhen.leave_op = cLOGOP->op_other;
3800+
}
3801+
3802+
3803+
PERL_STATIC_INLINE void
3804+
Perl_cx_popwhen(pTHX_ PERL_CONTEXT *cx)
3805+
{
3806+
PERL_ARGS_ASSERT_CX_POPWHEN;
3807+
assert(CxTYPE(cx) == CXt_WHEN);
3808+
3809+
PERL_UNUSED_ARG(cx);
3810+
PERL_UNUSED_CONTEXT;
3811+
/* currently NOOP */
3812+
}
3813+
3814+
3815+
PERL_STATIC_INLINE void
3816+
Perl_cx_pushgiven(pTHX_ PERL_CONTEXT *cx, SV *orig_defsv)
3817+
{
3818+
PERL_ARGS_ASSERT_CX_PUSHGIVEN;
3819+
3820+
cx->blk_givwhen.leave_op = cLOGOP->op_other;
3821+
cx->blk_givwhen.defsv_save = orig_defsv;
3822+
}
3823+
3824+
3825+
PERL_STATIC_INLINE void
3826+
Perl_cx_popgiven(pTHX_ PERL_CONTEXT *cx)
3827+
{
3828+
SV *sv;
3829+
3830+
PERL_ARGS_ASSERT_CX_POPGIVEN;
3831+
assert(CxTYPE(cx) == CXt_GIVEN);
3832+
3833+
sv = GvSV(PL_defgv);
3834+
GvSV(PL_defgv) = cx->blk_givwhen.defsv_save;
3835+
cx->blk_givwhen.defsv_save = NULL;
3836+
SvREFCNT_dec(sv);
3837+
}
3838+
3839+
37943840
/* Make @_ empty in-place in simple cases: a cheap av_clear().
37953841
* See Perl_clear_defarray() for non-simple cases */
37963842

0 commit comments

Comments
 (0)