/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 941 by zherczeg, Tue Feb 28 11:33:34 2012 UTC revision 999 by zherczeg, Mon Aug 6 07:36:49 2012 UTC
# Line 82  The code generator follows the recursive Line 82  The code generator follows the recursive
82  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
83  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
84  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
85  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
86    
87    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
88    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
92  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
93  the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94  branches on the hot path.  branches on the matching path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Hot path: match happens.     Matching path: match happens.
98     Fallback path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Hot path: no need to perform a match.     Matching path: no need to perform a match.
101     Fallback path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
104  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# Line 108  we have the following regular expression Line 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A hot path   A matching path
112   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
113   B hot path   B matching path
114   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
115   D hot path   D matching path
116   return with successful match   return with successful match
117    
118   D fallback path   D backtrack path
119   ')' fallback path (If we arrived from "C" jump to the fallback of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120   B fallback path   B backtrack path
121   C expected path   C expected path
122   jump to D hot path   jump to D matching path
123   C fallback path   C backtrack path
124   A fallback path   A backtrack path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of backtrack code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
129   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
130   the hot path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
134  /*  /*
135  Saved stack frames:  Saved stack frames:
136    
137  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of local variables
138  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the locals
139  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
140  mechanism.  mechanism.
141    
# Line 181  typedef struct stub_list { Line 181  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
182    int data;    int data;
183    struct sljit_jump *start;    struct sljit_jump *start;
184    struct sljit_label *leave;    struct sljit_label *quit;
185    struct stub_list *next;    struct stub_list *next;
186  } stub_list;  } stub_list;
187    
188  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189    
190  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
191  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
192  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
193  of its descendants. */  of its descendants. */
194  typedef struct fallback_common {  typedef struct backtrack_common {
195    /* Concatenation stack. */    /* Concatenation stack. */
196    struct fallback_common *prev;    struct backtrack_common *prev;
197    jump_list *nextfallbacks;    jump_list *nextbacktracks;
198    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
199    struct fallback_common *top;    struct backtrack_common *top;
200    jump_list *topfallbacks;    jump_list *topbacktracks;
201    /* Opcode pointer. */    /* Opcode pointer. */
202    pcre_uchar *cc;    pcre_uchar *cc;
203  } fallback_common;  } backtrack_common;
204    
205  typedef struct assert_fallback {  typedef struct assert_backtrack {
206    fallback_common common;    backtrack_common common;
207    jump_list *condfailed;    jump_list *condfailed;
208    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
209    int framesize;    int framesize;
210    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
211    int localptr;    int localptr;
212    /* For iterators. */    /* For iterators. */
213    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
214  } assert_fallback;  } assert_backtrack;
215    
216  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
217    fallback_common common;    backtrack_common common;
218    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
219    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
224    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
225    union {    union {
226      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
227      jump_list *condfailed;      jump_list *condfailed;
228      assert_fallback *assert;      assert_backtrack *assert;
229      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
230      int framesize;      int framesize;
231    } u;    } u;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int localptr;    int localptr;
234  } bracket_fallback;  } bracket_backtrack;
235    
236  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
237    fallback_common common;    backtrack_common common;
238    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
239    int localptr;    int localptr;
240    /* Reverting stack is needed. */    /* Reverting stack is needed. */
241    int framesize;    int framesize;
242    /* Allocated stack size. */    /* Allocated stack size. */
243    int stacksize;    int stacksize;
244  } bracketpos_fallback;  } bracketpos_backtrack;
245    
246  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
247    fallback_common common;    backtrack_common common;
248    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
249  } braminzero_fallback;  } braminzero_backtrack;
250    
251  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
252    fallback_common common;    backtrack_common common;
253    /* Next iteration. */    /* Next iteration. */
254    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
255  } iterator_fallback;  } iterator_backtrack;
256    
257  typedef struct recurse_entry {  typedef struct recurse_entry {
258    struct recurse_entry *next;    struct recurse_entry *next;
# Line 264  typedef struct recurse_entry { Line 264  typedef struct recurse_entry {
264    int start;    int start;
265  } recurse_entry;  } recurse_entry;
266    
267  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
268    fallback_common common;    backtrack_common common;
269  } recurse_fallback;  } recurse_backtrack;
270    
271    #define MAX_RANGE_SIZE 6
272    
273  typedef struct compiler_common {  typedef struct compiler_common {
274    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
275    pcre_uchar *start;    pcre_uchar *start;
276    
277    /* Local stack area size and variable pointers. */    /* Opcode local area direct map. */
   int localsize;  
278    int *localptrs;    int *localptrs;
279    int cbraptr;    int cbraptr;
280    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
# Line 291  typedef struct compiler_common { Line 292  typedef struct compiler_common {
292    /* Points to the marked string. */    /* Points to the marked string. */
293    int mark_ptr;    int mark_ptr;
294    
295    /* Other  */    /* Flipped and lower case tables. */
296    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
297    sljit_w lcc;    sljit_w lcc;
298      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
299    int mode;    int mode;
300      /* Newline control. */
301    int nltype;    int nltype;
302    int newline;    int newline;
303    int bsr_nltype;    int bsr_nltype;
304      /* Dollar endonly. */
305    int endonly;    int endonly;
306    BOOL has_set_som;    BOOL has_set_som;
307      /* Tables. */
308    sljit_w ctypes;    sljit_w ctypes;
309      int digits[2 + MAX_RANGE_SIZE];
310      /* Named capturing brackets. */
311    sljit_uw name_table;    sljit_uw name_table;
312    sljit_w name_count;    sljit_w name_count;
313    sljit_w name_entry_size;    sljit_w name_entry_size;
314    
315    /* Labels and jump lists. */    /* Labels and jump lists. */
316    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
317    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
318    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
319    stub_list *stubs;    stub_list *stubs;
320    recurse_entry *entries;    recurse_entry *entries;
321    recurse_entry *currententry;    recurse_entry *currententry;
322    jump_list *partialmatch;    jump_list *partialmatch;
323    jump_list *leave;    jump_list *quit;
324    jump_list *accept;    jump_list *accept;
325    jump_list *calllimit;    jump_list *calllimit;
326    jump_list *stackalloc;    jump_list *stackalloc;
# Line 448  the start pointers when the end of the c Line 455  the start pointers when the end of the c
455    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
456  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
457    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
458    #define GET_LOCAL_BASE(dst, dstw, offset) \
459      sljit_get_local_base(compiler, (dst), (dstw), (offset))
460    
461  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
462  {  {
# Line 466  return cc; Line 475  return cc;
475   init_frame   init_frame
476   get_localsize   get_localsize
477   copy_locals   copy_locals
478   compile_hotpath   compile_matchingpath
479   compile_fallbackpath   compile_backtrackingpath
480  */  */
481    
482  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 666  switch(*cc) Line 675  switch(*cc)
675    }    }
676  }  }
677    
678    #define CASE_ITERATOR_LOCAL1 \
679        case OP_MINSTAR: \
680        case OP_MINPLUS: \
681        case OP_QUERY: \
682        case OP_MINQUERY: \
683        case OP_MINSTARI: \
684        case OP_MINPLUSI: \
685        case OP_QUERYI: \
686        case OP_MINQUERYI: \
687        case OP_NOTMINSTAR: \
688        case OP_NOTMINPLUS: \
689        case OP_NOTQUERY: \
690        case OP_NOTMINQUERY: \
691        case OP_NOTMINSTARI: \
692        case OP_NOTMINPLUSI: \
693        case OP_NOTQUERYI: \
694        case OP_NOTMINQUERYI:
695    
696    #define CASE_ITERATOR_LOCAL2A \
697        case OP_STAR: \
698        case OP_PLUS: \
699        case OP_STARI: \
700        case OP_PLUSI: \
701        case OP_NOTSTAR: \
702        case OP_NOTPLUS: \
703        case OP_NOTSTARI: \
704        case OP_NOTPLUSI:
705    
706    #define CASE_ITERATOR_LOCAL2B \
707        case OP_UPTO: \
708        case OP_MINUPTO: \
709        case OP_UPTOI: \
710        case OP_MINUPTOI: \
711        case OP_NOTUPTO: \
712        case OP_NOTMINUPTO: \
713        case OP_NOTUPTOI: \
714        case OP_NOTMINUPTOI:
715    
716    #define CASE_ITERATOR_TYPE_LOCAL1 \
717        case OP_TYPEMINSTAR: \
718        case OP_TYPEMINPLUS: \
719        case OP_TYPEQUERY: \
720        case OP_TYPEMINQUERY:
721    
722    #define CASE_ITERATOR_TYPE_LOCAL2A \
723        case OP_TYPESTAR: \
724        case OP_TYPEPLUS:
725    
726    #define CASE_ITERATOR_TYPE_LOCAL2B \
727        case OP_TYPEUPTO: \
728        case OP_TYPEMINUPTO:
729    
730    static int get_class_iterator_size(pcre_uchar *cc)
731    {
732    switch(*cc)
733      {
734      case OP_CRSTAR:
735      case OP_CRPLUS:
736      return 2;
737    
738      case OP_CRMINSTAR:
739      case OP_CRMINPLUS:
740      case OP_CRQUERY:
741      case OP_CRMINQUERY:
742      return 1;
743    
744      case OP_CRRANGE:
745      case OP_CRMINRANGE:
746      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
747        return 0;
748      return 2;
749    
750      default:
751      return 0;
752      }
753    }
754    
755  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
756  {  {
757  int localspace = 0;  int localspace = 0;
758  pcre_uchar *alternative;  pcre_uchar *alternative;
759    pcre_uchar *end = NULL;
760    int space, size, bracketlen;
761    
762  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
763  while (cc < ccend)  while (cc < ccend)
764    {    {
765      space = 0;
766      size = 0;
767      bracketlen = 0;
768    switch(*cc)    switch(*cc)
769      {      {
770      case OP_SET_SOM:      case OP_SET_SOM:
# Line 691  while (cc < ccend) Line 783  while (cc < ccend)
783      case OP_SBRAPOS:      case OP_SBRAPOS:
784      case OP_SCOND:      case OP_SCOND:
785      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
786      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
787      break;      break;
788    
789      case OP_CBRAPOS:      case OP_CBRAPOS:
790      case OP_SCBRAPOS:      case OP_SCBRAPOS:
791      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
792      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
793      break;      break;
794    
795      case OP_COND:      case OP_COND:
# Line 705  while (cc < ccend) Line 797  while (cc < ccend)
797      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
798      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
799        localspace += sizeof(sljit_w);        localspace += sizeof(sljit_w);
800      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
801        break;
802    
803        case OP_BRA:
804        bracketlen = 1 + LINK_SIZE;
805        break;
806    
807        case OP_CBRA:
808        case OP_SCBRA:
809        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
810        break;
811    
812        CASE_ITERATOR_LOCAL1
813        space = 1;
814        size = -2;
815        break;
816    
817        CASE_ITERATOR_LOCAL2A
818        space = 2;
819        size = -2;
820        break;
821    
822        CASE_ITERATOR_LOCAL2B
823        space = 2;
824        size = -(2 + IMM2_SIZE);
825        break;
826    
827        CASE_ITERATOR_TYPE_LOCAL1
828        space = 1;
829        size = 1;
830        break;
831    
832        CASE_ITERATOR_TYPE_LOCAL2A
833        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
834          space = 2;
835        size = 1;
836      break;      break;
837    
838        CASE_ITERATOR_TYPE_LOCAL2B
839        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
840          space = 2;
841        size = 1 + IMM2_SIZE;
842        break;
843    
844        case OP_CLASS:
845        case OP_NCLASS:
846        size += 1 + 32 / sizeof(pcre_uchar);
847        space = get_class_iterator_size(cc + size);
848        break;
849    
850    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
851        case OP_XCLASS:
852        size = GET(cc, 1);
853        space = get_class_iterator_size(cc + size);
854        break;
855    #endif
856    
857      case OP_RECURSE:      case OP_RECURSE:
858      /* Set its value only once. */      /* Set its value only once. */
859      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 733  while (cc < ccend) Line 879  while (cc < ccend)
879        return -1;        return -1;
880      break;      break;
881      }      }
882    
883      if (space > 0 && cc >= end)
884        localspace += sizeof(sljit_w) * space;
885    
886      if (size != 0)
887        {
888        if (size < 0)
889          {
890          cc += -size;
891    #ifdef SUPPORT_UTF
892          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
893    #endif
894          }
895        else
896          cc += size;
897        }
898    
899      if (bracketlen > 0)
900        {
901        if (cc >= end)
902          {
903          end = bracketend(cc);
904          if (end[-1 - LINK_SIZE] == OP_KET)
905            end = NULL;
906          }
907        cc += bracketlen;
908        }
909    }    }
910  return localspace;  return localspace;
911  }  }
# Line 741  static void set_localptrs(compiler_commo Line 914  static void set_localptrs(compiler_commo
914  {  {
915  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
916  pcre_uchar *alternative;  pcre_uchar *alternative;
917    pcre_uchar *end = NULL;
918    int space, size, bracketlen;
919    
920  while (cc < ccend)  while (cc < ccend)
921    {    {
922      space = 0;
923      size = 0;
924      bracketlen = 0;
925    switch(*cc)    switch(*cc)
926      {      {
927      case OP_ASSERT:      case OP_ASSERT:
# Line 757  while (cc < ccend) Line 936  while (cc < ccend)
936      case OP_SCOND:      case OP_SCOND:
937      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
938      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
939      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
940      break;      break;
941    
942      case OP_CBRAPOS:      case OP_CBRAPOS:
943      case OP_SCBRAPOS:      case OP_SCBRAPOS:
944      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
945      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
946      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      case OP_COND:      case OP_COND:
# Line 775  while (cc < ccend) Line 954  while (cc < ccend)
954        common->localptrs[cc - common->start] = localptr;        common->localptrs[cc - common->start] = localptr;
955        localptr += sizeof(sljit_w);        localptr += sizeof(sljit_w);
956        }        }
957      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
958      break;      break;
959    
960        case OP_BRA:
961        bracketlen = 1 + LINK_SIZE;
962        break;
963    
964        case OP_CBRA:
965        case OP_SCBRA:
966        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
967        break;
968    
969        CASE_ITERATOR_LOCAL1
970        space = 1;
971        size = -2;
972        break;
973    
974        CASE_ITERATOR_LOCAL2A
975        space = 2;
976        size = -2;
977        break;
978    
979        CASE_ITERATOR_LOCAL2B
980        space = 2;
981        size = -(2 + IMM2_SIZE);
982        break;
983    
984        CASE_ITERATOR_TYPE_LOCAL1
985        space = 1;
986        size = 1;
987        break;
988    
989        CASE_ITERATOR_TYPE_LOCAL2A
990        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
991          space = 2;
992        size = 1;
993        break;
994    
995        CASE_ITERATOR_TYPE_LOCAL2B
996        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
997          space = 2;
998        size = 1 + IMM2_SIZE;
999        break;
1000    
1001        case OP_CLASS:
1002        case OP_NCLASS:
1003        size += 1 + 32 / sizeof(pcre_uchar);
1004        space = get_class_iterator_size(cc + size);
1005        break;
1006    
1007    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1008        case OP_XCLASS:
1009        size = GET(cc, 1);
1010        space = get_class_iterator_size(cc + size);
1011        break;
1012    #endif
1013    
1014      default:      default:
1015      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1016      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1017      break;      break;
1018      }      }
1019    
1020      if (space > 0 && cc >= end)
1021        {
1022        common->localptrs[cc - common->start] = localptr;
1023        localptr += sizeof(sljit_w) * space;
1024        }
1025    
1026      if (size != 0)
1027        {
1028        if (size < 0)
1029          {
1030          cc += -size;
1031    #ifdef SUPPORT_UTF
1032          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1033    #endif
1034          }
1035        else
1036          cc += size;
1037        }
1038    
1039      if (bracketlen > 0)
1040        {
1041        if (cc >= end)
1042          {
1043          end = bracketend(cc);
1044          if (end[-1 - LINK_SIZE] == OP_KET)
1045            end = NULL;
1046          }
1047        cc += bracketlen;
1048        }
1049    }    }
1050  }  }
1051    
# Line 962  SLJIT_ASSERT(stackpos == STACK(stacktop) Line 1225  SLJIT_ASSERT(stackpos == STACK(stacktop)
1225  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1226  {  {
1227  int localsize = 2;  int localsize = 2;
1228    int size;
1229  pcre_uchar *alternative;  pcre_uchar *alternative;
1230  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
1231  while (cc < ccend)  while (cc < ccend)
1232    {    {
1233      size = 0;
1234    switch(*cc)    switch(*cc)
1235      {      {
1236      case OP_ASSERT:      case OP_ASSERT:
# Line 1002  while (cc < ccend) Line 1267  while (cc < ccend)
1267      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1268      break;      break;
1269    
1270        CASE_ITERATOR_LOCAL1
1271        if (PRIV_DATA(cc))
1272          localsize++;
1273        cc += 2;
1274    #ifdef SUPPORT_UTF
1275        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1276    #endif
1277        break;
1278    
1279        CASE_ITERATOR_LOCAL2A
1280        if (PRIV_DATA(cc))
1281          localsize += 2;
1282        cc += 2;
1283    #ifdef SUPPORT_UTF
1284        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1285    #endif
1286        break;
1287    
1288        CASE_ITERATOR_LOCAL2B
1289        if (PRIV_DATA(cc))
1290          localsize += 2;
1291        cc += 2 + IMM2_SIZE;
1292    #ifdef SUPPORT_UTF
1293        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1294    #endif
1295        break;
1296    
1297        CASE_ITERATOR_TYPE_LOCAL1
1298        if (PRIV_DATA(cc))
1299          localsize++;
1300        cc += 1;
1301        break;
1302    
1303        CASE_ITERATOR_TYPE_LOCAL2A
1304        if (PRIV_DATA(cc))
1305          localsize += 2;
1306        cc += 1;
1307        break;
1308    
1309        CASE_ITERATOR_TYPE_LOCAL2B
1310        if (PRIV_DATA(cc))
1311          localsize += 2;
1312        cc += 1 + IMM2_SIZE;
1313        break;
1314    
1315        case OP_CLASS:
1316        case OP_NCLASS:
1317    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1318        case OP_XCLASS:
1319        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1320    #else
1321        size = 1 + 32 / (int)sizeof(pcre_uchar);
1322    #endif
1323        if (PRIV_DATA(cc))
1324          localsize += get_class_iterator_size(cc + size);
1325        cc += size;
1326        break;
1327    
1328      default:      default:
1329      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1330      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1017  static void copy_locals(compiler_common Line 1340  static void copy_locals(compiler_common
1340  {  {
1341  DEFINE_COMPILER;  DEFINE_COMPILER;
1342  int srcw[2];  int srcw[2];
1343  int count;  int count, size;
1344  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1345  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1346  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1097  while (status != end) Line 1420  while (status != end)
1420        case OP_CBRAPOS:        case OP_CBRAPOS:
1421        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1422        count = 2;        count = 2;
1423        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1424        srcw[0] = PRIV_DATA(cc);        srcw[1] = PRIV_DATA(cc);
1425        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1426        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1427        break;        break;
# Line 1115  while (status != end) Line 1438  while (status != end)
1438        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1439        break;        break;
1440    
1441          CASE_ITERATOR_LOCAL1
1442          if (PRIV_DATA(cc))
1443            {
1444            count = 1;
1445            srcw[0] = PRIV_DATA(cc);
1446            }
1447          cc += 2;
1448    #ifdef SUPPORT_UTF
1449          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1450    #endif
1451          break;
1452    
1453          CASE_ITERATOR_LOCAL2A
1454          if (PRIV_DATA(cc))
1455            {
1456            count = 2;
1457            srcw[0] = PRIV_DATA(cc);
1458            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1459            }
1460          cc += 2;
1461    #ifdef SUPPORT_UTF
1462          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1463    #endif
1464          break;
1465    
1466          CASE_ITERATOR_LOCAL2B
1467          if (PRIV_DATA(cc))
1468            {
1469            count = 2;
1470            srcw[0] = PRIV_DATA(cc);
1471            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1472            }
1473          cc += 2 + IMM2_SIZE;
1474    #ifdef SUPPORT_UTF
1475          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1476    #endif
1477          break;
1478    
1479          CASE_ITERATOR_TYPE_LOCAL1
1480          if (PRIV_DATA(cc))
1481            {
1482            count = 1;
1483            srcw[0] = PRIV_DATA(cc);
1484            }
1485          cc += 1;
1486          break;
1487    
1488          CASE_ITERATOR_TYPE_LOCAL2A
1489          if (PRIV_DATA(cc))
1490            {
1491            count = 2;
1492            srcw[0] = PRIV_DATA(cc);
1493            srcw[1] = srcw[0] + sizeof(sljit_w);
1494            }
1495          cc += 1;
1496          break;
1497    
1498          CASE_ITERATOR_TYPE_LOCAL2B
1499          if (PRIV_DATA(cc))
1500            {
1501            count = 2;
1502            srcw[0] = PRIV_DATA(cc);
1503            srcw[1] = srcw[0] + sizeof(sljit_w);
1504            }
1505          cc += 1 + IMM2_SIZE;
1506          break;
1507    
1508          case OP_CLASS:
1509          case OP_NCLASS:
1510    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1511          case OP_XCLASS:
1512          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1513    #else
1514          size = 1 + 32 / (int)sizeof(pcre_uchar);
1515    #endif
1516          if (PRIV_DATA(cc))
1517            switch(get_class_iterator_size(cc + size))
1518              {
1519              case 1:
1520              count = 1;
1521              srcw[0] = PRIV_DATA(cc);
1522              break;
1523    
1524              case 2:
1525              count = 2;
1526              srcw[0] = PRIV_DATA(cc);
1527              srcw[1] = srcw[0] + sizeof(sljit_w);
1528              break;
1529    
1530              default:
1531              SLJIT_ASSERT_STOP();
1532              break;
1533              }
1534          cc += size;
1535          break;
1536    
1537        default:        default:
1538        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1539        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1217  if (save) Line 1636  if (save)
1636  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1637  }  }
1638    
1639    #undef CASE_ITERATOR_LOCAL1
1640    #undef CASE_ITERATOR_LOCAL2A
1641    #undef CASE_ITERATOR_LOCAL2B
1642    #undef CASE_ITERATOR_TYPE_LOCAL1
1643    #undef CASE_ITERATOR_TYPE_LOCAL2A
1644    #undef CASE_ITERATOR_TYPE_LOCAL2B
1645    
1646  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1647  {  {
1648  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1227  static SLJIT_INLINE void set_jumps(jump_ Line 1653  static SLJIT_INLINE void set_jumps(jump_
1653  while (list)  while (list)
1654    {    {
1655    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1656    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1657    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1658    list = list->next;    list = list->next;
1659    }    }
# Line 1254  if (list_item) Line 1680  if (list_item)
1680    list_item->type = type;    list_item->type = type;
1681    list_item->data = data;    list_item->data = data;
1682    list_item->start = start;    list_item->start = start;
1683    list_item->leave = LABEL();    list_item->quit = LABEL();
1684    list_item->next = common->stubs;    list_item->next = common->stubs;
1685    common->stubs = list_item;    common->stubs = list_item;
1686    }    }
# Line 1274  while (list_item) Line 1700  while (list_item)
1700      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1701      break;      break;
1702      }      }
1703    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1704    list_item = list_item->next;    list_item = list_item->next;
1705    }    }
1706  common->stubs = NULL;  common->stubs = NULL;
# Line 1325  if (length < 8) Line 1751  if (length < 8)
1751    }    }
1752  else  else
1753    {    {
1754    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1755    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1756    loop = LABEL();    loop = LABEL();
1757    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1352  if (common->mark_ptr != 0) Line 1778  if (common->mark_ptr != 0)
1778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1779  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1780  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1781  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1782  /* Unlikely, but possible */  /* Unlikely, but possible */
1783  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1784  loop = LABEL();  loop = LABEL();
# Line 1370  JUMPHERE(earlyexit); Line 1796  JUMPHERE(earlyexit);
1796  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1797  if (topbracket > 1)  if (topbracket > 1)
1798    {    {
1799    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1800    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1801    
1802    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
# Line 1384  else Line 1810  else
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1811  }  }
1812    
1813  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1814  {  {
1815  DEFINE_COMPILER;  DEFINE_COMPILER;
1816    
# Line 1394  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1820  SLJIT_ASSERT(common->start_used_ptr != 0
1820  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1821  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1822  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1823  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1824    
1825  /* Store match begin and end. */  /* Store match begin and end. */
1826  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 1412  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1838  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1838  #endif  #endif
1839  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1840    
1841  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1842  }  }
1843    
1844  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1621  JUMPHERE(jump); Line 2047  JUMPHERE(jump);
2047  return return_value;  return return_value;
2048  }  }
2049    
2050  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2051  {  {
2052  DEFINE_COMPILER;  DEFINE_COMPILER;
2053  struct sljit_jump *jump;  struct sljit_jump *jump;
2054    
2055  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2056    {    {
2057    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2058    return;    return;
2059    }    }
2060    
2061  /* Partial matching mode. */  /* Partial matching mode. */
2062  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2063  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2064  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2065    {    {
2066    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2067    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2068    }    }
2069  else  else
2070    {    {
# Line 1788  if (common->utf) Line 2214  if (common->utf)
2214  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2215  }  }
2216    
2217  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
2218  {  {
2219  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2220  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1796  DEFINE_COMPILER; Line 2222  DEFINE_COMPILER;
2222  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2223    {    {
2224    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2225    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2226    }    }
2227  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2228    {    {
# Line 1804  else if (nltype == NLTYPE_ANYCRLF) Line 2230  else if (nltype == NLTYPE_ANYCRLF)
2230    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2231    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2232    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2233    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2234    }    }
2235  else  else
2236    {    {
2237    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2238    add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2239    }    }
2240  }  }
2241    
# Line 1823  of the character (>= 0xc0). Return char Line 2249  of the character (>= 0xc0). Return char
2249  DEFINE_COMPILER;  DEFINE_COMPILER;
2250  struct sljit_jump *jump;  struct sljit_jump *jump;
2251    
2252  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2253  /* Searching for the first zero. */  /* Searching for the first zero. */
2254  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2255  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1882  DEFINE_COMPILER; Line 2308  DEFINE_COMPILER;
2308  struct sljit_jump *jump;  struct sljit_jump *jump;
2309  struct sljit_jump *compare;  struct sljit_jump *compare;
2310    
2311  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2312    
2313  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
2314  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1919  of the character (>= 0xd800). Return cha Line 2345  of the character (>= 0xd800). Return cha
2345  DEFINE_COMPILER;  DEFINE_COMPILER;
2346  struct sljit_jump *jump;  struct sljit_jump *jump;
2347    
2348  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2349  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2350  /* Do nothing, only return. */  /* Do nothing, only return. */
2351  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1956  DEFINE_COMPILER; Line 2382  DEFINE_COMPILER;
2382    
2383  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2384    
2385  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2386  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2387  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
2388  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
# Line 1993  if (firstline) Line 2419  if (firstline)
2419    {    {
2420    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2421    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2423    
2424    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2425      {      {
# Line 2005  if (firstline) Line 2430  if (firstline)
2430      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2431      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2432      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2433        JUMPHERE(end);
2434      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2435      }      }
2436    else    else
# Line 2016  if (firstline) Line 2442  if (firstline)
2442      read_char(common);      read_char(common);
2443      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2444      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2445        JUMPHERE(end);
2446      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2447      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2448      }      }
2449    
2450    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2451    }    }
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2043  if (newlinecheck) Line 2469  if (newlinecheck)
2469    
2470  mainloop = LABEL();  mainloop = LABEL();
2471    
2472  /* Increasing the STR_PTR here requires one less jump in the most common case. */  /* Increasing the STR_PTR here requires one less jump in the most common case. */
2473  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2474  if (common->utf) readuchar = TRUE;  if (common->utf) readuchar = TRUE;
2475    #endif
2476    if (newlinecheck) readuchar = TRUE;
2477    
2478    if (readuchar)
2479      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2480    
2481    if (newlinecheck)
2482      CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2483    
2484    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2485    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2486    if (common->utf)
2487      {
2488      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2489      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2490      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2491      JUMPHERE(singlechar);
2492      }
2493    #endif
2494    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2495    if (common->utf)
2496      {
2497      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2498      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2499      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2500      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2501      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2502      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2503      JUMPHERE(singlechar);
2504      }
2505    #endif
2506    JUMPHERE(start);
2507    
2508    if (newlinecheck)
2509      {
2510      JUMPHERE(end);
2511      JUMPHERE(nl);
2512      }
2513    
2514    return mainloop;
2515    }
2516    
2517    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2518    {
2519    DEFINE_COMPILER;
2520    struct sljit_label *start;
2521    struct sljit_jump *quit;
2522    struct sljit_jump *found;
2523    pcre_int32 chars[4];
2524    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2525    int location = 0;
2526    pcre_int32 len, c, bit, caseless;
2527    BOOL must_end;
2528    
2529    #ifdef COMPILE_PCRE8
2530    union {
2531        sljit_uh ascombined;
2532        sljit_ub asuchars[2];
2533    } pair;
2534    #else
2535    union {
2536        sljit_ui ascombined;
2537        sljit_uh asuchars[2];
2538    } pair;
2539    #endif
2540    
2541    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2542      return FALSE;
2543    
2544    while (TRUE)
2545      {
2546      caseless = 0;
2547      must_end = TRUE;
2548      switch(*cc)
2549        {
2550        case OP_CHAR:
2551        must_end = FALSE;
2552        cc++;
2553        break;
2554    
2555        case OP_CHARI:
2556        caseless = 1;
2557        must_end = FALSE;
2558        cc++;
2559        break;
2560    
2561        case OP_SOD:
2562        case OP_SOM:
2563        case OP_SET_SOM:
2564        case OP_NOT_WORD_BOUNDARY:
2565        case OP_WORD_BOUNDARY:
2566        case OP_EODN:
2567        case OP_EOD:
2568        case OP_CIRC:
2569        case OP_CIRCM:
2570        case OP_DOLL:
2571        case OP_DOLLM:
2572        /* Zero width assertions. */
2573        cc++;
2574        continue;
2575    
2576        case OP_PLUS:
2577        case OP_MINPLUS:
2578        case OP_POSPLUS:
2579        cc++;
2580        break;
2581    
2582        case OP_EXACT:
2583        cc += 1 + IMM2_SIZE;
2584        break;
2585    
2586        case OP_PLUSI:
2587        case OP_MINPLUSI:
2588        case OP_POSPLUSI:
2589        caseless = 1;
2590        cc++;
2591        break;
2592    
2593        case OP_EXACTI:
2594        caseless = 1;
2595        cc += 1 + IMM2_SIZE;
2596        break;
2597    
2598        default:
2599        return FALSE;
2600        }
2601    
2602      len = 1;
2603    #ifdef SUPPORT_UTF
2604      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2605    #endif
2606    
2607      if (caseless && char_has_othercase(common, cc))
2608        {
2609        caseless = char_get_othercase_bit(common, cc);
2610        if (caseless == 0)
2611          return FALSE;
2612    #ifdef COMPILE_PCRE8
2613        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2614    #else
2615        if ((caseless & 0x100) != 0)
2616          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2617        else
2618          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2619    #endif
2620        }
2621      else
2622        caseless = 0;
2623    
2624      while (len > 0 && location < 2 * 2)
2625        {
2626        c = *cc;
2627        bit = 0;
2628        if (len == (caseless & 0xff))
2629          {
2630          bit = caseless >> 8;
2631          c |= bit;
2632          }
2633    
2634        chars[location] = c;
2635        chars[location + 1] = bit;
2636    
2637        len--;
2638        location += 2;
2639        cc++;
2640        }
2641    
2642      if (location == 2 * 2)
2643        break;
2644      else if (must_end)
2645        return FALSE;
2646      }
2647    
2648    if (firstline)
2649      {
2650      SLJIT_ASSERT(common->first_line_end != 0);
2651      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2652      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2653      }
2654    else
2655      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2656    
2657    start = LABEL();
2658    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2659    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2660    #ifdef COMPILE_PCRE8
2661    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2662    #else /* COMPILE_PCRE8 */
2663    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2664  #endif  #endif
 if (newlinecheck) readuchar = TRUE;  
2665    
2666  if (readuchar)  #else /* SLJIT_UNALIGNED */
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
2667    
2668  if (newlinecheck)  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2669    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2670    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2671    #else /* SLJIT_BIG_ENDIAN */
2672    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2673    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2674    #endif /* SLJIT_BIG_ENDIAN */
2675    
2676  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #ifdef COMPILE_PCRE8
2677  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2678  if (common->utf)  #else /* COMPILE_PCRE8 */
2679    {  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
   }  
2680  #endif  #endif
2681  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2682  if (common->utf)  
   {  
   singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
   }  
2683  #endif  #endif
 JUMPHERE(start);  
2684    
2685  if (newlinecheck)  if (chars[1] != 0 || chars[3] != 0)
2686    {    {
2687    JUMPHERE(end);    pair.asuchars[0] = chars[1];
2688    JUMPHERE(nl);    pair.asuchars[1] = chars[3];
2689      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2690    }    }
2691    
2692  return mainloop;  pair.asuchars[0] = chars[0];
2693    pair.asuchars[1] = chars[2];
2694    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2695    
2696    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2697    JUMPTO(SLJIT_JUMP, start);
2698    JUMPHERE(found);
2699    JUMPHERE(quit);
2700    
2701    if (firstline)
2702      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2703    else
2704      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    return TRUE;
2706  }  }
2707    
2708  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2709  {  {
2710  DEFINE_COMPILER;  DEFINE_COMPILER;
2711  struct sljit_label *start;  struct sljit_label *start;
2712  struct sljit_jump *leave;  struct sljit_jump *quit;
2713  struct sljit_jump *found;  struct sljit_jump *found;
2714  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2715    
2716  if (firstline)  if (firstline)
2717    {    {
2718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2719      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2720    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2721    }    }
2722    
2723  start = LABEL();  start = LABEL();
2724  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2725  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2726    
2727  oc = first_char;  oc = first_char;
# Line 2136  else Line 2754  else
2754    }    }
2755    
2756  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2757  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2758  JUMPHERE(found);  JUMPHERE(found);
2759  JUMPHERE(leave);  JUMPHERE(quit);
2760    
2761  if (firstline)  if (firstline)
2762    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2763  }  }
2764    
2765  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2169  DEFINE_COMPILER; Line 2768  DEFINE_COMPILER;
2768  struct sljit_label *loop;  struct sljit_label *loop;
2769  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2770  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2771  struct sljit_jump *leave;  struct sljit_jump *quit;
2772  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2773  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2774  jump_list *newline = NULL;  jump_list *newline = NULL;
2775    
2776  if (firstline)  if (firstline)
2777    {    {
2778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2779      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2780    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2781    }    }
2782    
# Line 2198  if (common->nltype == NLTYPE_FIXED && co Line 2798  if (common->nltype == NLTYPE_FIXED && co
2798    
2799    loop = LABEL();    loop = LABEL();
2800    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2801    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2802    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2803    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2804    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2805    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2806    
2807    JUMPHERE(leave);    JUMPHERE(quit);
2808    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2809    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2810    
# Line 2228  set_jumps(newline, loop); Line 2828  set_jumps(newline, loop);
2828    
2829  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2830    {    {
2831    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2832    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2833    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2834    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2239  if (common->nltype == NLTYPE_ANY || comm Line 2839  if (common->nltype == NLTYPE_ANY || comm
2839  #endif  #endif
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2841    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2842    JUMPHERE(leave);    JUMPHERE(quit);
2843    }    }
2844  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2845  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2846    
2847  if (firstline)  if (firstline)
2848    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2849  }  }
2850    
2851  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2852  {  {
2853  DEFINE_COMPILER;  DEFINE_COMPILER;
2854  struct sljit_label *start;  struct sljit_label *start;
2855  struct sljit_jump *leave;  struct sljit_jump *quit;
2856  struct sljit_jump *found;  struct sljit_jump *found;
2857  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2858  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2260  struct sljit_jump *jump; Line 2860  struct sljit_jump *jump;
2860    
2861  if (firstline)  if (firstline)
2862    {    {
2863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2864      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2865    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2866    }    }
2867    
2868  start = LABEL();  start = LABEL();
2869  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2870  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2871  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2872  if (common->utf)  if (common->utf)
# Line 2309  if (common->utf) Line 2910  if (common->utf)
2910  #endif  #endif
2911  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2912  JUMPHERE(found);  JUMPHERE(found);
2913  JUMPHERE(leave);  JUMPHERE(quit);
2914    
2915  if (firstline)  if (firstline)
2916    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2917  }  }
2918    
2919  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2384  DEFINE_COMPILER; Line 2985  DEFINE_COMPILER;
2985  struct sljit_jump *jump;  struct sljit_jump *jump;
2986  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2987    
2988  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2989  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2990    GET_LOCAL_BASE(TMP3, 0, 0);
2991    
2992  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2993  mainloop = LABEL();  mainloop = LABEL();
2994  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2995  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2996  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2997  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2998  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
2999  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
# Line 2437  struct sljit_jump *jump; Line 3039  struct sljit_jump *jump;
3039    
3040  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3041    
3042  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3043  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3044  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3045  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 2535  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3137  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3137  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3138  }  }
3139    
3140    /*
3141      range format:
3142    
3143      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3144      ranges[1] = first bit (0 or 1)
3145      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3146    */
3147    
3148    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3149    {
3150    DEFINE_COMPILER;
3151    struct sljit_jump *jump;
3152    
3153    if (ranges[0] < 0)
3154      return FALSE;
3155    
3156    switch(ranges[0])
3157      {
3158      case 1:
3159      if (readch)
3160        read_char(common);
3161      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3162      return TRUE;
3163    
3164      case 2:
3165      if (readch)
3166        read_char(common);
3167      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3168      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3169      return TRUE;
3170    
3171      case 4:
3172      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3173        {
3174        if (readch)
3175          read_char(common);
3176        if (ranges[1] != 0)
3177          {
3178          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          }
3181        else
3182          {
3183          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3184          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3185          JUMPHERE(jump);
3186          }
3187        return TRUE;
3188        }
3189      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3190        {
3191        if (readch)
3192          read_char(common);
3193        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3194        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3195        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3196        return TRUE;
3197        }
3198      return FALSE;
3199    
3200      default:
3201      return FALSE;
3202      }
3203    }
3204    
3205    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3206    {
3207    int i, bit, length;
3208    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3209    
3210    bit = ctypes[0] & flag;
3211    ranges[0] = -1;
3212    ranges[1] = bit != 0 ? 1 : 0;
3213    length = 0;
3214    
3215    for (i = 1; i < 256; i++)
3216      if ((ctypes[i] & flag) != bit)
3217        {
3218        if (length >= MAX_RANGE_SIZE)
3219          return;
3220        ranges[2 + length] = i;
3221        length++;
3222        bit ^= flag;
3223        }
3224    
3225    if (bit != 0)
3226      {
3227      if (length >= MAX_RANGE_SIZE)
3228        return;
3229      ranges[2 + length] = 256;
3230      length++;
3231      }
3232    ranges[0] = length;
3233    }
3234    
3235    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3236    {
3237    int ranges[2 + MAX_RANGE_SIZE];
3238    pcre_uint8 bit, cbit, all;
3239    int i, byte, length = 0;
3240    
3241    bit = bits[0] & 0x1;
3242    ranges[1] = bit;
3243    /* Can be 0 or 255. */
3244    all = -bit;
3245    
3246    for (i = 0; i < 256; )
3247      {
3248      byte = i >> 3;
3249      if ((i & 0x7) == 0 && bits[byte] == all)
3250        i += 8;
3251      else
3252        {
3253        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3254        if (cbit != bit)
3255          {
3256          if (length >= MAX_RANGE_SIZE)
3257            return FALSE;
3258          ranges[2 + length] = i;
3259          length++;
3260          bit = cbit;
3261          all = -cbit;
3262          }
3263        i++;
3264        }
3265      }
3266    
3267    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3268      {
3269      if (length >= MAX_RANGE_SIZE)
3270        return FALSE;
3271      ranges[2 + length] = 256;
3272      length++;
3273      }
3274    ranges[0] = length;
3275    
3276    return check_ranges(common, ranges, backtracks, FALSE);
3277    }
3278    
3279  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3280  {  {
3281  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3282  DEFINE_COMPILER;  DEFINE_COMPILER;
3283    
3284  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3285    
3286  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3287  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
# Line 2567  static void check_hspace(compiler_common Line 3308  static void check_hspace(compiler_common
3308  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3309  DEFINE_COMPILER;  DEFINE_COMPILER;
3310    
3311  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3312    
3313  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3314  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
# Line 2606  static void check_vspace(compiler_common Line 3347  static void check_vspace(compiler_common
3347  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3348  DEFINE_COMPILER;  DEFINE_COMPILER;
3349    
3350  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3351    
3352  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3353  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
# Line 2638  DEFINE_COMPILER; Line 3379  DEFINE_COMPILER;
3379  struct sljit_jump *jump;  struct sljit_jump *jump;
3380  struct sljit_label *label;  struct sljit_label *label;
3381    
3382  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3383  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3384  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3385  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2667  DEFINE_COMPILER; Line 3408  DEFINE_COMPILER;
3408  struct sljit_jump *jump;  struct sljit_jump *jump;
3409  struct sljit_label *label;  struct sljit_label *label;
3410    
3411  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3412  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3413    
3414  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2731  return src2; Line 3472  return src2;
3472  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3473    
3474  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
3475      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3476  {  {
3477  DEFINE_COMPILER;  DEFINE_COMPILER;
3478  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2832  do Line 3573  do
3573        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3574        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3575          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
3576        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3577        break;        break;
3578    
3579        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3580        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3581          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
3582        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
3583        break;        break;
3584    
3585  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3586        case 1:        case 1:
3587        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3588          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
3589        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
3590        break;        break;
3591  #endif  #endif
3592    
# Line 2871  do Line 3612  do
3612    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3613      {      {
3614      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3615      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
3616      }      }
3617    else    else
3618      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
3619    
3620  #endif  #endif
3621    
# Line 2910  return cc; Line 3651  return cc;
3651      } \      } \
3652    charoffset = (value);    charoffset = (value);
3653    
3654  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3655  {  {
3656  DEFINE_COMPILER;  DEFINE_COMPILER;
3657  jump_list *found = NULL;  jump_list *found = NULL;
3658  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3659  unsigned int c;  unsigned int c;
3660  int compares;  int compares;
3661  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2928  unsigned int typeoffset; Line 3669  unsigned int typeoffset;
3669  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3670  unsigned int charoffset;  unsigned int charoffset;
3671    
3672  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3673  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3674    detect_partial_match(common, backtracks);
3675  read_char(common);  read_char(common);
3676    
3677  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2942  if ((*cc++ & XCL_MAP) != 0) Line 3684  if ((*cc++ & XCL_MAP) != 0)
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685  #endif  #endif
3686    
3687    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3688    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3690    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3691    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3692    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3693        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3694        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3695        }
3696    
3697  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3698    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3080  typeoffset = 0; Line 3825  typeoffset = 0;
3825  while (*cc != XCL_END)  while (*cc != XCL_END)
3826    {    {
3827    compares--;    compares--;
3828    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3829    jump = NULL;    jump = NULL;
3830    
3831    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3162  while (*cc != XCL_END) Line 3907  while (*cc != XCL_END)
3907      switch(*cc)      switch(*cc)
3908        {        {
3909        case PT_ANY:        case PT_ANY:
3910        if (list != fallbacks)        if (list != backtracks)
3911          {          {
3912          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
3913            continue;            continue;
# Line 3235  while (*cc != XCL_END) Line 3980  while (*cc != XCL_END)
3980  #endif  #endif
3981    
3982    if (jump != NULL)    if (jump != NULL)
3983      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3984    }    }
3985    
3986  if (found != NULL)  if (found != NULL)
# Line 3247  if (found != NULL) Line 3992  if (found != NULL)
3992    
3993  #endif  #endif
3994    
3995  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3996  {  {
3997  DEFINE_COMPILER;  DEFINE_COMPILER;
3998  int length;  int length;
# Line 3266  switch(type) Line 4011  switch(type)
4011    case OP_SOD:    case OP_SOD:
4012    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4013    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4014    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4015    return cc;    return cc;
4016    
4017    case OP_SOM:    case OP_SOM:
4018    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4019    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
4020    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4021    return cc;    return cc;
4022    
4023    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4024    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4025    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4026    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4027    return cc;    return cc;
4028    
4029    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4030    case OP_DIGIT:    case OP_DIGIT:
4031    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4032    read_char8_type(common);    if (common->digits[0] == -2)
4033    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4034    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4035      /* Flip the starting bit in the negative case. */
4036      if (type == OP_NOT_DIGIT)
4037        common->digits[1] ^= 1;
4038      if (!check_ranges(common, common->digits, backtracks, TRUE))
4039        {
4040        read_char8_type(common);
4041        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4042        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4043        }
4044      if (type == OP_NOT_DIGIT)
4045        common->digits[1] ^= 1;
4046    return cc;    return cc;
4047    
4048    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4049    case OP_WHITESPACE:    case OP_WHITESPACE:
4050    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4051    read_char8_type(common);    read_char8_type(common);
4052    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
4053    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4054    return cc;    return cc;
4055    
4056    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4057    case OP_WORDCHAR:    case OP_WORDCHAR:
4058    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4059    read_char8_type(common);    read_char8_type(common);
4060    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
4061    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4062    return cc;    return cc;
4063    
4064    case OP_ANY:    case OP_ANY:
4065    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4066    read_char(common);    read_char(common);
4067    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4068      {      {
# Line 3317  switch(type) Line 4073  switch(type)
4073        jump[1] = check_str_end(common);        jump[1] = check_str_end(common);
4074    
4075      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4076      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4077      if (jump[1] != NULL)      if (jump[1] != NULL)
4078        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4079      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4080      }      }
4081    else    else
4082      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4083    return cc;    return cc;
4084    
4085    case OP_ALLANY:    case OP_ALLANY:
4086    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4087  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4088    if (common->utf)    if (common->utf)
4089      {      {
# Line 3355  switch(type) Line 4111  switch(type)
4111    return cc;    return cc;
4112    
4113    case OP_ANYBYTE:    case OP_ANYBYTE:
4114    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4115    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4116    return cc;    return cc;
4117    
# Line 3368  switch(type) Line 4124  switch(type)
4124    propdata[2] = cc[0];    propdata[2] = cc[0];
4125    propdata[3] = cc[1];    propdata[3] = cc[1];
4126    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4127    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4128    return cc + 2;    return cc + 2;
4129  #endif  #endif
4130  #endif  #endif
4131    
4132    case OP_ANYNL:    case OP_ANYNL:
4133    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4134    read_char(common);    read_char(common);
4135    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
4136    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
# Line 3387  switch(type) Line 4143  switch(type)
4143    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4144    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4145    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4146    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4147    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4148    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4149    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3395  switch(type) Line 4151  switch(type)
4151    
4152    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4153    case OP_HSPACE:    case OP_HSPACE:
4154    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4155    read_char(common);    read_char(common);
4156    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4157    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4158    return cc;    return cc;
4159    
4160    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4161    case OP_VSPACE:    case OP_VSPACE:
4162    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4163    read_char(common);    read_char(common);
4164    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4165    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4166    return cc;    return cc;
4167    
4168  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4169    case OP_EXTUNI:    case OP_EXTUNI:
4170    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4171    read_char(common);    read_char(common);
4172    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4173    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
4174    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
4175    
4176    label = LABEL();    label = LABEL();
4177    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 3445  switch(type) Line 4201  switch(type)
4201      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4202      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4203      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4204        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
4205      else      else
4206        {        {
4207        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
# Line 3453  switch(type) Line 4209  switch(type)
4209        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4210        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4211        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
4212        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4213        check_partial(common, TRUE);        check_partial(common, TRUE);
4214        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4215        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4216        }        }
4217      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4218      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4219      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4220      }      }
4221    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4222      {      {
4223      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4224      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4225      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
4226      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
4227      }      }
4228    else    else
4229      {      {
# Line 3476  switch(type) Line 4232  switch(type)
4232      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4233      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4234      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4235      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4236      /* Equal. */      /* Equal. */
4237      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4238      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4239      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4240    
4241      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4242      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4243        {        {
4244        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4245        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
4246        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
4247        }        }
4248      else      else
4249        {        {
4250        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4251        read_char(common);        read_char(common);
4252        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
4253        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4254        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4255        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4256        }        }
4257      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
# Line 3506  switch(type) Line 4262  switch(type)
4262    return cc;    return cc;
4263    
4264    case OP_EOD:    case OP_EOD:
4265    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4266    check_partial(common, FALSE);    check_partial(common, FALSE);
4267    return cc;    return cc;
4268    
4269    case OP_CIRC:    case OP_CIRC:
4270    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4271    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
4272    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
4273    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
4274    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4275    return cc;    return cc;
4276    
4277    case OP_CIRCM:    case OP_CIRCM:
# Line 3523  switch(type) Line 4279  switch(type)
4279    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
4280    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4281    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
4282    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4283    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4284    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4285    
4286    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4287    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4288      {      {
4289      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4290      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4291      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4292      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4293      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4294      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4295      }      }
4296    else    else
4297      {      {
4298      skip_char_back(common);      skip_char_back(common);
4299      read_char(common);      read_char(common);
4300      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4301      }      }
4302    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4303    return cc;    return cc;
# Line 3549  switch(type) Line 4305  switch(type)
4305    case OP_DOLL:    case OP_DOLL:
4306    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4307    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
4308    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4309    
4310    if (!common->endonly)    if (!common->endonly)
4311      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4312    else    else
4313      {      {
4314      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4315      check_partial(common, FALSE);      check_partial(common, FALSE);
4316      }      }
4317    return cc;    return cc;
# Line 3564  switch(type) Line 4320  switch(type)
4320    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4321    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4322    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
4323    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4324    check_partial(common, FALSE);    check_partial(common, FALSE);
4325    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4326    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3574  switch(type) Line 4330  switch(type)
4330      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4331      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4332      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4333        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
4334      else      else
4335        {        {
4336        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4337        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
4338        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4339        check_partial(common, TRUE);        check_partial(common, TRUE);
4340        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4341        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4342        }        }
4343    
4344      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4345      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4346      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4347      }      }
4348    else    else
4349      {      {
4350      peek_char(common);      peek_char(common);
4351      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4352      }      }
4353    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4354    return cc;    return cc;
# Line 3606  switch(type) Line 4362  switch(type)
4362    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
4363      {      {
4364      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
4365      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
4366    
4367      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4368      context.sourcereg = -1;      context.sourcereg = -1;
4369  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4370      context.ucharptr = 0;      context.ucharptr = 0;
4371  #endif  #endif
4372      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4373      }      }
4374    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4375    read_char(common);    read_char(common);
4376  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4377    if (common->utf)    if (common->utf)
# Line 3627  switch(type) Line 4383  switch(type)
4383      c = *cc;      c = *cc;
4384    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4385      {      {
4386      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
4387      return cc + length;      return cc + length;
4388      }      }
4389    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 3635  switch(type) Line 4391  switch(type)
4391    if (ispowerof2(bit))    if (ispowerof2(bit))
4392      {      {
4393      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4394      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4395      return cc + length;      return cc + length;
4396      }      }
4397    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4398    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4399    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4400    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4401    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4402    return cc + length;    return cc + length;
4403    
4404    case OP_NOT:    case OP_NOT:
4405    case OP_NOTI:    case OP_NOTI:
4406    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4407    length = 1;    length = 1;
4408  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4409    if (common->utf)    if (common->utf)
# Line 3658  switch(type) Line 4414  switch(type)
4414        {        {
4415        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4416        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4417          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4418        else        else
4419          {          {
4420          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
4421          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4422          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
4423          }          }
4424        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4425        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
# Line 3688  switch(type) Line 4444  switch(type)
4444      }      }
4445    
4446    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4447      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4448    else    else
4449      {      {
4450      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3696  switch(type) Line 4452  switch(type)
4452      if (ispowerof2(bit))      if (ispowerof2(bit))
4453        {        {
4454        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4455        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4456        }        }
4457      else      else
4458        {        {
4459        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4460        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
4461        }        }
4462      }      }
4463    return cc + length;    return cc + length;
4464    
4465    case OP_CLASS:    case OP_CLASS:
4466    case OP_NCLASS:    case OP_NCLASS:
4467    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4468    read_char(common);    read_char(common);
4469      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4470        return cc + 32 / sizeof(pcre_uchar);
4471    
4472  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4473    jump[0] = NULL;    jump[0] = NULL;
4474  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3721  switch(type) Line 4480  switch(type)
4480      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4481      if (type == OP_CLASS)      if (type == OP_CLASS)
4482        {        {
4483        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4484        jump[0] = NULL;        jump[0] = NULL;
4485        }        }
4486      }      }
# Line 3731  switch(type) Line 4490  switch(type)
4490    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4491    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4492    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4493    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4494  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4495    if (jump[0] != NULL)    if (jump[0] != NULL)
4496      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3740  switch(type) Line 4499  switch(type)
4499    
4500  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4501    case OP_XCLASS:    case OP_XCLASS:
4502    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4503    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4504  #endif  #endif
4505    
4506    case OP_REVERSE:    case OP_REVERSE:
4507    length = GET(cc, 0);    length = GET(cc, 0);
4508    SLJIT_ASSERT(length > 0);    if (length == 0)
4509        return cc + LINK_SIZE;
4510    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4511  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4512    if (common->utf)    if (common->utf)
# Line 3754  switch(type) Line 4514  switch(type)
4514      OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4515      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4516      label = LABEL();      label = LABEL();
4517      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
4518      skip_char_back(common);      skip_char_back(common);
4519      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
4520      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3764  switch(type) Line 4524  switch(type)
4524      {      {
4525      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4526      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
4527      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
4528      }      }
4529    check_start_used_ptr(common);    check_start_used_ptr(common);
4530    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3773  SLJIT_ASSERT_STOP(); Line 4533  SLJIT_ASSERT_STOP();
4533  return cc;  return cc;
4534  }  }
4535    
4536  static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4537  {  {
4538  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4539  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3825  if (context.length > 0) Line 4585  if (context.length > 0)
4585    {    {
4586    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4587    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
4588    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
4589    
4590    context.sourcereg = -1;    context.sourcereg = -1;
4591  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4592    context.ucharptr = 0;    context.ucharptr = 0;
4593  #endif  #endif
4594    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
4595    return cc;    return cc;
4596    }    }
4597    
4598  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4599  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4600  }  }
4601    
4602  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
4603  {  {
4604  DEFINE_COMPILER;  DEFINE_COMPILER;
4605  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3847  int offset = GET2(cc, 1) << 1; Line 4607  int offset = GET2(cc, 1) << 1;
4607  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4608  if (!common->jscript_compat)  if (!common->jscript_compat)
4609    {    {
4610    if (fallbacks == NULL)    if (backtracks == NULL)
4611      {      {
4612      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4613      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
# Line 3856  if (!common->jscript_compat) Line 4616  if (!common->jscript_compat)
4616      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4617      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4618      }      }
4619    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4620    }    }
4621  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4622  }  }
4623    
4624  /* Forward definitions. */  /* Forward definitions. */
4625  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4626  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4627    
4628  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4629    do \    do \
4630      { \      { \
4631      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4632      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4633        return error; \        return error; \
4634      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4635      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4636      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4637      parent->top = fallback; \      parent->top = backtrack; \
4638      } \      } \
4639    while (0)    while (0)
4640    
4641  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4642    do \    do \
4643      { \      { \
4644      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4645      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4646        return; \        return; \
4647      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4648      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4649      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4650      parent->top = fallback; \      parent->top = backtrack; \
4651      } \      } \
4652    while (0)    while (0)
4653    
4654  #define FALLBACK_AS(type) ((type *)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4655    
4656  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4657  {  {
4658  DEFINE_COMPILER;  DEFINE_COMPILER;
4659  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3904  struct sljit_jump *nopartial; Line 4664  struct sljit_jump *nopartial;
4664  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4665  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
4666  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4667    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4668    
4669  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4670  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3921  if (common->utf && *cc == OP_REFI) Line 4681  if (common->utf && *cc == OP_REFI)
4681    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
4682    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4683    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4684      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
4685    else    else
4686      {      {
4687      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
4688      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
4689      check_partial(common, FALSE);      check_partial(common, FALSE);
4690      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4691      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4692      }      }
4693    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3942  else Line 4702  else
4702    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4703    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4704    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4705      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
4706    
4707    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
4708    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4709    
4710    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
4711      {      {
# Line 3957  else Line 4717  else
4717      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4718      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4719      add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
4720      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4721      JUMPHERE(partial);      JUMPHERE(partial);
4722      check_partial(common, FALSE);      check_partial(common, FALSE);
4723      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4724      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4725      }      }
4726    }    }
# Line 3968  else Line 4728  else
4728  if (jump != NULL)  if (jump != NULL)
4729    {    {
4730    if (emptyfail)    if (emptyfail)
4731      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4732    else    else
4733      JUMPHERE(jump);      JUMPHERE(jump);
4734    }    }
4735  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4736  }  }
4737    
4738  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4739  {  {
4740  DEFINE_COMPILER;  DEFINE_COMPILER;
4741  fallback_common *fallback;  backtrack_common *backtrack;
4742  pcre_uchar type;  pcre_uchar type;
4743  struct sljit_label *label;  struct sljit_label *label;
4744  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3987  pcre_uchar *ccbegin = cc; Line 4747  pcre_uchar *ccbegin = cc;
4747  int min = 0, max = 0;  int min = 0, max = 0;
4748  BOOL minimize;  BOOL minimize;
4749    
4750  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4751    
4752  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4753  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 4039  if (!minimize) Line 4799  if (!minimize)
4799      {      {
4800      allocate_stack(common, 1);      allocate_stack(common, 1);
4801      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4802      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4803      }      }
4804    
4805    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4806      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4807    
4808    label = LABEL();    label = LABEL();
4809    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4810    
4811    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4812      {      {
# Line 4074  if (!minimize) Line 4834  if (!minimize)
4834      }      }
4835    
4836    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4837    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4838    
4839    decrease_call_count(common);    decrease_call_count(common);
4840    return cc;    return cc;
# Line 4092  if (min == 0) Line 4852  if (min == 0)
4852    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4853    }    }
4854  else  else
4855    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4856    
4857  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4858  if (max > 0)  if (max > 0)
4859    add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4860    
4861  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4862  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4863    
4864  if (min > 1)  if (min > 1)
# Line 4106  if (min > 1) Line 4866  if (min > 1)
4866    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4867    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4868    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4869    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4870    }    }
4871  else if (max > 0)  else if (max > 0)
4872    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 4119  decrease_call_count(common); Line 4879  decrease_call_count(common);
4879  return cc;  return cc;
4880  }  }
4881    
4882  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4883  {  {
4884  DEFINE_COMPILER;  DEFINE_COMPILER;
4885  fallback_common *fallback;  backtrack_common *backtrack;
4886  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4887  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4888  int start = GET(cc, 1);  int start = GET(cc, 1);
4889    
4890  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4891  while (entry != NULL)  while (entry != NULL)
4892    {    {
4893    if (entry->start == start)    if (entry->start == start)
# Line 4172  if (entry->entry == NULL) Line 4932  if (entry->entry == NULL)
4932  else  else
4933    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4934  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4935  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
4936  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4937  }  }
4938    
4939  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4940  {  {
4941  DEFINE_COMPILER;  DEFINE_COMPILER;
4942  int framesize;  int framesize;
4943  int localptr;  int localptr;
4944  fallback_common altfallback;  backtrack_common altbacktrack;
4945  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4946  pcre_uchar opcode;  pcre_uchar opcode;
4947  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4948  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4949  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4950  jump_list **found;  jump_list **found;
4951  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4952  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4953  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4954  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4955  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4956  struct sljit_jump *jump;  struct sljit_jump *jump;
4957  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4965  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4965  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
4966  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4967  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4968  fallback->framesize = framesize;  backtrack->framesize = framesize;
4969  fallback->localptr = localptr;  backtrack->localptr = localptr;
4970  opcode = *cc;  opcode = *cc;
4971  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4972  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4215  cc += GET(cc, 1); Line 4975  cc += GET(cc, 1);
4975    
4976  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4977    {    {
4978    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
4979    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4980    free_stack(common, 1);    free_stack(common, 1);
4981    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 4238  else Line 4998  else
4998    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
4999    }    }
5000    
5001  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5002  common->leavelabel = NULL;  common->quitlabel = NULL;
5003  common->leave = NULL;  common->quit = NULL;
5004  while (1)  while (1)
5005    {    {
5006    common->acceptlabel = NULL;    common->acceptlabel = NULL;
5007    common->accept = NULL;    common->accept = NULL;
5008    altfallback.top = NULL;    altbacktrack.top = NULL;
5009    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5010    
5011    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5012      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5013    
5014    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5015    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5016    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5017      {      {
5018      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5019      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5020      common->leave = save_leave;      common->quit = save_quit;
5021      common->accept = save_accept;      common->accept = save_accept;
5022      return NULL;      return NULL;
5023      }      }
# Line 4307  while (1) Line 5067  while (1)
5067      }      }
5068    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5069    
5070    compile_fallbackpath(common, altfallback.top);    compile_backtrackingpath(common, altbacktrack.top);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5074      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5075      common->leave = save_leave;      common->quit = save_quit;
5076      common->accept = save_accept;      common->accept = save_accept;
5077      return NULL;      return NULL;
5078      }      }
5079    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5080    
5081    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5082      break;      break;
# Line 4325  while (1) Line 5085  while (1)
5085    cc += GET(cc, 1);    cc += GET(cc, 1);
5086    }    }
5087  /* None of them matched. */  /* None of them matched. */
5088  if (common->leave != NULL)  if (common->quit != NULL)
5089    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5090    
5091  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5092    {    {
# Line 4393  if (opcode == OP_ASSERT || opcode == OP_ Line 5153  if (opcode == OP_ASSERT || opcode == OP_
5153    
5154    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5155      {      {
5156      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5157      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->matchingpath);
5158      }      }
5159    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5160      {      {
5161      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5162      JUMPHERE(brajump);      JUMPHERE(brajump);
5163      if (framesize >= 0)      if (framesize >= 0)
5164        {        {
# Line 4406  if (opcode == OP_ASSERT || opcode == OP_ Line 5166  if (opcode == OP_ASSERT || opcode == OP_
5166        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5167        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5168        }        }
5169      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5170      }      }
5171    }    }
5172  else  else
# Line 4436  else Line 5196  else
5196      }      }
5197    
5198    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5199      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5200    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5201      {      {
5202      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5203      JUMPHERE(brajump);      JUMPHERE(brajump);
5204      }      }
5205    
5206    if (bra != OP_BRA)    if (bra != OP_BRA)
5207      {      {
5208      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5209      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5210      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5211      }      }
5212    }    }
5213    
5214  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5215  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5216  common->leave = save_leave;  common->quit = save_quit;
5217  common->accept = save_accept;  common->accept = save_accept;
5218  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5219  }  }
# Line 4622  return condition; Line 5382  return condition;
5382                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5383  */  */
5384    
5385  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5386  {  {
5387  DEFINE_COMPILER;  DEFINE_COMPILER;
5388  fallback_common *fallback;  backtrack_common *backtrack;
5389  pcre_uchar opcode;  pcre_uchar opcode;
5390  int localptr = 0;  int localptr = 0;
5391  int offset = 0;  int offset = 0;
5392  int stacksize;  int stacksize;
5393  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5394  pcre_uchar *hotpath;  pcre_uchar *matchingpath;
5395  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5396  pcre_uchar ket;  pcre_uchar ket;
5397  assert_fallback *assert;  assert_backtrack *assert;
5398  BOOL has_alternatives;  BOOL has_alternatives;
5399  struct sljit_jump *jump;  struct sljit_jump *jump;
5400  struct sljit_jump *skip;  struct sljit_jump *skip;
5401  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
5402  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
5403    
5404  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5405    
5406  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5407    {    {
# Line 4652  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5412    
5413  opcode = *cc;  opcode = *cc;
5414  ccbegin = cc;  ccbegin = cc;
5415  hotpath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5416    
5417  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5418    {    {
5419    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
5420    parent->top = fallback->prev;    parent->top = backtrack->prev;
5421    return bracketend(cc);    return bracketend(cc);
5422    }    }
5423    
# Line 4669  cc += GET(cc, 1); Line 5429  cc += GET(cc, 1);
5429  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5430  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5431    {    {
5432    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5433    if (*hotpath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5434      {      {
5435      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5436      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5437        has_alternatives = FALSE;        has_alternatives = FALSE;
5438      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4693  if (opcode == OP_CBRA || opcode == OP_SC Line 5453  if (opcode == OP_CBRA || opcode == OP_SC
5453    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5454    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
5455    offset <<= 1;    offset <<= 1;
5456    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5457    hotpath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5458    }    }
5459  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5460    {    {
5461    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5462    localptr = PRIV_DATA(ccbegin);    localptr = PRIV_DATA(ccbegin);
5463    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
5464    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5465    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5466      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5467    }    }
5468    
5469  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4728  if (bra == OP_BRAZERO) Line 5488  if (bra == OP_BRAZERO)
5488    
5489  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5490    {    {
5491    /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */    /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
5492    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5493    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
5494      {      {
# Line 4745  if (bra == OP_BRAMINZERO) Line 5505  if (bra == OP_BRAMINZERO)
5505        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
5506        JUMPHERE(jump);        JUMPHERE(jump);
5507        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5508        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5509          {          {
5510          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, localptr contains the previous STR_PTR. */
5511          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4754  if (bra == OP_BRAMINZERO) Line 5514  if (bra == OP_BRAMINZERO)
5514          {          {
5515          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5516          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5517          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5518          }          }
5519        JUMPHERE(skip);        JUMPHERE(skip);
5520        }        }
# Line 4768  if (bra == OP_BRAMINZERO) Line 5528  if (bra == OP_BRAMINZERO)
5528    }    }
5529    
5530  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5531    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5532    
5533  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5534    {    {
5535    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5536    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5537      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5538    }    }
5539    
5540  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
5541  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5542    {    {
5543    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5544      {      {
5545      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5546      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
# Line 4804  if (opcode == OP_ONCE) Line 5564  if (opcode == OP_ONCE)
5564      {      {
5565      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5566        {        {
5567        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5568        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5569        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5570        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5571        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5572        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5573        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5574        }        }
5575      else      else
5576        {        {
5577        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5578        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5579        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5580        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5581        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5582        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5583        }        }
5584      }      }
5585    }    }
# Line 4853  else if (has_alternatives) Line 5613  else if (has_alternatives)
5613  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5614  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5615    {    {
5616    if (*hotpath == OP_CREF)    if (*matchingpath == OP_CREF)
5617      {      {
5618      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5619      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5620        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5621      hotpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5622      }      }
5623    else if (*hotpath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5624      {      {
5625      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5626      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5627      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5628    
5629      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5630      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5631      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
5632      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
5633      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5634      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5635      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
5636      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5637      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5638    
5639      JUMPHERE(jump);      JUMPHERE(jump);
5640      hotpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5641      }      }
5642    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5643      {      {
5644      /* Never has other case. */      /* Never has other case. */
5645      FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5646    
5647      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5648      if (common->currententry == NULL)      if (common->currententry == NULL)
5649        stacksize = 0;        stacksize = 0;
5650      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4894  if (opcode == OP_COND || opcode == OP_SC Line 5654  if (opcode == OP_COND || opcode == OP_SC
5654      else      else
5655        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5656    
5657      if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5658        {        {
5659        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5660        if (stacksize != 0)        if (stacksize != 0)
5661          hotpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5662        else        else
5663          {          {
5664          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5665            {            {
5666            hotpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5667            cc += GET(cc, 1);            cc += GET(cc, 1);
5668            }            }
5669          else          else
5670            hotpath = cc;            matchingpath = cc;
5671          }          }
5672        }        }
5673      else      else
5674        {        {
5675        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5676    
5677        stacksize = GET2(hotpath, 1);        stacksize = GET2(matchingpath, 1);
5678        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
5681        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
5682        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
5683        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5684        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5685        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5686        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5687        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5688        hotpath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5689        }        }
5690      }      }
5691    else    else
5692      {      {
5693      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5694      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5695      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5696      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5697        return NULL;        return NULL;
5698      memset(assert, 0, sizeof(assert_fallback));      memset(assert, 0, sizeof(assert_backtrack));
5699      assert->common.cc = hotpath;      assert->common.cc = matchingpath;
5700      FALLBACK_AS(bracket_fallback)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5701      hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5702      }      }
5703    }    }
5704    
5705  compile_hotpath(common, hotpath, cc, fallback);  compile_matchingpath(common, matchingpath, cc, backtrack);
5706  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5707    return NULL;    return NULL;
5708    
5709  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5710    {    {
5711    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5712      {      {
5713      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5714      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 4963  if (opcode == OP_ONCE) Line 5723  if (opcode == OP_ONCE)
5723    else    else
5724      {      {
5725      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5726      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5727      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5728        {        {
5729        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 4998  if (has_alternatives) Line 5758  if (has_alternatives)
5758    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5760    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5761      FALLBACK_AS(bracket_fallback)->althotpath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5762    }    }
5763    
5764  /* Must be after the hotpath label. */  /* Must be after the matchingpath label. */
5765  if (offset != 0)  if (offset != 0)
5766    {    {
5767    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 5014  if (ket == OP_KETRMAX) Line 5774  if (ket == OP_KETRMAX)
5774    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5775      {      {
5776      if (has_alternatives)      if (has_alternatives)
5777        FALLBACK_AS(bracket_fallback)->althotpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5778      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5779      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5780          {
5781        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
5782          /* Drop STR_PTR for greedy plus quantifier. */
5783          if (bra != OP_BRAZERO)
5784            free_stack(common, 1);
5785          }
5786      else      else
5787        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5788        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5789      }      }
5790    else    else
5791      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5792    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5793    }    }
5794    
5795  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5796    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5797    
5798  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5799    {    {
5800    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5801    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5802    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5803      {      {
5804      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5805      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5806      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5807      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5808      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5809        {        {
5810        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5811        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5048  if (bra == OP_BRAMINZERO) Line 5813  if (bra == OP_BRAMINZERO)
5813      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5814        free_stack(common, 1);        free_stack(common, 1);
5815      }      }
5816    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5817    }    }
5818    
5819  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
# Line 5061  cc += 1 + LINK_SIZE; Line 5826  cc += 1 + LINK_SIZE;
5826  return cc;  return cc;
5827  }  }
5828    
5829  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5830  {  {
5831  DEFINE_COMPILER;  DEFINE_COMPILER;
5832  fallback_common *fallback;  backtrack_common *backtrack;
5833  pcre_uchar opcode;  pcre_uchar opcode;
5834  int localptr;  int localptr;
5835  int cbraprivptr = 0;  int cbraprivptr = 0;
# Line 5077  int stack; Line 5842  int stack;
5842  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5843  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5844    
5845  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5846  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5847    {    {
5848    zero = TRUE;    zero = TRUE;
# Line 5087  if (*cc == OP_BRAPOSZERO) Line 5852  if (*cc == OP_BRAPOSZERO)
5852  opcode = *cc;  opcode = *cc;
5853  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
5854  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
5855  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
5856  switch(opcode)  switch(opcode)
5857    {    {
5858    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5109  switch(opcode) Line 5874  switch(opcode)
5874    }    }
5875    
5876  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5877  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5878  if (framesize < 0)  if (framesize < 0)
5879    {    {
5880    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5881    if (!zero)    if (!zero)
5882      stacksize++;      stacksize++;
5883    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5884    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5885    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
5886    
# Line 5139  else Line 5904  else
5904      stacksize++;      stacksize++;
5905    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5906      stacksize++;      stacksize++;
5907    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5908    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5909    
5910    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 5166  if (opcode == OP_CBRAPOS || opcode == OP Line 5931  if (opcode == OP_CBRAPOS || opcode == OP
5931  loop = LABEL();  loop = LABEL();
5932  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
5933    {    {
5934    fallback->top = NULL;    backtrack->top = NULL;
5935    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
5936    cc += GET(cc, 1);    cc += GET(cc, 1);
5937    
5938    compile_hotpath(common, ccbegin, cc, fallback);    compile_matchingpath(common, ccbegin, cc, backtrack);
5939    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5940      return NULL;      return NULL;
5941    
# Line 5231  while (*cc != OP_KETRPOS) Line 5996  while (*cc != OP_KETRPOS)
5996    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5997    flush_stubs(common);    flush_stubs(common);
5998    
5999    compile_fallbackpath(common, fallback->top);    compile_backtrackingpath(common, backtrack->top);
6000    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6001      return NULL;      return NULL;
6002    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
6003    
6004    if (framesize < 0)    if (framesize < 0)
6005      {      {
# Line 5264  while (*cc != OP_KETRPOS) Line 6029  while (*cc != OP_KETRPOS)
6029    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6030    }    }
6031    
6032  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
6033  if (!zero)  if (!zero)
6034    {    {
6035    if (framesize < 0)    if (framesize < 0)
6036      add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
6037    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [localptr] above. */
6038      add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
6039    }    }
6040    
6041  /* None of them matched. */  /* None of them matched. */
# Line 5371  if (end != NULL) Line 6136  if (end != NULL)
6136  return cc;  return cc;
6137  }  }
6138    
6139  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6140  {  {
6141  DEFINE_COMPILER;  DEFINE_COMPILER;
6142  fallback_common *fallback;  backtrack_common *backtrack;
6143  pcre_uchar opcode;  pcre_uchar opcode;
6144  pcre_uchar type;  pcre_uchar type;
6145  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 5382  pcre_uchar* end; Line 6147  pcre_uchar* end;
6147  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6148  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6149  struct sljit_label *label;  struct sljit_label *label;
6150    int localptr = PRIV_DATA(cc);
6151    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6152    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6153    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6154    int tmp_base, tmp_offset;
6155    
6156  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6157    
6158  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6159    
6160    switch (type)
6161      {
6162      case OP_NOT_DIGIT:
6163      case OP_DIGIT:
6164      case OP_NOT_WHITESPACE:
6165      case OP_WHITESPACE:
6166      case OP_NOT_WORDCHAR:
6167      case OP_WORDCHAR:
6168      case OP_ANY:
6169      case OP_ALLANY:
6170      case OP_ANYBYTE:
6171      case OP_ANYNL:
6172      case OP_NOT_HSPACE:
6173      case OP_HSPACE:
6174      case OP_NOT_VSPACE:
6175      case OP_VSPACE:
6176      case OP_CHAR:
6177      case OP_CHARI:
6178      case OP_NOT:
6179      case OP_NOTI:
6180      case OP_CLASS:
6181      case OP_NCLASS:
6182      tmp_base = TMP3;
6183      tmp_offset = 0;
6184      break;
6185    
6186      default:
6187      SLJIT_ASSERT_STOP();
6188      /* Fall through. */
6189    
6190      case OP_EXTUNI:
6191      case OP_XCLASS:
6192      case OP_NOTPROP:
6193      case OP_PROP:
6194      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6195      tmp_offset = POSSESSIVE0;
6196      break;
6197      }
6198    
6199  switch(opcode)  switch(opcode)
6200    {    {
6201    case OP_STAR:    case OP_STAR:
# Line 5395  switch(opcode) Line 6204  switch(opcode)
6204    case OP_CRRANGE:    case OP_CRRANGE:
6205    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6206      {      {
6207        SLJIT_ASSERT(localptr == 0);
6208      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6209        {        {
6210        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5406  switch(opcode) Line 6216  switch(opcode)
6216        allocate_stack(common, 1);        allocate_stack(common, 1);
6217        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6218        }        }
6219    
6220      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6221        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6222    
6223      label = LABEL();      label = LABEL();
6224      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6225      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6226        {        {
6227        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5422  switch(opcode) Line 6233  switch(opcode)
6233        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6234        }        }
6235    
6236        /* We cannot use TMP3 because of this allocate_stack. */
6237      allocate_stack(common, 1);      allocate_stack(common, 1);
6238      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6239      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5430  switch(opcode) Line 6242  switch(opcode)
6242      }      }
6243    else    else
6244      {      {
6245      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6246      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6247      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (localptr == 0)
6248          allocate_stack(common, 2);
6249        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6250        if (opcode <= OP_PLUS)
6251          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6252        else
6253          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6254      label = LABEL();      label = LABEL();
6255      compile_char1_hotpath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6256      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6257      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6258          JUMPTO(SLJIT_JUMP, label);
6259        else if (opcode == OP_CRRANGE && arg1 == 0)
6260        {        {
6261        OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6262        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6263        }        }
6264      else      else
6265        {        {
6266        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6267        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6268        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6269        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6270        }        }
6271      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6272      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6273        add_jump(compiler, &fallback->topfallbacks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6274          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6275      }      }
6276    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6277    break;    break;
6278    
6279    case OP_MINSTAR:    case OP_MINSTAR:
6280    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6281    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6282      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6283    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    if (localptr == 0)
6284        allocate_stack(common, 1);
6285      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6286      BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6287    break;    break;
6288    
6289    case OP_MINUPTO:    case OP_MINUPTO:
6290    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6291    allocate_stack(common, 2);    if (localptr == 0)
6292    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6293    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6294      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6295    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6296      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6297    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6298    break;    break;
6299    
6300    case OP_QUERY:    case OP_QUERY:
6301    case OP_MINQUERY:    case OP_MINQUERY:
6302    allocate_stack(common, 1);    if (localptr == 0)
6303    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6304      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6305    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6306      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6307    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6308    break;    break;
6309    
6310    case OP_EXACT:    case OP_EXACT:
6311    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6312    label = LABEL();    label = LABEL();
6313    compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6314    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6315    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6316    break;    break;
6317    
6318    case OP_POSSTAR:    case OP_POSSTAR:
6319    case OP_POSPLUS:    case OP_POSPLUS:
6320    case OP_POSUPTO:    case OP_POSUPTO:
6321    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6322      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6323    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6324        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6325      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6326    label = LABEL();    label = LABEL();
6327    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6328    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6329    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6330      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6331    else    else
6332      {      {
6333      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6334      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6335      }      }
6336    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6337    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6338    break;    break;
6339    
6340    case OP_POSQUERY:    case OP_POSQUERY:
6341    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6342    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6343    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6344    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6345    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6346    break;    break;
6347    
6348    default:    default:
# Line 5540  decrease_call_count(common); Line 6354  decrease_call_count(common);
6354  return end;  return end;
6355  }  }
6356    
6357  static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6358  {  {
6359  DEFINE_COMPILER;  DEFINE_COMPILER;
6360  fallback_common *fallback;  backtrack_common *backtrack;
6361    
6362  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6363    
6364  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
6365    {    {
6366    add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6367    return cc + 1;    return cc + 1;
6368    }    }
6369    
# Line 5569  else Line 6383  else
6383    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
6384  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6385  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
6386  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
6387  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
6388  if (common->acceptlabel == NULL)  if (common->acceptlabel == NULL)
6389    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
# Line 5580  if (common->acceptlabel == NULL) Line 6394  if (common->acceptlabel == NULL)
6394    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
6395  else  else
6396    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
6397  add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6398  return cc + 1;  return cc + 1;
6399  }  }
6400    
6401  static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
6402  {  {
6403  DEFINE_COMPILER;  DEFINE_COMPILER;
6404  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 5600  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 6414  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
6414  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6415  }  }
6416    
6417  static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6418  {  {
6419  DEFINE_COMPILER;  DEFINE_COMPILER;
6420  fallback_common *fallback;  backtrack_common *backtrack;
6421    
6422  while (cc < ccend)  while (cc < ccend)
6423    {    {
# Line 5639  while (cc < ccend) Line 6453  while (cc < ccend)
6453      case OP_NOT:      case OP_NOT:
6454      case OP_NOTI:      case OP_NOTI:
6455      case OP_REVERSE:      case OP_REVERSE:
6456      cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6457      break;      break;
6458    
6459      case OP_SET_SOM:      case OP_SET_SOM:
6460      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
6461      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6462      allocate_stack(common, 1);      allocate_stack(common, 1);
6463      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
# Line 5654  while (cc < ccend) Line 6468  while (cc < ccend)
6468      case OP_CHAR:      case OP_CHAR:
6469      case OP_CHARI:      case OP_CHARI:
6470      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6471        cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_charn_matchingpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6472      else      else
6473        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6474      break;      break;
6475    
6476      case OP_STAR:      case OP_STAR:
# Line 5724  while (cc < ccend) Line 6538  while (cc < ccend)
6538      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6539      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6540      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6541      cc = compile_iterator_hotpath(common, cc, parent);      cc = compile_iterator_matchingpath(common, cc, parent);
6542      break;      break;
6543    
6544      case OP_CLASS:      case OP_CLASS:
6545      case OP_NCLASS:      case OP_NCLASS:
6546      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
6547        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6548      else      else
6549        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6550      break;      break;
6551    
6552  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6553      case OP_XCLASS:      case OP_XCLASS:
6554      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
6555        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
6556      else      else
6557        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6558      break;      break;
6559  #endif  #endif
6560    
6561      case OP_REF:      case OP_REF:
6562      case OP_REFI:      case OP_REFI:
6563      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
6564        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
6565      else      else
6566        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
6567      break;      break;
6568    
6569      case OP_RECURSE:      case OP_RECURSE:
6570      cc = compile_recurse_hotpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
6571      break;      break;
6572    
6573      case OP_ASSERT:      case OP_ASSERT:
6574      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
6575      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6576      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6577      PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6578      cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);      cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6579      break;      break;
6580    
6581      case OP_BRAMINZERO:      case OP_BRAMINZERO:
6582      PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
6583      cc = bracketend(cc + 1);      cc = bracketend(cc + 1);
6584      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
6585        {        {
# Line 5778  while (cc < ccend) Line 6592  while (cc < ccend)
6592        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6593        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6594        }        }
6595      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
6596      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6597        decrease_call_count(common);        decrease_call_count(common);
6598      break;      break;
# Line 5791  while (cc < ccend) Line 6605  while (cc < ccend)
6605      case OP_SBRA:      case OP_SBRA:
6606      case OP_SCBRA:      case OP_SCBRA:
6607      case OP_SCOND:      case OP_SCOND:
6608      cc = compile_bracket_hotpath(common, cc, parent);      cc = compile_bracket_matchingpath(common, cc, parent);
6609      break;      break;
6610    
6611      case OP_BRAZERO:      case OP_BRAZERO:
6612      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6613        cc = compile_bracket_hotpath(common, cc, parent);        cc = compile_bracket_matchingpath(common, cc, parent);
6614      else      else
6615        {        {
6616        PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6617        cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);        cc = compile_assert_matchingpath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6618        }        }
6619      break;      break;
6620    
# Line 5809  while (cc < ccend) Line 6623  while (cc < ccend)
6623      case OP_SBRAPOS:      case OP_SBRAPOS:
6624      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6625      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6626      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_matchingpath(common, cc, parent);
6627      break;      break;
6628    
6629      case OP_MARK:      case OP_MARK:
6630      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
6631      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
6632      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
6633      allocate_stack(common, 1);      allocate_stack(common, 1);
# Line 5826  while (cc < ccend) Line 6640  while (cc < ccend)
6640      break;      break;
6641    
6642      case OP_COMMIT:      case OP_COMMIT:
6643      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
6644      cc += 1;      cc += 1;
6645      break;      break;
6646    
6647      case OP_FAIL:      case OP_FAIL:
6648      case OP_ACCEPT:      case OP_ACCEPT:
6649      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6650      cc = compile_fail_accept_hotpath(common, cc, parent);      cc = compile_fail_accept_matchingpath(common, cc, parent);
6651      break;      break;
6652    
6653      case OP_CLOSE:      case OP_CLOSE:
6654      cc = compile_close_hotpath(common, cc);      cc = compile_close_matchingpath(common, cc);
6655      break;      break;
6656    
6657      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 5854  while (cc < ccend) Line 6668  while (cc < ccend)
6668  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
6669  }  }
6670    
6671  #undef PUSH_FALLBACK  #undef PUSH_BACKTRACK
6672  #undef PUSH_FALLBACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6673  #undef FALLBACK_AS  #undef BACKTRACK_AS
6674    
6675  #define COMPILE_FALLBACKPATH(current) \  #define COMPILE_BACKTRACKINGPATH(current) \
6676    do \    do \
6677      { \      { \
6678      compile_fallbackpath(common, (current)); \      compile_backtrackingpath(common, (current)); \
6679      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6680        return; \        return; \
6681      } \      } \
# Line 5869  SLJIT_ASSERT(cc == ccend); Line 6683  SLJIT_ASSERT(cc == ccend);
6683    
6684  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6685    
6686  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
6687  {  {
6688  DEFINE_COMPILER;  DEFINE_COMPILER;
6689  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5878  pcre_uchar type; Line 6692  pcre_uchar type;
6692  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
6693  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6694  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6695    jump_list *jumplist = NULL;
6696    int localptr = PRIV_DATA(cc);
6697    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6698    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6699    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6700    
6701  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6702    
# Line 5889  switch(opcode) Line 6708  switch(opcode)
6708    case OP_CRRANGE:    case OP_CRRANGE:
6709    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6710      {      {
6711      set_jumps(current->topfallbacks, LABEL());      SLJIT_ASSERT(localptr == 0);
6712        set_jumps(current->topbacktracks, LABEL());
6713      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6714      free_stack(common, 1);      free_stack(common, 1);
6715      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
6716      }      }
6717    else    else
6718      {      {
6719      if (opcode == OP_STAR || opcode == OP_UPTO)