@@ -10547,7 +10547,7 @@ PCRE2_UCHAR type;
1054710547sljit_u32 max = 0 ,exact ;
1054810548sljit_s32 early_fail_ptr = PRIVATE_DATA (cc + 1 );
1054910549sljit_s32 early_fail_type ;
10550- BOOL charpos_enabled ;
10550+ BOOL charpos_enabled , use_tmp ;
1055110551PCRE2_UCHAR charpos_char ;
1055210552unsignedint charpos_othercasebit ;
1055310553PCRE2_SPTR end ;
@@ -10560,9 +10560,6 @@ int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_SP
1056010560int offset0 = (private_data_ptr == 0 ) ?STACK (0 ) :private_data_ptr ;
1056110561int offset1 = (private_data_ptr == 0 ) ?STACK (1 ) :private_data_ptr + SSIZE_OF (sw );
1056210562int tmp_base ,tmp_offset ;
10563- #if definedSUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10564- BOOL use_tmp ;
10565- #endif
1056610563
1056710564PUSH_BACKTRACK (sizeof (char_iterator_backtrack ),cc ,NULL );
1056810565
@@ -10754,6 +10751,7 @@ switch(opcode)
1075410751charpos_char = 0 ;
1075510752charpos_othercasebit = 0 ;
1075610753
10754+ SLJIT_ASSERT (tmp_base == TMP3 );
1075710755if ((type != OP_CHAR && type != OP_CHARI )&& (* end == OP_CHAR || * end == OP_CHARI ))
1075810756 {
1075910757#ifdef SUPPORT_UNICODE
@@ -10786,153 +10784,146 @@ switch(opcode)
1078610784BACKTRACK_AS (char_iterator_backtrack )-> charpos_enabled = TRUE;
1078710785BACKTRACK_AS (char_iterator_backtrack )-> u .charpos .chr = charpos_char ;
1078810786BACKTRACK_AS (char_iterator_backtrack )-> u .charpos .othercasebit = charpos_othercasebit ;
10789- }
10790- }
1079110787
10792- SLJIT_ASSERT (tmp_base == TMP3 );
10793- if (charpos_enabled )
10794- {
10795- if (opcode == OP_UPTO )
10796- OP1 (SLJIT_MOV ,tmp_base ,tmp_offset ,SLJIT_IMM ,max + 1 );
10788+ if (private_data_ptr == 0 )
10789+ allocate_stack (common ,2 );
1079710790
10798- /* Search the first instance of charpos_char. */
10799- if (exact == 1 )
10800- {
10801- SLJIT_ASSERT (opcode == OP_STAR );
10802- detect_partial_match (common ,& backtrack -> own_backtracks );
10803- }
10804- else
10805- jump = JUMP (SLJIT_JUMP );
10791+ use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR );
1080610792
10807- label = LABEL ();
10808- if (opcode == OP_UPTO )
10809- {
10810- OP2 (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,tmp_base ,tmp_offset ,SLJIT_IMM ,1 );
10811- add_jump (compiler ,& backtrack -> own_backtracks ,JUMP (SLJIT_ZERO ));
10812- }
10813- compile_char1_matchingpath (common ,type ,cc ,& backtrack -> own_backtracks , FALSE);
10814- if (early_fail_ptr != 0 )
10815- OP1 (SLJIT_MOV ,SLJIT_MEM1 (SLJIT_SP ),early_fail_ptr ,STR_PTR ,0 );
10816-
10817- if (exact != 1 )
10818- JUMPHERE (jump );
10793+ if (use_tmp )
10794+ {
10795+ OP1 (SLJIT_MOV ,tmp_base ,tmp_offset ,SLJIT_IMM ,0 );
10796+ OP1 (SLJIT_MOV ,base ,offset0 ,tmp_base ,tmp_offset );
10797+ }
10798+ else
10799+ {
10800+ OP1 (SLJIT_MOV ,TMP1 ,0 ,SLJIT_IMM ,0 );
10801+ OP1 (SLJIT_MOV ,base ,offset0 ,TMP1 ,0 );
10802+ OP1 (SLJIT_MOV ,base ,offset1 ,TMP1 ,0 );
10803+ if (opcode == OP_UPTO )
10804+ OP1 (SLJIT_MOV ,tmp_base ,tmp_offset ,SLJIT_IMM ,max + 1 );
10805+ }
1081910806
10820- detect_partial_match (common ,& backtrack -> own_backtracks );
10821- OP1 (MOV_UCHAR ,TMP1 ,0 ,SLJIT_MEM1 (STR_PTR ),IN_UCHARS (0 ));
10822- if (charpos_othercasebit != 0 )
10823- OP2 (SLJIT_OR ,TMP1 ,0 ,TMP1 ,0 ,SLJIT_IMM ,charpos_othercasebit );
10824- CMPTO (SLJIT_NOT_EQUAL ,TMP1 ,0 ,SLJIT_IMM ,charpos_char ,label );
10807+ /* Search the first instance of charpos_char. */
10808+ if (exact == 1 )
10809+ {
10810+ SLJIT_ASSERT (opcode == OP_STAR );
10811+ detect_partial_match (common ,& no_match );
10812+ }
10813+ else
10814+ jump = JUMP (SLJIT_JUMP );
1082510815
10826- if (private_data_ptr == 0 )
10827- {
10828- if (opcode == OP_UPTO )
10829- OP1 (SLJIT_MOV ,TMP2 ,0 ,tmp_base ,tmp_offset );
10830- allocate_stack (common ,2 );
10816+ label = LABEL ();
1083110817if (opcode == OP_UPTO )
10832- OP1 (SLJIT_MOV ,tmp_base ,tmp_offset ,TMP2 ,0 );
10833- }
10834- OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10835- OP1 (SLJIT_MOV ,base ,offset1 ,STR_PTR ,0 );
10818+ {
10819+ OP2 (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,tmp_base ,tmp_offset ,SLJIT_IMM ,1 );
10820+ add_jump (compiler ,& no_match ,JUMP (SLJIT_ZERO ));
10821+ }
10822+ compile_char1_matchingpath (common ,type ,cc ,& no_match , FALSE);
1083610823
10837- if (opcode == OP_UPTO )
10838- {
10839- OP2 (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,tmp_base ,tmp_offset ,SLJIT_IMM ,1 );
10840- add_jump (compiler ,& no_match ,JUMP (SLJIT_ZERO ));
10841- }
10824+ if (early_fail_ptr != 0 )
10825+ OP1 (SLJIT_MOV ,SLJIT_MEM1 (SLJIT_SP ),early_fail_ptr ,STR_PTR ,0 );
1084210826
10843- /* Search the last instance of charpos_char. */
10844- label = LABEL ();
10845- compile_char1_matchingpath (common ,type ,cc ,& no_match , FALSE);
10846- if (early_fail_ptr != 0 )
10847- OP1 (SLJIT_MOV ,SLJIT_MEM1 (SLJIT_SP ),early_fail_ptr ,STR_PTR ,0 );
10848- detect_partial_match (common ,& no_match );
10849- OP1 (MOV_UCHAR ,TMP1 ,0 ,SLJIT_MEM1 (STR_PTR ),IN_UCHARS (0 ));
10850- if (charpos_othercasebit != 0 )
10851- OP2 (SLJIT_OR ,TMP1 ,0 ,TMP1 ,0 ,SLJIT_IMM ,charpos_othercasebit );
10827+ if (exact != 1 )
10828+ JUMPHERE (jump );
1085210829
10853- if (opcode == OP_STAR )
10854- {
10830+ detect_partial_match (common ,& no_match );
10831+ OP1 (MOV_UCHAR ,TMP1 ,0 ,SLJIT_MEM1 (STR_PTR ),IN_UCHARS (0 ));
10832+ if (charpos_othercasebit != 0 )
10833+ OP2 (SLJIT_OR ,TMP1 ,0 ,TMP1 ,0 ,SLJIT_IMM ,charpos_othercasebit );
1085510834CMPTO (SLJIT_NOT_EQUAL ,TMP1 ,0 ,SLJIT_IMM ,charpos_char ,label );
10856- OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10835+
10836+ if (use_tmp )
10837+ {
10838+ OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10839+ OP2U (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,SLJIT_IMM ,0 );
10840+ SELECT (SLJIT_EQUAL ,tmp_base ,STR_PTR ,0 ,tmp_base );
10841+ }
10842+ else
10843+ {
10844+ OP1 (SLJIT_MOV ,TMP2 ,0 ,base ,offset1 );
10845+ OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10846+ OP2U (SLJIT_SUB |SLJIT_SET_Z ,TMP2 ,0 ,SLJIT_IMM ,0 );
10847+ SELECT (SLJIT_EQUAL ,TMP2 ,STR_PTR ,0 ,TMP2 );
10848+ OP1 (SLJIT_MOV ,base ,offset1 ,TMP2 ,0 );
10849+ }
1085710850JUMPTO (SLJIT_JUMP ,label );
10858- }
10859- else
10860- {
10861- jump = CMP (SLJIT_NOT_EQUAL ,TMP1 ,0 ,SLJIT_IMM ,charpos_char );
10851+
10852+ set_jumps (no_match ,LABEL ());
10853+ OP1 (SLJIT_MOV ,STR_PTR ,0 ,base ,offset0 );
10854+ if (use_tmp )
10855+ OP1 (SLJIT_MOV ,base ,offset1 ,tmp_base ,tmp_offset );
10856+
10857+ add_jump (compiler ,& backtrack -> own_backtracks ,CMP (SLJIT_EQUAL ,STR_PTR ,0 ,SLJIT_IMM ,0 ));
10858+
10859+ BACKTRACK_AS (char_iterator_backtrack )-> matchingpath = LABEL ();
1086210860OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10863- JUMPHERE (jump );
10864- OP2 (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,tmp_base ,tmp_offset ,SLJIT_IMM ,1 );
10865- JUMPTO (SLJIT_NOT_ZERO ,label );
10861+ OP2 (SLJIT_ADD ,STR_PTR ,0 ,STR_PTR ,0 ,SLJIT_IMM ,IN_UCHARS (1 ));
10862+ break ;
1086610863 }
10867-
10868- set_jumps (no_match ,LABEL ());
10869- OP2 (SLJIT_ADD ,STR_PTR ,0 ,base ,offset0 ,SLJIT_IMM ,IN_UCHARS (1 ));
10870- OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
1087110864 }
10872- else
10873- {
10874- if (private_data_ptr == 0 )
10875- allocate_stack (common ,2 );
1087610865
10877- OP1 (SLJIT_MOV ,base ,offset1 ,STR_PTR ,0 );
10866+ if (private_data_ptr == 0 )
10867+ allocate_stack (common ,2 );
10868+
10869+ OP1 (SLJIT_MOV ,base ,offset1 ,STR_PTR ,0 );
1087810870#if definedSUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10879- use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR );
10880- SLJIT_ASSERT (!use_tmp || tmp_base == TMP3 );
10871+ use_tmp = (!HAS_VIRTUAL_REGISTERS && opcode == OP_STAR );
10872+ SLJIT_ASSERT (!use_tmp || tmp_base == TMP3 );
1088110873
10882- if (common -> utf )
10883- OP1 (SLJIT_MOV ,use_tmp ?TMP3 :base ,use_tmp ?0 :offset0 ,STR_PTR ,0 );
10874+ if (common -> utf )
10875+ OP1 (SLJIT_MOV ,use_tmp ?TMP3 :base ,use_tmp ?0 :offset0 ,STR_PTR ,0 );
1088410876#endif
10885- if (opcode == OP_UPTO )
10886- OP1 (SLJIT_MOV ,tmp_base ,tmp_offset ,SLJIT_IMM ,max );
10877+ if (opcode == OP_UPTO )
10878+ OP1 (SLJIT_MOV ,tmp_base ,tmp_offset ,SLJIT_IMM ,max );
1088710879
10888- detect_partial_match (common ,& no_match );
10889- label = LABEL ();
10890- compile_char1_matchingpath (common ,type ,cc ,& no_char1_match , FALSE);
10880+ detect_partial_match (common ,& no_match );
10881+ label = LABEL ();
10882+ compile_char1_matchingpath (common ,type ,cc ,& no_char1_match , FALSE);
1089110883#if definedSUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10892- if (common -> utf )
10893- OP1 (SLJIT_MOV ,use_tmp ?TMP3 :base ,use_tmp ?0 :offset0 ,STR_PTR ,0 );
10884+ if (common -> utf )
10885+ OP1 (SLJIT_MOV ,use_tmp ?TMP3 :base ,use_tmp ?0 :offset0 ,STR_PTR ,0 );
1089410886#endif
1089510887
10896- if (opcode == OP_UPTO )
10897- {
10898- OP2 (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,tmp_base ,tmp_offset ,SLJIT_IMM ,1 );
10899- add_jump (compiler ,& no_match ,JUMP (SLJIT_ZERO ));
10900- }
10888+ if (opcode == OP_UPTO )
10889+ {
10890+ OP2 (SLJIT_SUB |SLJIT_SET_Z ,tmp_base ,tmp_offset ,tmp_base ,tmp_offset ,SLJIT_IMM ,1 );
10891+ add_jump (compiler ,& no_match ,JUMP (SLJIT_ZERO ));
10892+ }
1090110893
10902- detect_partial_match_to (common ,label );
10903- OP2 (SLJIT_ADD ,STR_PTR ,0 ,STR_PTR ,0 ,SLJIT_IMM ,IN_UCHARS (1 ));
10894+ detect_partial_match_to (common ,label );
10895+ OP2 (SLJIT_ADD ,STR_PTR ,0 ,STR_PTR ,0 ,SLJIT_IMM ,IN_UCHARS (1 ));
1090410896
10905- set_jumps (no_char1_match ,LABEL ());
10897+ set_jumps (no_char1_match ,LABEL ());
1090610898#if definedSUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32
10907- if (common -> utf )
10899+ if (common -> utf )
10900+ {
10901+ set_jumps (no_match ,LABEL ());
10902+ if (use_tmp )
1090810903 {
10909- set_jumps (no_match ,LABEL ());
10910- if (use_tmp )
10911- {
10912- OP1 (SLJIT_MOV ,STR_PTR ,0 ,TMP3 ,0 );
10913- OP1 (SLJIT_MOV ,base ,offset0 ,TMP3 ,0 );
10914- }
10915- else
10916- OP1 (SLJIT_MOV ,STR_PTR ,0 ,base ,offset0 );
10904+ OP1 (SLJIT_MOV ,STR_PTR ,0 ,TMP3 ,0 );
10905+ OP1 (SLJIT_MOV ,base ,offset0 ,TMP3 ,0 );
1091710906 }
1091810907else
10908+ OP1 (SLJIT_MOV ,STR_PTR ,0 ,base ,offset0 );
10909+ }
10910+ else
1091910911#endif
10920- {
10921- OP2 (SLJIT_SUB ,STR_PTR ,0 ,STR_PTR ,0 ,SLJIT_IMM ,IN_UCHARS (1 ));
10922- set_jumps (no_match ,LABEL ());
10923- OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10924- }
10925-
10926- if (exact == 1 )
10927- {
10928- SLJIT_ASSERT (opcode == OP_STAR );
10929- add_jump (compiler ,& BACKTRACK_AS (char_iterator_backtrack )-> u .backtracks ,CMP (SLJIT_EQUAL ,base ,offset1 ,STR_PTR ,0 ));
10930- }
10912+ {
10913+ OP2 (SLJIT_SUB ,STR_PTR ,0 ,STR_PTR ,0 ,SLJIT_IMM ,IN_UCHARS (1 ));
10914+ set_jumps (no_match ,LABEL ());
10915+ OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
10916+ }
1093110917
10932- if (early_fail_ptr != 0 )
10933- OP1 (SLJIT_MOV ,SLJIT_MEM1 (SLJIT_SP ),early_fail_ptr ,STR_PTR ,0 );
10918+ if (exact == 1 )
10919+ {
10920+ SLJIT_ASSERT (opcode == OP_STAR );
10921+ add_jump (compiler ,& BACKTRACK_AS (char_iterator_backtrack )-> u .backtracks ,CMP (SLJIT_EQUAL ,base ,offset1 ,STR_PTR ,0 ));
1093410922 }
1093510923
10924+ if (early_fail_ptr != 0 )
10925+ OP1 (SLJIT_MOV ,SLJIT_MEM1 (SLJIT_SP ),early_fail_ptr ,STR_PTR ,0 );
10926+
1093610927BACKTRACK_AS (char_iterator_backtrack )-> matchingpath = LABEL ();
1093710928break ;
1093810929
@@ -11661,19 +11652,22 @@ switch(opcode)
1166111652 {
1166211653OP1 (SLJIT_MOV ,STR_PTR ,0 ,base ,offset0 );
1166311654OP1 (SLJIT_MOV ,TMP2 ,0 ,base ,offset1 );
11664- OP2 (SLJIT_SUB ,STR_PTR ,0 ,STR_PTR ,0 ,SLJIT_IMM ,IN_UCHARS (1 ));
1166511655
1166611656jump = CMP (SLJIT_LESS_EQUAL ,STR_PTR ,0 ,TMP2 ,0 );
1166711657label = LABEL ();
1166811658if (type == OP_ANYNL )
1166911659compile_newline_move_back (common );
11670- OP1 (MOV_UCHAR ,TMP1 ,0 ,SLJIT_MEM1 (STR_PTR ),IN_UCHARS (-1 ));
11671- OP1 (SLJIT_MOV ,base ,offset0 ,STR_PTR ,0 );
11660+ move_back (common ,NULL , TRUE);
11661+
11662+ OP1 (MOV_UCHAR ,TMP1 ,0 ,SLJIT_MEM1 (STR_PTR ),IN_UCHARS (0 ));
1167211663if (CURRENT_AS (char_iterator_backtrack )-> u .charpos .othercasebit != 0 )
1167311664OP2 (SLJIT_OR ,TMP1 ,0 ,TMP1 ,0 ,SLJIT_IMM ,CURRENT_AS (char_iterator_backtrack )-> u .charpos .othercasebit );
1167411665CMPTO (SLJIT_EQUAL ,TMP1 ,0 ,SLJIT_IMM ,CURRENT_AS (char_iterator_backtrack )-> u .charpos .chr ,CURRENT_AS (char_iterator_backtrack )-> matchingpath );
11675- move_back (common ,NULL , TRUE);
11676- CMPTO (SLJIT_GREATER ,STR_PTR ,0 ,TMP2 ,0 ,label );
11666+ /* The range beginning must match, no need to compare. */
11667+ JUMPTO (SLJIT_JUMP ,label );
11668+
11669+ set_jumps (current -> own_backtracks ,LABEL ());
11670+ current -> own_backtracks = NULL ;
1167711671 }
1167811672else
1167911673 {