@@ -163,6 +163,7 @@ typedef struct scan_frame {
163
163
regnode *next_regnode; /* next node to process when last is reached */
164
164
U32 prev_recursed_depth;
165
165
I32 stopparen; /* what stopparen do we use */
166
+ bool in_gosub; /* this or an outer frame is for GOSUB */
166
167
167
168
struct scan_frame *this_prev_frame; /* this previous frame */
168
169
struct scan_frame *prev_frame; /* previous frame */
@@ -4606,6 +4607,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
4606
4607
node length to get a real minimum (because
4607
4608
the folded version may be shorter) */
4608
4609
bool unfolded_multi_char = FALSE;
4610
+ bool mutate_ok = (frame && frame->in_gosub) ? 0 : 1;
4609
4611
/* Peephole optimizer: */
4610
4612
DEBUG_STUDYDATA("Peep", data, depth, is_inf);
4611
4613
DEBUG_PEEP("Peep", scan, depth, flags);
@@ -4619,7 +4621,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
4619
4621
if (PL_regkind[OP(scan)] == EXACT
4620
4622
&& OP(scan) != LEXACT
4621
4623
&& OP(scan) != LEXACT_REQ8
4622
- && !frame
4624
+ && mutate_ok
4623
4625
) {
4624
4626
join_exact(pRExC_state, scan, &min_subtract, &unfolded_multi_char,
4625
4627
0, NULL, depth + 1);
@@ -4810,7 +4812,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
4810
4812
4811
4813
if (PERL_ENABLE_TRIE_OPTIMISATION
4812
4814
&& OP(startbranch) == BRANCH
4813
- && !frame
4815
+ && mutate_ok
4814
4816
) {
4815
4817
/* demq.
4816
4818
@@ -5264,6 +5266,9 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
5264
5266
newframe->stopparen = stopparen;
5265
5267
newframe->prev_recursed_depth = recursed_depth;
5266
5268
newframe->this_prev_frame= frame;
5269
+ newframe->in_gosub = (
5270
+ (frame && frame->in_gosub) || OP(scan) == GOSUB
5271
+ );
5267
5272
5268
5273
DEBUG_STUDYDATA("frame-new", data, depth, is_inf);
5269
5274
DEBUG_PEEP("fnew", scan, depth, flags);
@@ -5349,7 +5354,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
5349
5354
&& ( OP(scan) == EXACTFAA
5350
5355
|| ( OP(scan) == EXACTFU
5351
5356
&& ! HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE(*s)))
5352
- && !frame
5357
+ && mutate_ok
5353
5358
) {
5354
5359
U8 mask = ~ ('A' ^ 'a'); /* These differ in just one bit */
5355
5360
@@ -5443,7 +5448,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
5443
5448
5444
5449
/* This temporary node can now be turned into EXACTFU, and
5445
5450
* must, as regexec.c doesn't handle it */
5446
- if (OP(next) == EXACTFU_S_EDGE && !frame ) {
5451
+ if (OP(next) == EXACTFU_S_EDGE && mutate_ok ) {
5447
5452
OP(next) = EXACTFU;
5448
5453
}
5449
5454
@@ -5452,7 +5457,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
5452
5457
&& ( OP(next) == EXACTFAA
5453
5458
|| ( OP(next) == EXACTFU
5454
5459
&& ! HAS_NONLATIN1_SIMPLE_FOLD_CLOSURE(* STRING(next))))
5455
- && !frame
5460
+ && mutate_ok
5456
5461
) {
5457
5462
/* These differ in just one bit */
5458
5463
U8 mask = ~ ('A' ^ 'a');
@@ -5601,7 +5606,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
5601
5606
&& data->flags & SF_IN_PAR
5602
5607
&& !(data->flags & SF_HAS_EVAL)
5603
5608
&& !deltanext && minnext == 1
5604
- && !frame
5609
+ && mutate_ok
5605
5610
) {
5606
5611
/* Try to optimize to CURLYN. */
5607
5612
regnode *nxt = NEXTOPER(oscan) + EXTRA_STEP_2ARGS;
@@ -5655,7 +5660,7 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp,
5655
5660
/* Nor characters whose fold at run-time may be
5656
5661
* multi-character */
5657
5662
&& ! (RExC_seen & REG_UNFOLDED_MULTI_SEEN)
5658
- && !frame
5663
+ && mutate_ok
5659
5664
) {
5660
5665
/* XXXX How to optimize if data == 0? */
5661
5666
/* Optimize to a simpler form. */
0 commit comments