@@ -3238,20 +3238,25 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
32383238 int text_length = FixedLengthLoopLengthForAlternative (&alternatives_->at (0 ));
32393239 AlternativeGenerationList alt_gens (choice_count, zone ());
32403240
3241+ // Flags need to be reset to the state of the ChoiceNode at the beginning
3242+ // of each alternative (in-line and out-of-line), as flags might be modified
3243+ // when emitting an alternative.
3244+ RegExpFlags flags = compiler->flags ();
32413245 if (choice_count > 1 && text_length != kNodeIsTooComplexForFixedLengthLoops ) {
32423246 trace = EmitFixedLengthLoop (compiler, trace, &alt_gens, &preload,
3243- &fixed_length_loop_state, text_length);
3247+ &fixed_length_loop_state, text_length, flags );
32443248 } else {
32453249 preload.eats_at_least_ = EmitOptimizedUnanchoredSearch (compiler, trace);
32463250
3247- EmitChoices (compiler, &alt_gens, 0 , trace, &preload);
3251+ EmitChoices (compiler, &alt_gens, 0 , trace, &preload, flags );
32483252 }
32493253
32503254 // At this point we need to generate slow checks for the alternatives where
32513255 // the quick check was inlined. We can recognize these because the associated
32523256 // label was bound.
32533257 int new_flush_budget = trace->flush_budget () / choice_count;
32543258 for (int i = 0 ; i < choice_count; i++) {
3259+ compiler->set_flags (flags);
32553260 AlternativeGeneration* alt_gen = alt_gens.at (i);
32563261 Trace new_trace (*trace);
32573262 // If there are actions to be flushed we have to limit how many times
@@ -3271,7 +3276,7 @@ void ChoiceNode::Emit(RegExpCompiler* compiler, Trace* trace) {
32713276Trace* ChoiceNode::EmitFixedLengthLoop (
32723277 RegExpCompiler* compiler, Trace* trace, AlternativeGenerationList* alt_gens,
32733278 PreloadState* preload, FixedLengthLoopState* fixed_length_loop_state,
3274- int text_length) {
3279+ int text_length, RegExpFlags flags ) {
32753280 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler ();
32763281 // Here we have special handling for greedy loops containing only text nodes
32773282 // and other simple nodes. We call these fixed length loops. These are
@@ -3298,7 +3303,7 @@ Trace* ChoiceNode::EmitFixedLengthLoop(
32983303
32993304 // In a fixed length loop there is only one other choice, which is what
33003305 // comes after the greedy quantifer. Try to match that now.
3301- EmitChoices (compiler, alt_gens, 1 , new_trace, preload);
3306+ EmitChoices (compiler, alt_gens, 1 , new_trace, preload, flags );
33023307
33033308 fixed_length_loop_state->BindStepBackwardsLabel (macro_assembler);
33043309 // If we have unwound to the bottom then backtrack.
@@ -3358,7 +3363,7 @@ int ChoiceNode::EmitOptimizedUnanchoredSearch(RegExpCompiler* compiler,
33583363void ChoiceNode::EmitChoices (RegExpCompiler* compiler,
33593364 AlternativeGenerationList* alt_gens,
33603365 int first_choice, Trace* trace,
3361- PreloadState* preload) {
3366+ PreloadState* preload, RegExpFlags flags ) {
33623367 RegExpMacroAssembler* macro_assembler = compiler->macro_assembler ();
33633368 SetUpPreLoad (compiler, trace, preload);
33643369
@@ -3369,6 +3374,7 @@ void ChoiceNode::EmitChoices(RegExpCompiler* compiler,
33693374 int new_flush_budget = trace->flush_budget () / choice_count;
33703375
33713376 for (int i = first_choice; i < choice_count; i++) {
3377+ compiler->set_flags (flags);
33723378 bool is_last = i == choice_count - 1 ;
33733379 bool fall_through_on_failure = !is_last;
33743380 GuardedAlternative alternative = alternatives_->at (i);
0 commit comments