/[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 991 by zherczeg, Sun Jul 8 16:44:39 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 try 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 try path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Hot path: match happens.     Try 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.     Try 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 try path
112   '(' hot path (pushing arguments to the stack)   '(' try path (pushing arguments to the stack)
113   B hot path   B try path
114   ')' hot path (pushing arguments to the stack)   ')' try path (pushing arguments to the stack)
115   D hot path   D try 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 try 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 try 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_trypath, and contains
192  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackpath. 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 *trypath;
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 *alttrypath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivehotpath;    struct sljit_label *recursivetrypath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerohotpath;    struct sljit_label *zerotrypath;
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 *trypath;
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 *trypath;
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_trypath
479   compile_fallbackpath   compile_backtrackpath
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 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 2041  if (newlinecheck) Line 2467  if (newlinecheck)
2467    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2468    }    }
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      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2651      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2652      }
2653    else
2654      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2655    
2656    start = LABEL();
2657    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2658    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2659    #ifdef COMPILE_PCRE8
2660    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2661    #else /* COMPILE_PCRE8 */
2662    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2663  #endif  #endif
 if (newlinecheck) readuchar = TRUE;  
2664    
2665  if (readuchar)  #else /* SLJIT_UNALIGNED */
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
2666    
2667  if (newlinecheck)  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2668    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2669    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2670    #else /* SLJIT_BIG_ENDIAN */
2671    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2672    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2673    #endif /* SLJIT_BIG_ENDIAN */
2674    
2675  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #ifdef COMPILE_PCRE8
2676  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2677  if (common->utf)  #else /* COMPILE_PCRE8 */
2678    {  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);  
   }  
2679  #endif  #endif
2680  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2681  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);  
   }  
2682  #endif  #endif
 JUMPHERE(start);  
2683    
2684  if (newlinecheck)  if (chars[1] != 0 || chars[3] != 0)
2685    {    {
2686    JUMPHERE(end);    pair.asuchars[0] = chars[1];
2687    JUMPHERE(nl);    pair.asuchars[1] = chars[3];
2688      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2689    }    }
2690    
2691  return mainloop;  pair.asuchars[0] = chars[0];
2692    pair.asuchars[1] = chars[2];
2693    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2694    
2695    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2696    JUMPTO(SLJIT_JUMP, start);
2697    JUMPHERE(found);
2698    JUMPHERE(quit);
2699    
2700    if (firstline)
2701      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2702    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2703    return TRUE;
2704  }  }
2705    
2706  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)
2707  {  {
2708  DEFINE_COMPILER;  DEFINE_COMPILER;
2709  struct sljit_label *start;  struct sljit_label *start;
2710  struct sljit_jump *leave;  struct sljit_jump *quit;
2711  struct sljit_jump *found;  struct sljit_jump *found;
2712  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2713    
# Line 2103  if (firstline) Line 2718  if (firstline)
2718    }    }
2719    
2720  start = LABEL();  start = LABEL();
2721  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2722  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2723    
2724  oc = first_char;  oc = first_char;
# Line 2136  else Line 2751  else
2751    }    }
2752    
2753  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  
2754  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2755  JUMPHERE(found);  JUMPHERE(found);
2756  JUMPHERE(leave);  JUMPHERE(quit);
2757    
2758  if (firstline)  if (firstline)
2759    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 2169  DEFINE_COMPILER; Line 2765  DEFINE_COMPILER;
2765  struct sljit_label *loop;  struct sljit_label *loop;
2766  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2767  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2768  struct sljit_jump *leave;  struct sljit_jump *quit;
2769  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2770  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2771  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 2198  if (common->nltype == NLTYPE_FIXED && co Line 2794  if (common->nltype == NLTYPE_FIXED && co
2794    
2795    loop = LABEL();    loop = LABEL();
2796    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));
2797    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2798    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2799    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2800    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);
2801    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);
2802    
2803    JUMPHERE(leave);    JUMPHERE(quit);
2804    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2805    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2806    
# Line 2228  set_jumps(newline, loop); Line 2824  set_jumps(newline, loop);
2824    
2825  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2826    {    {
2827    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2828    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2829    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2830    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 2835  if (common->nltype == NLTYPE_ANY || comm
2835  #endif  #endif
2836    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2837    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2838    JUMPHERE(leave);    JUMPHERE(quit);
2839    }    }
2840  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2841  JUMPHERE(firstchar);  JUMPHERE(firstchar);
# Line 2252  static SLJIT_INLINE void fast_forward_st Line 2848  static SLJIT_INLINE void fast_forward_st
2848  {  {
2849  DEFINE_COMPILER;  DEFINE_COMPILER;
2850  struct sljit_label *start;  struct sljit_label *start;
2851  struct sljit_jump *leave;  struct sljit_jump *quit;
2852  struct sljit_jump *found;  struct sljit_jump *found;
2853  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2854  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2265  if (firstline) Line 2861  if (firstline)
2861    }    }
2862    
2863  start = LABEL();  start = LABEL();
2864  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2865  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2866  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2867  if (common->utf)  if (common->utf)
# Line 2309  if (common->utf) Line 2905  if (common->utf)
2905  #endif  #endif
2906  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2907  JUMPHERE(found);  JUMPHERE(found);
2908  JUMPHERE(leave);  JUMPHERE(quit);
2909    
2910  if (firstline)  if (firstline)
2911    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 2384  DEFINE_COMPILER; Line 2980  DEFINE_COMPILER;
2980  struct sljit_jump *jump;  struct sljit_jump *jump;
2981  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2982    
2983  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2984  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2985    GET_LOCAL_BASE(TMP3, 0, 0);
2986    
2987  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2988  mainloop = LABEL();  mainloop = LABEL();
2989  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2990  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);
2991  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2992  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));
2993  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));
2994  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 3034  struct sljit_jump *jump;
3034    
3035  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3036    
3037  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);
3038  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3039  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3040  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 3132  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3132  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3133  }  }
3134    
3135    /*
3136      range format:
3137    
3138      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3139      ranges[1] = first bit (0 or 1)
3140      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3141    */
3142    
3143    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3144    {
3145    DEFINE_COMPILER;
3146    struct sljit_jump *jump;
3147    
3148    if (ranges[0] < 0)
3149      return FALSE;
3150    
3151    switch(ranges[0])
3152      {
3153      case 1:
3154      if (readch)
3155        read_char(common);
3156      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3157      return TRUE;
3158    
3159      case 2:
3160      if (readch)
3161        read_char(common);
3162      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3163      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3164      return TRUE;
3165    
3166      case 4:
3167      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3168        {
3169        if (readch)
3170          read_char(common);
3171        if (ranges[1] != 0)
3172          {
3173          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3174          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3175          }
3176        else
3177          {
3178          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          JUMPHERE(jump);
3181          }
3182        return TRUE;
3183        }
3184      return FALSE;
3185    
3186      default:
3187      return FALSE;
3188      }
3189    }
3190    
3191    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3192    {
3193    int i, bit, length;
3194    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3195    
3196    bit = ctypes[0] & flag;
3197    ranges[1] = bit != 0 ? 1 : 0;
3198    length = 0;
3199    
3200    for (i = 1; i < 256; i++)
3201      if ((ctypes[i] & flag) != bit)
3202        {
3203        if (length >= MAX_RANGE_SIZE)
3204          {
3205          ranges[0] = -1;
3206          return;
3207          }
3208        ranges[2 + length] = i;
3209        length++;
3210        bit ^= flag;
3211        }
3212    
3213    if (bit != 0)
3214      {
3215      if (length >= MAX_RANGE_SIZE)
3216        {
3217        ranges[0] = -1;
3218        return;
3219        }
3220      ranges[2 + length] = 256;
3221      length++;
3222      }
3223    ranges[0] = length;
3224    }
3225    
3226    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3227    {
3228    int ranges[2 + MAX_RANGE_SIZE];
3229    pcre_uint8 bit, cbit, all;
3230    int i, byte, length = 0;
3231    
3232    bit = bits[0] & 0x1;
3233    ranges[1] = bit;
3234    /* Can be 0 or 255. */
3235    all = -bit;
3236    
3237    for (i = 0; i < 256; )
3238      {
3239      byte = i >> 3;
3240      if ((i & 0x7) == 0 && bits[byte] == all)
3241        i += 8;
3242      else
3243        {
3244        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3245        if (cbit != bit)
3246          {
3247          if (length >= MAX_RANGE_SIZE)
3248            return FALSE;
3249          ranges[2 + length] = i;
3250          length++;
3251          bit = cbit;
3252          all = -cbit;
3253          }
3254        i++;
3255        }
3256      }
3257    
3258    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3259      {
3260      if (length >= MAX_RANGE_SIZE)
3261        return FALSE;
3262      ranges[2 + length] = 256;
3263      length++;
3264      }
3265    ranges[0] = length;
3266    
3267    return check_ranges(common, ranges, backtracks, FALSE);
3268    }
3269    
3270  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3271  {  {
3272  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3273  DEFINE_COMPILER;  DEFINE_COMPILER;
3274    
3275  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3276    
3277  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3278  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 3299  static void check_hspace(compiler_common
3299  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3300  DEFINE_COMPILER;  DEFINE_COMPILER;
3301    
3302  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3303    
3304  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);
3305  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 3338  static void check_vspace(compiler_common
3338  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3339  DEFINE_COMPILER;  DEFINE_COMPILER;
3340    
3341  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3342    
3343  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3344  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 3370  DEFINE_COMPILER;
3370  struct sljit_jump *jump;  struct sljit_jump *jump;
3371  struct sljit_label *label;  struct sljit_label *label;
3372    
3373  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3374  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3375  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3376  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 3399  DEFINE_COMPILER;
3399  struct sljit_jump *jump;  struct sljit_jump *jump;
3400  struct sljit_label *label;  struct sljit_label *label;
3401    
3402  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3403  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3404    
3405  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2731  return src2; Line 3463  return src2;
3463  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3464    
3465  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,
3466      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3467  {  {
3468  DEFINE_COMPILER;  DEFINE_COMPILER;
3469  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2832  do Line 3564  do
3564        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3565        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3566          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);
3567        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));
3568        break;        break;
3569    
3570        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3571        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3572          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);
3573        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));
3574        break;        break;
3575    
3576  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3577        case 1:        case 1:
3578        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3579          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);
3580        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));
3581        break;        break;
3582  #endif  #endif
3583    
# Line 2871  do Line 3603  do
3603    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3604      {      {
3605      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3606      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));
3607      }      }
3608    else    else
3609      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));
3610    
3611  #endif  #endif
3612    
# Line 2910  return cc; Line 3642  return cc;
3642      } \      } \
3643    charoffset = (value);    charoffset = (value);
3644    
3645  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3646  {  {
3647  DEFINE_COMPILER;  DEFINE_COMPILER;
3648  jump_list *found = NULL;  jump_list *found = NULL;
3649  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3650  unsigned int c;  unsigned int c;
3651  int compares;  int compares;
3652  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2928  unsigned int typeoffset; Line 3660  unsigned int typeoffset;
3660  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3661  unsigned int charoffset;  unsigned int charoffset;
3662    
3663  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3664  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3665    detect_partial_match(common, backtracks);
3666  read_char(common);  read_char(common);
3667    
3668  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2942  if ((*cc++ & XCL_MAP) != 0) Line 3675  if ((*cc++ & XCL_MAP) != 0)
3675      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3676  #endif  #endif
3677    
3678    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3679    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3680    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3681    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3682    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);
3683    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3684        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3685        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3686        }
3687    
3688  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3689    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3080  typeoffset = 0; Line 3816  typeoffset = 0;
3816  while (*cc != XCL_END)  while (*cc != XCL_END)
3817    {    {
3818    compares--;    compares--;
3819    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3820    jump = NULL;    jump = NULL;
3821    
3822    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3162  while (*cc != XCL_END) Line 3898  while (*cc != XCL_END)
3898      switch(*cc)      switch(*cc)
3899        {        {
3900        case PT_ANY:        case PT_ANY:
3901        if (list != fallbacks)        if (list != backtracks)
3902          {          {
3903          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))
3904            continue;            continue;
# Line 3235  while (*cc != XCL_END) Line 3971  while (*cc != XCL_END)
3971  #endif  #endif
3972    
3973    if (jump != NULL)    if (jump != NULL)
3974      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3975    }    }
3976    
3977  if (found != NULL)  if (found != NULL)
# Line 3247  if (found != NULL) Line 3983  if (found != NULL)
3983    
3984  #endif  #endif
3985    
3986  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3987  {  {
3988  DEFINE_COMPILER;  DEFINE_COMPILER;
3989  int length;  int length;
# Line 3266  switch(type) Line 4002  switch(type)
4002    case OP_SOD:    case OP_SOD:
4003    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4004    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));
4005    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));
4006    return cc;    return cc;
4007    
4008    case OP_SOM:    case OP_SOM:
4009    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4010    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));
4011    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));
4012    return cc;    return cc;
4013    
4014    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4015    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4016    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4017    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));
4018    return cc;    return cc;
4019    
4020    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4021    case OP_DIGIT:    case OP_DIGIT:
4022    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4023    read_char8_type(common);    if (common->digits[0] == -2)
4024    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4025    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4026      /* Flip the starting bit in the negative case. */
4027      if (type == OP_NOT_DIGIT)
4028        common->digits[1] ^= 1;
4029      if (!check_ranges(common, common->digits, backtracks, TRUE))
4030        {
4031        read_char8_type(common);
4032        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4033        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4034        }
4035      if (type == OP_NOT_DIGIT)
4036        common->digits[1] ^= 1;
4037    return cc;    return cc;
4038    
4039    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4040    case OP_WHITESPACE:    case OP_WHITESPACE:
4041    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4042    read_char8_type(common);    read_char8_type(common);
4043    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);
4044    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));
4045    return cc;    return cc;
4046    
4047    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4048    case OP_WORDCHAR:    case OP_WORDCHAR:
4049    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4050    read_char8_type(common);    read_char8_type(common);
4051    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);
4052    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));
4053    return cc;    return cc;
4054    
4055    case OP_ANY:    case OP_ANY:
4056    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4057    read_char(common);    read_char(common);
4058    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4059      {      {
# Line 3317  switch(type) Line 4064  switch(type)
4064        jump[1] = check_str_end(common);        jump[1] = check_str_end(common);
4065    
4066      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4067      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));
4068      if (jump[1] != NULL)      if (jump[1] != NULL)
4069        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4070      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4071      }      }
4072    else    else
4073      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4074    return cc;    return cc;
4075    
4076    case OP_ALLANY:    case OP_ALLANY:
4077    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4078  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4079    if (common->utf)    if (common->utf)
4080      {      {
# Line 3355  switch(type) Line 4102  switch(type)
4102    return cc;    return cc;
4103    
4104    case OP_ANYBYTE:    case OP_ANYBYTE:
4105    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4106    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));
4107    return cc;    return cc;
4108    
# Line 3368  switch(type) Line 4115  switch(type)
4115    propdata[2] = cc[0];    propdata[2] = cc[0];
4116    propdata[3] = cc[1];    propdata[3] = cc[1];
4117    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4118    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_trypath(common, propdata, backtracks);
4119    return cc + 2;    return cc + 2;
4120  #endif  #endif
4121  #endif  #endif
4122    
4123    case OP_ANYNL:    case OP_ANYNL:
4124    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4125    read_char(common);    read_char(common);
4126    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);
4127    /* 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 4134  switch(type)
4134    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));
4135    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4136    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4137    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4138    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4139    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4140    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3395  switch(type) Line 4142  switch(type)
4142    
4143    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4144    case OP_HSPACE:    case OP_HSPACE:
4145    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4146    read_char(common);    read_char(common);
4147    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4148    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));
4149    return cc;    return cc;
4150    
4151    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4152    case OP_VSPACE:    case OP_VSPACE:
4153    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4154    read_char(common);    read_char(common);
4155    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4156    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));
4157    return cc;    return cc;
4158    
4159  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4160    case OP_EXTUNI:    case OP_EXTUNI:
4161    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4162    read_char(common);    read_char(common);
4163    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4164    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
4165    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));
4166    
4167    label = LABEL();    label = LABEL();
4168    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 4192  switch(type)
4192      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));
4193      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4194      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4195        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));
4196      else      else
4197        {        {
4198        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 4200  switch(type)
4200        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4201        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);
4202        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);
4203        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4204        check_partial(common, TRUE);        check_partial(common, TRUE);
4205        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4206        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4207        }        }
4208      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4209      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));
4210      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));
4211      }      }
4212    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4213      {      {
4214      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));
4215      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4216      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));
4217      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));
4218      }      }
4219    else    else
4220      {      {
# Line 3476  switch(type) Line 4223  switch(type)
4223      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));
4224      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);
4225      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4226      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4227      /* Equal. */      /* Equal. */
4228      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4229      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4230      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4231    
4232      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4233      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4234        {        {
4235        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));
4236        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));
4237        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));
4238        }        }
4239      else      else
4240        {        {
4241        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4242        read_char(common);        read_char(common);
4243        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));
4244        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4245        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4246        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4247        }        }
4248      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
# Line 3506  switch(type) Line 4253  switch(type)
4253    return cc;    return cc;
4254    
4255    case OP_EOD:    case OP_EOD:
4256    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));
4257    check_partial(common, FALSE);    check_partial(common, FALSE);
4258    return cc;    return cc;
4259    
4260    case OP_CIRC:    case OP_CIRC:
4261    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4262    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));
4263    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));
4264    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));
4265    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));
4266    return cc;    return cc;
4267    
4268    case OP_CIRCM:    case OP_CIRCM:
# Line 3523  switch(type) Line 4270  switch(type)
4270    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));
4271    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4272    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));
4273    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));
4274    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4275    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4276    
4277    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));
4278    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4279      {      {
4280      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));
4281      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4282      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4283      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4284      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));
4285      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));
4286      }      }
4287    else    else
4288      {      {
4289      skip_char_back(common);      skip_char_back(common);
4290      read_char(common);      read_char(common);
4291      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4292      }      }
4293    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4294    return cc;    return cc;
# Line 3549  switch(type) Line 4296  switch(type)
4296    case OP_DOLL:    case OP_DOLL:
4297    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4298    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));
4299    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));
4300    
4301    if (!common->endonly)    if (!common->endonly)
4302      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_trypath(common, OP_EODN, cc, backtracks);
4303    else    else
4304      {      {
4305      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));
4306      check_partial(common, FALSE);      check_partial(common, FALSE);
4307      }      }
4308    return cc;    return cc;
# Line 3564  switch(type) Line 4311  switch(type)
4311    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4312    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4313    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));
4314    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));
4315    check_partial(common, FALSE);    check_partial(common, FALSE);
4316    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4317    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3574  switch(type) Line 4321  switch(type)
4321      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));
4322      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4323      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4324        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));
4325      else      else
4326        {        {
4327        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4328        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
4329        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));
4330        check_partial(common, TRUE);        check_partial(common, TRUE);
4331        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4332        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4333        }        }
4334    
4335      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4336      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));
4337      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));
4338      }      }
4339    else    else
4340      {      {
4341      peek_char(common);      peek_char(common);
4342      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4343      }      }
4344    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4345    return cc;    return cc;
# Line 3606  switch(type) Line 4353  switch(type)
4353    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))
4354      {      {
4355      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));
4356      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));
4357    
4358      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4359      context.sourcereg = -1;      context.sourcereg = -1;
4360  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4361      context.ucharptr = 0;      context.ucharptr = 0;
4362  #endif  #endif
4363      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4364      }      }
4365    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4366    read_char(common);    read_char(common);
4367  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4368    if (common->utf)    if (common->utf)
# Line 3627  switch(type) Line 4374  switch(type)
4374      c = *cc;      c = *cc;
4375    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4376      {      {
4377      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));
4378      return cc + length;      return cc + length;
4379      }      }
4380    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 3635  switch(type) Line 4382  switch(type)
4382    if (ispowerof2(bit))    if (ispowerof2(bit))
4383      {      {
4384      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4385      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));
4386      return cc + length;      return cc + length;
4387      }      }
4388    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);
4389    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4390    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, char_othercase(common, c));
4391    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4392    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4393    return cc + length;    return cc + length;
4394    
4395    case OP_NOT:    case OP_NOT:
4396    case OP_NOTI:    case OP_NOTI:
4397    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4398    length = 1;    length = 1;
4399  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4400    if (common->utf)    if (common->utf)
# Line 3658  switch(type) Line 4405  switch(type)
4405        {        {
4406        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4407        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4408          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));
4409        else        else
4410          {          {
4411          /* 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. */
4412          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4413          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));
4414          }          }
4415        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4416        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 4435  switch(type)
4435      }      }
4436    
4437    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4438      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));
4439    else    else
4440      {      {
4441      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3696  switch(type) Line 4443  switch(type)
4443      if (ispowerof2(bit))      if (ispowerof2(bit))
4444        {        {
4445        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4446        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));
4447        }        }
4448      else      else
4449        {        {
4450        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));
4451        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));
4452        }        }
4453      }      }
4454    return cc + length;    return cc + length;
4455    
4456    case OP_CLASS:    case OP_CLASS:
4457    case OP_NCLASS:    case OP_NCLASS:
4458    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4459    read_char(common);    read_char(common);
4460      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4461        return cc + 32 / sizeof(pcre_uchar);
4462    
4463  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4464    jump[0] = NULL;    jump[0] = NULL;
4465  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3721  switch(type) Line 4471  switch(type)
4471      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4472      if (type == OP_CLASS)      if (type == OP_CLASS)
4473        {        {
4474        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4475        jump[0] = NULL;        jump[0] = NULL;
4476        }        }
4477      }      }
# Line 3731  switch(type) Line 4481  switch(type)
4481    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4482    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4483    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);
4484    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4485  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4486    if (jump[0] != NULL)    if (jump[0] != NULL)
4487      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3740  switch(type) Line 4490  switch(type)
4490    
4491  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4492    case OP_XCLASS:    case OP_XCLASS:
4493    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
4494    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4495  #endif  #endif
4496    
4497    case OP_REVERSE:    case OP_REVERSE:
4498    length = GET(cc, 0);    length = GET(cc, 0);
4499    SLJIT_ASSERT(length > 0);    if (length == 0)
4500        return cc + LINK_SIZE;
4501    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4502  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4503    if (common->utf)    if (common->utf)
# Line 3754  switch(type) Line 4505  switch(type)
4505      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));
4506      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4507      label = LABEL();      label = LABEL();
4508      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));
4509      skip_char_back(common);      skip_char_back(common);
4510      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);
4511      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3764  switch(type) Line 4515  switch(type)
4515      {      {
4516      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));
4517      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));
4518      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));
4519      }      }
4520    check_start_used_ptr(common);    check_start_used_ptr(common);
4521    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3773  SLJIT_ASSERT_STOP(); Line 4524  SLJIT_ASSERT_STOP();
4524  return cc;  return cc;
4525  }  }
4526    
4527  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_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4528  {  {
4529  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4530  /* 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 4576  if (context.length > 0)
4576    {    {
4577    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4578    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);
4579    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));
4580    
4581    context.sourcereg = -1;    context.sourcereg = -1;
4582  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4583    context.ucharptr = 0;    context.ucharptr = 0;
4584  #endif  #endif
4585    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);
4586    return cc;    return cc;
4587    }    }
4588    
4589  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4590  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_trypath(common, *cc, cc + 1, backtracks);
4591  }  }
4592    
4593  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)
4594  {  {
4595  DEFINE_COMPILER;  DEFINE_COMPILER;
4596  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3847  int offset = GET2(cc, 1) << 1; Line 4598  int offset = GET2(cc, 1) << 1;
4598  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4599  if (!common->jscript_compat)  if (!common->jscript_compat)
4600    {    {
4601    if (fallbacks == NULL)    if (backtracks == NULL)
4602      {      {
4603      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4604      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 4607  if (!common->jscript_compat)
4607      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4608      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4609      }      }
4610    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)));
4611    }    }
4612  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));
4613  }  }
4614    
4615  /* Forward definitions. */  /* Forward definitions. */
4616  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4617  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
4618    
4619  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4620    do \    do \
4621      { \      { \
4622      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4623      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4624        return error; \        return error; \
4625      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4626      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4627      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4628      parent->top = fallback; \      parent->top = backtrack; \
4629      } \      } \
4630    while (0)    while (0)
4631    
4632  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4633    do \    do \
4634      { \      { \
4635      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4636      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4637        return; \        return; \
4638      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4639      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4640      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4641      parent->top = fallback; \      parent->top = backtrack; \
4642      } \      } \
4643    while (0)    while (0)
4644    
4645  #define FALLBACK_AS(type) ((type *)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4646    
4647  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4648  {  {
4649  DEFINE_COMPILER;  DEFINE_COMPILER;
4650  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3904  struct sljit_jump *nopartial; Line 4655  struct sljit_jump *nopartial;
4655  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4656  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
4657  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4658    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)));
4659    
4660  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4661  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3921  if (common->utf && *cc == OP_REFI) Line 4672  if (common->utf && *cc == OP_REFI)
4672    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));
4673    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4674    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4675      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));
4676    else    else
4677      {      {
4678      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));
4679      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);
4680      check_partial(common, FALSE);      check_partial(common, FALSE);
4681      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4682      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4683      }      }
4684    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3942  else Line 4693  else
4693    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4694    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4695    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4696      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
4697    
4698    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));
4699    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));
4700    
4701    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
4702      {      {
# Line 3957  else Line 4708  else
4708      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4709      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4710      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));
4711      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));
4712      JUMPHERE(partial);      JUMPHERE(partial);
4713      check_partial(common, FALSE);      check_partial(common, FALSE);
4714      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4715      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4716      }      }
4717    }    }
# Line 3968  else Line 4719  else
4719  if (jump != NULL)  if (jump != NULL)
4720    {    {
4721    if (emptyfail)    if (emptyfail)
4722      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4723    else    else
4724      JUMPHERE(jump);      JUMPHERE(jump);
4725    }    }
4726  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4727  }  }
4728    
4729  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_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4730  {  {
4731  DEFINE_COMPILER;  DEFINE_COMPILER;
4732  fallback_common *fallback;  backtrack_common *backtrack;
4733  pcre_uchar type;  pcre_uchar type;
4734  struct sljit_label *label;  struct sljit_label *label;
4735  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3987  pcre_uchar *ccbegin = cc; Line 4738  pcre_uchar *ccbegin = cc;
4738  int min = 0, max = 0;  int min = 0, max = 0;
4739  BOOL minimize;  BOOL minimize;
4740    
4741  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4742    
4743  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4744  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 4039  if (!minimize) Line 4790  if (!minimize)
4790      {      {
4791      allocate_stack(common, 1);      allocate_stack(common, 1);
4792      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4793      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4794      }      }
4795    
4796    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4797      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4798    
4799    label = LABEL();    label = LABEL();
4800    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4801    
4802    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4803      {      {
# Line 4074  if (!minimize) Line 4825  if (!minimize)
4825      }      }
4826    
4827    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4828    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4829    
4830    decrease_call_count(common);    decrease_call_count(common);
4831    return cc;    return cc;
# Line 4092  if (min == 0) Line 4843  if (min == 0)
4843    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4844    }    }
4845  else  else
4846    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4847    
4848  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4849  if (max > 0)  if (max > 0)
4850    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));
4851    
4852  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4853  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4854    
4855  if (min > 1)  if (min > 1)
# Line 4106  if (min > 1) Line 4857  if (min > 1)
4857    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4858    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4859    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4860    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)->trypath);
4861    }    }
4862  else if (max > 0)  else if (max > 0)
4863    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 4870  decrease_call_count(common);
4870  return cc;  return cc;
4871  }  }
4872    
4873  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4874  {  {
4875  DEFINE_COMPILER;  DEFINE_COMPILER;
4876  fallback_common *fallback;  backtrack_common *backtrack;
4877  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4878  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4879  int start = GET(cc, 1);  int start = GET(cc, 1);
4880    
4881  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4882  while (entry != NULL)  while (entry != NULL)
4883    {    {
4884    if (entry->start == start)    if (entry->start == start)
# Line 4172  if (entry->entry == NULL) Line 4923  if (entry->entry == NULL)
4923  else  else
4924    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4925  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4926  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));
4927  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4928  }  }
4929    
4930  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4931  {  {
4932  DEFINE_COMPILER;  DEFINE_COMPILER;
4933  int framesize;  int framesize;
4934  int localptr;  int localptr;
4935  fallback_common altfallback;  backtrack_common altbacktrack;
4936  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4937  pcre_uchar opcode;  pcre_uchar opcode;
4938  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4939  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4940  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4941  jump_list **found;  jump_list **found;
4942  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4943  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4944  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4945  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4946  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4947  struct sljit_jump *jump;  struct sljit_jump *jump;
4948  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4956  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4956  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
4957  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4958  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4959  fallback->framesize = framesize;  backtrack->framesize = framesize;
4960  fallback->localptr = localptr;  backtrack->localptr = localptr;
4961  opcode = *cc;  opcode = *cc;
4962  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4963  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 4966  cc += GET(cc, 1);
4966    
4967  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4968    {    {
4969    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
4970    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4971    free_stack(common, 1);    free_stack(common, 1);
4972    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 4989  else
4989    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
4990    }    }
4991    
4992  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
4993  common->leavelabel = NULL;  common->quitlabel = NULL;
4994  common->leave = NULL;  common->quit = NULL;
4995  while (1)  while (1)
4996    {    {
4997    common->acceptlabel = NULL;    common->acceptlabel = NULL;
4998    common->accept = NULL;    common->accept = NULL;
4999    altfallback.top = NULL;    altbacktrack.top = NULL;
5000    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5001    
5002    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5003      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5004    
5005    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5006    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5007    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5008      {      {
5009      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5010      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5011      common->leave = save_leave;      common->quit = save_quit;
5012      common->accept = save_accept;      common->accept = save_accept;
5013      return NULL;      return NULL;
5014      }      }
# Line 4307  while (1) Line 5058  while (1)
5058      }      }
5059    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5060    
5061    compile_fallbackpath(common, altfallback.top);    compile_backtrackpath(common, altbacktrack.top);
5062    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5063      {      {
5064      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5065      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5066      common->leave = save_leave;      common->quit = save_quit;
5067      common->accept = save_accept;      common->accept = save_accept;
5068      return NULL;      return NULL;
5069      }      }
5070    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5071    
5072    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5073      break;      break;
# Line 4325  while (1) Line 5076  while (1)
5076    cc += GET(cc, 1);    cc += GET(cc, 1);
5077    }    }
5078  /* None of them matched. */  /* None of them matched. */
5079  if (common->leave != NULL)  if (common->quit != NULL)
5080    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5081    
5082  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5083    {    {
# Line 4393  if (opcode == OP_ASSERT || opcode == OP_ Line 5144  if (opcode == OP_ASSERT || opcode == OP_
5144    
5145    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5146      {      {
5147      fallback->hotpath = LABEL();      backtrack->trypath = LABEL();
5148      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->trypath);
5149      }      }
5150    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5151      {      {
5152      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->trypath);
5153      JUMPHERE(brajump);      JUMPHERE(brajump);
5154      if (framesize >= 0)      if (framesize >= 0)
5155        {        {
# Line 4406  if (opcode == OP_ASSERT || opcode == OP_ Line 5157  if (opcode == OP_ASSERT || opcode == OP_
5157        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5158        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));
5159        }        }
5160      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5161      }      }
5162    }    }
5163  else  else
# Line 4436  else Line 5187  else
5187      }      }
5188    
5189    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5190      fallback->hotpath = LABEL();      backtrack->trypath = LABEL();
5191    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5192      {      {
5193      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->trypath);
5194      JUMPHERE(brajump);      JUMPHERE(brajump);
5195      }      }
5196    
5197    if (bra != OP_BRA)    if (bra != OP_BRA)
5198      {      {
5199      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5200      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5201      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5202      }      }
5203    }    }
5204    
5205  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5206  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5207  common->leave = save_leave;  common->quit = save_quit;
5208  common->accept = save_accept;  common->accept = save_accept;
5209  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5210  }  }
# Line 4622  return condition; Line 5373  return condition;
5373                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5374  */  */
5375    
5376  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5377  {  {
5378  DEFINE_COMPILER;  DEFINE_COMPILER;
5379  fallback_common *fallback;  backtrack_common *backtrack;
5380  pcre_uchar opcode;  pcre_uchar opcode;
5381  int localptr = 0;  int localptr = 0;
5382  int offset = 0;  int offset = 0;
5383  int stacksize;  int stacksize;
5384  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5385  pcre_uchar *hotpath;  pcre_uchar *trypath;
5386  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5387  pcre_uchar ket;  pcre_uchar ket;
5388  assert_fallback *assert;  assert_backtrack *assert;
5389  BOOL has_alternatives;  BOOL has_alternatives;
5390  struct sljit_jump *jump;  struct sljit_jump *jump;
5391  struct sljit_jump *skip;  struct sljit_jump *skip;
5392  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
5393  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
5394    
5395  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5396    
5397  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5398    {    {
# Line 4652  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5403  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5403    
5404  opcode = *cc;  opcode = *cc;
5405  ccbegin = cc;  ccbegin = cc;
5406  hotpath = ccbegin + 1 + LINK_SIZE;  trypath = ccbegin + 1 + LINK_SIZE;
5407    
5408  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)
5409    {    {
5410    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
5411    parent->top = fallback->prev;    parent->top = backtrack->prev;
5412    return bracketend(cc);    return bracketend(cc);
5413    }    }
5414    
# Line 4669  cc += GET(cc, 1); Line 5420  cc += GET(cc, 1);
5420  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5421  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5422    {    {
5423    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;
5424    if (*hotpath == OP_NRREF)    if (*trypath == OP_NRREF)
5425      {      {
5426      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
5427      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5428        has_alternatives = FALSE;        has_alternatives = FALSE;
5429      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4693  if (opcode == OP_CBRA || opcode == OP_SC Line 5444  if (opcode == OP_CBRA || opcode == OP_SC
5444    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5445    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
5446    offset <<= 1;    offset <<= 1;
5447    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5448    hotpath += IMM2_SIZE;    trypath += IMM2_SIZE;
5449    }    }
5450  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5451    {    {
5452    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5453    localptr = PRIV_DATA(ccbegin);    localptr = PRIV_DATA(ccbegin);
5454    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
5455    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5456    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5457      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5458    }    }
5459    
5460  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4728  if (bra == OP_BRAZERO) Line 5479  if (bra == OP_BRAZERO)
5479    
5480  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5481    {    {
5482    /* 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) */
5483    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5484    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
5485      {      {
# Line 4745  if (bra == OP_BRAMINZERO) Line 5496  if (bra == OP_BRAMINZERO)
5496        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
5497        JUMPHERE(jump);        JUMPHERE(jump);
5498        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5499        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5500          {          {
5501          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, localptr contains the previous STR_PTR. */
5502          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 5505  if (bra == OP_BRAMINZERO)
5505          {          {
5506          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5507          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5508          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));
5509          }          }
5510        JUMPHERE(skip);        JUMPHERE(skip);
5511        }        }
# Line 4768  if (bra == OP_BRAMINZERO) Line 5519  if (bra == OP_BRAMINZERO)
5519    }    }
5520    
5521  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5522    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5523    
5524  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5525    {    {
5526    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5527    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5528      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;
5529    }    }
5530    
5531  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
5532  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5533    {    {
5534    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5535      {      {
5536      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5537      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
# Line 4804  if (opcode == OP_ONCE) Line 5555  if (opcode == OP_ONCE)
5555      {      {
5556      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5557        {        {
5558        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5559        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5560        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));
5561        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5562        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5563        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5564        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);
5565        }        }
5566      else      else
5567        {        {
5568        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5569        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5570        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));
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(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5573        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5574        }        }
5575      }      }
5576    }    }
# Line 4853  else if (has_alternatives) Line 5604  else if (has_alternatives)
5604  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5605  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5606    {    {
5607    if (*hotpath == OP_CREF)    if (*trypath == OP_CREF)
5608      {      {
5609      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5610      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5611        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(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5612      hotpath += 1 + IMM2_SIZE;      trypath += 1 + IMM2_SIZE;
5613      }      }
5614    else if (*hotpath == OP_NCREF)    else if (*trypath == OP_NCREF)
5615      {      {
5616      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5617      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
5618      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));
5619    
5620      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5621      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);
5622      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);
5623      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)));
5624      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5625      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5626      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));
5627      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5628      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));
5629    
5630      JUMPHERE(jump);      JUMPHERE(jump);
5631      hotpath += 1 + IMM2_SIZE;      trypath += 1 + IMM2_SIZE;
5632      }      }
5633    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*trypath == OP_RREF || *trypath == OP_NRREF)
5634      {      {
5635      /* Never has other case. */      /* Never has other case. */
5636      FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5637    
5638      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
5639      if (common->currententry == NULL)      if (common->currententry == NULL)
5640        stacksize = 0;        stacksize = 0;
5641      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4894  if (opcode == OP_COND || opcode == OP_SC Line 5645  if (opcode == OP_COND || opcode == OP_SC
5645      else      else
5646        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5647    
5648      if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)
5649        {        {
5650        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5651        if (stacksize != 0)        if (stacksize != 0)
5652          hotpath += 1 + IMM2_SIZE;          trypath += 1 + IMM2_SIZE;
5653        else        else
5654          {          {
5655          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5656            {            {
5657            hotpath = cc + 1 + LINK_SIZE;            trypath = cc + 1 + LINK_SIZE;
5658            cc += GET(cc, 1);            cc += GET(cc, 1);
5659            }            }
5660          else          else
5661            hotpath = cc;            trypath = cc;
5662          }          }
5663        }        }
5664      else      else
5665        {        {
5666        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5667    
5668        stacksize = GET2(hotpath, 1);        stacksize = GET2(trypath, 1);
5669        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5670        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);
5671        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);
5672        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));
5673        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
5674        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5675        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5676        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));
5677        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5678        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));
5679        hotpath += 1 + IMM2_SIZE;        trypath += 1 + IMM2_SIZE;
5680        }        }
5681      }      }
5682    else    else
5683      {      {
5684      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);
5685      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5686      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5687      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5688        return NULL;        return NULL;
5689      memset(assert, 0, sizeof(assert_fallback));      memset(assert, 0, sizeof(assert_backtrack));
5690      assert->common.cc = hotpath;      assert->common.cc = trypath;
5691      FALLBACK_AS(bracket_fallback)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5692      hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);      trypath = compile_assert_trypath(common, trypath, assert, TRUE);
5693      }      }
5694    }    }
5695    
5696  compile_hotpath(common, hotpath, cc, fallback);  compile_trypath(common, trypath, cc, backtrack);
5697  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5698    return NULL;    return NULL;
5699    
5700  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5701    {    {
5702    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5703      {      {
5704      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5705      /* 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 5714  if (opcode == OP_ONCE)
5714    else    else
5715      {      {
5716      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5717      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));
5718      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5719        {        {
5720        /* 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 5749  if (has_alternatives)
5749    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5750      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5751    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5752      FALLBACK_AS(bracket_fallback)->althotpath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5753    }    }
5754    
5755  /* Must be after the hotpath label. */  /* Must be after the trypath label. */
5756  if (offset != 0)  if (offset != 0)
5757    {    {
5758    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 5765  if (ket == OP_KETRMAX)
5765    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5766      {      {
5767      if (has_alternatives)      if (has_alternatives)
5768        FALLBACK_AS(bracket_fallback)->althotpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5769      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5770      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5771          {
5772        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);
5773          /* Drop STR_PTR for greedy plus quantifier. */
5774          if (bra != OP_BRAZERO)
5775            free_stack(common, 1);
5776          }
5777      else      else
5778        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5779        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5780      }      }
5781    else    else
5782      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5783    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5784    }    }
5785    
5786  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5787    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
5788    
5789  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5790    {    {
5791    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5792    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
5793    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5794      {      {
5795      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5796      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5797      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5798      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5799      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5800        {        {
5801        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5802        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 5804  if (bra == OP_BRAMINZERO)
5804      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5805        free_stack(common, 1);        free_stack(common, 1);
5806      }      }
5807    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5808    }    }
5809    
5810  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 5817  cc += 1 + LINK_SIZE;
5817  return cc;  return cc;
5818  }  }
5819    
5820  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5821  {  {
5822  DEFINE_COMPILER;  DEFINE_COMPILER;
5823  fallback_common *fallback;  backtrack_common *backtrack;
5824  pcre_uchar opcode;  pcre_uchar opcode;
5825  int localptr;  int localptr;
5826  int cbraprivptr = 0;  int cbraprivptr = 0;
# Line 5077  int stack; Line 5833  int stack;
5833  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5834  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5835    
5836  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5837  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5838    {    {
5839    zero = TRUE;    zero = TRUE;
# Line 5087  if (*cc == OP_BRAPOSZERO) Line 5843  if (*cc == OP_BRAPOSZERO)
5843  opcode = *cc;  opcode = *cc;
5844  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
5845  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
5846  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
5847  switch(opcode)  switch(opcode)
5848    {    {
5849    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5109  switch(opcode) Line 5865  switch(opcode)
5865    }    }
5866    
5867  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5868  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5869  if (framesize < 0)  if (framesize < 0)
5870    {    {
5871    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5872    if (!zero)    if (!zero)
5873      stacksize++;      stacksize++;
5874    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5875    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5876    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
5877    
# Line 5139  else Line 5895  else
5895      stacksize++;      stacksize++;
5896    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5897      stacksize++;      stacksize++;
5898    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5899    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5900    
5901    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 5922  if (opcode == OP_CBRAPOS || opcode == OP
5922  loop = LABEL();  loop = LABEL();
5923  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
5924    {    {
5925    fallback->top = NULL;    backtrack->top = NULL;
5926    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
5927    cc += GET(cc, 1);    cc += GET(cc, 1);
5928    
5929    compile_hotpath(common, ccbegin, cc, fallback);    compile_trypath(common, ccbegin, cc, backtrack);
5930    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5931      return NULL;      return NULL;
5932    
# Line 5231  while (*cc != OP_KETRPOS) Line 5987  while (*cc != OP_KETRPOS)
5987    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5988    flush_stubs(common);    flush_stubs(common);
5989    
5990    compile_fallbackpath(common, fallback->top);    compile_backtrackpath(common, backtrack->top);
5991    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5992      return NULL;      return NULL;
5993    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
5994    
5995    if (framesize < 0)    if (framesize < 0)
5996      {      {
# Line 5264  while (*cc != OP_KETRPOS) Line 6020  while (*cc != OP_KETRPOS)
6020    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6021    }    }
6022    
6023  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
6024  if (!zero)  if (!zero)
6025    {    {
6026    if (framesize < 0)    if (framesize < 0)
6027      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));
6028    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [localptr] above. */
6029      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));
6030    }    }
6031    
6032  /* None of them matched. */  /* None of them matched. */
# Line 5371  if (end != NULL) Line 6127  if (end != NULL)
6127  return cc;  return cc;
6128  }  }
6129    
6130  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6131  {  {
6132  DEFINE_COMPILER;  DEFINE_COMPILER;
6133  fallback_common *fallback;  backtrack_common *backtrack;
6134  pcre_uchar opcode;  pcre_uchar opcode;
6135  pcre_uchar type;  pcre_uchar type;
6136  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 5382  pcre_uchar* end; Line 6138  pcre_uchar* end;
6138  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6139  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6140  struct sljit_label *label;  struct sljit_label *label;
6141    int localptr = PRIV_DATA(cc);
6142    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6143    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6144    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6145    int tmp_base, tmp_offset;
6146    
6147  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6148    
6149  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6150    
6151    switch (type)
6152      {
6153      case OP_NOT_DIGIT:
6154      case OP_DIGIT:
6155      case OP_NOT_WHITESPACE:
6156      case OP_WHITESPACE:
6157      case OP_NOT_WORDCHAR:
6158      case OP_WORDCHAR:
6159      case OP_ANY:
6160      case OP_ALLANY:
6161      case OP_ANYBYTE:
6162      case OP_ANYNL:
6163      case OP_NOT_HSPACE:
6164      case OP_HSPACE:
6165      case OP_NOT_VSPACE:
6166      case OP_VSPACE:
6167      case OP_CHAR:
6168      case OP_CHARI:
6169      case OP_NOT:
6170      case OP_NOTI:
6171      case OP_CLASS:
6172      case OP_NCLASS:
6173      tmp_base = TMP3;
6174      tmp_offset = 0;
6175      break;
6176    
6177      default:
6178      SLJIT_ASSERT_STOP();
6179      /* Fall through. */
6180    
6181      case OP_EXTUNI:
6182      case OP_XCLASS:
6183      case OP_NOTPROP:
6184      case OP_PROP:
6185      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6186      tmp_offset = POSSESSIVE0;
6187      break;
6188      }
6189    
6190  switch(opcode)  switch(opcode)
6191    {    {
6192    case OP_STAR:    case OP_STAR:
# Line 5395  switch(opcode) Line 6195  switch(opcode)
6195    case OP_CRRANGE:    case OP_CRRANGE:
6196    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6197      {      {
6198        SLJIT_ASSERT(localptr == 0);
6199      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6200        {        {
6201        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5406  switch(opcode) Line 6207  switch(opcode)
6207        allocate_stack(common, 1);        allocate_stack(common, 1);
6208        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6209        }        }
6210    
6211      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6212        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6213    
6214      label = LABEL();      label = LABEL();
6215      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6216      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6217        {        {
6218        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 6224  switch(opcode)
6224        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6225        }        }
6226    
6227        /* We cannot use TMP3 because of this allocate_stack. */
6228      allocate_stack(common, 1);      allocate_stack(common, 1);
6229      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6230      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5430  switch(opcode) Line 6233  switch(opcode)
6233      }      }
6234    else    else
6235      {      {
6236      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6237      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6238      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (localptr == 0)
6239          allocate_stack(common, 2);
6240        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6241        if (opcode <= OP_PLUS)
6242          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6243        else
6244          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6245      label = LABEL();      label = LABEL();
6246      compile_char1_hotpath(common, type, cc, &nomatch);      compile_char1_trypath(common, type, cc, &nomatch);
6247      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6248      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6249          JUMPTO(SLJIT_JUMP, label);
6250        else if (opcode == OP_CRRANGE && arg1 == 0)
6251        {        {
6252        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);
6253        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6254        }        }
6255      else      else
6256        {        {
6257        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6258        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6259        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6260        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6261        }        }
6262      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6263      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6264        add_jump(compiler, &fallback->topfallbacks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6265          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));  
6266      }      }
6267    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6268    break;    break;
6269    
6270    case OP_MINSTAR:    case OP_MINSTAR:
6271    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6272    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6273      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6274    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    if (localptr == 0)
6275        allocate_stack(common, 1);
6276      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6277      BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6278    break;    break;
6279    
6280    case OP_MINUPTO:    case OP_MINUPTO:
6281    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6282    allocate_stack(common, 2);    if (localptr == 0)
6283    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6284    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6285      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6286    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6287      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6288    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6289    break;    break;
6290    
6291    case OP_QUERY:    case OP_QUERY:
6292    case OP_MINQUERY:    case OP_MINQUERY:
6293    allocate_stack(common, 1);    if (localptr == 0)
6294    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6295      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6296    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6297      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6298    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
6299    break;    break;
6300    
6301    case OP_EXACT:    case OP_EXACT:
6302    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6303    label = LABEL();    label = LABEL();
6304    compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6305    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);
6306    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);  
6307    break;    break;
6308    
6309    case OP_POSSTAR:    case OP_POSSTAR:
6310    case OP_POSPLUS:    case OP_POSPLUS:
6311    case OP_POSUPTO:    case OP_POSUPTO:
6312    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6313      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
6314    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6315        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6316      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6317    label = LABEL();    label = LABEL();
6318    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6319    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6320    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6321      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6322    else    else
6323      {      {
6324      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);
6325      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);  
6326      }      }
6327    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6328    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);  
6329    break;    break;
6330    
6331    case OP_POSQUERY:    case OP_POSQUERY:
6332    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6333    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
6334    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6335    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6336    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
6337    break;    break;
6338    
6339    default:    default:
# Line 5540  decrease_call_count(common); Line 6345  decrease_call_count(common);
6345  return end;  return end;
6346  }  }
6347    
6348  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_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6349  {  {
6350  DEFINE_COMPILER;  DEFINE_COMPILER;
6351  fallback_common *fallback;  backtrack_common *backtrack;
6352    
6353  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6354    
6355  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
6356    {    {
6357    add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6358    return cc + 1;    return cc + 1;
6359    }    }
6360    
# Line 5569  else Line 6374  else
6374    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);
6375  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6376  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));
6377  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));
6378  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));
6379  if (common->acceptlabel == NULL)  if (common->acceptlabel == NULL)
6380    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 6385  if (common->acceptlabel == NULL)
6385    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));
6386  else  else
6387    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
6388  add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6389  return cc + 1;  return cc + 1;
6390  }  }
6391    
6392  static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)
6393  {  {
6394  DEFINE_COMPILER;  DEFINE_COMPILER;
6395  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 5600  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 6405  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
6405  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
6406  }  }
6407    
6408  static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
6409  {  {
6410  DEFINE_COMPILER;  DEFINE_COMPILER;
6411  fallback_common *fallback;  backtrack_common *backtrack;
6412    
6413  while (cc < ccend)  while (cc < ccend)
6414    {    {
# Line 5639  while (cc < ccend) Line 6444  while (cc < ccend)
6444      case OP_NOT:      case OP_NOT:
6445      case OP_NOTI:      case OP_NOTI:
6446      case OP_REVERSE:      case OP_REVERSE:
6447      cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6448      break;      break;
6449    
6450      case OP_SET_SOM:      case OP_SET_SOM:
6451      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
6452      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6453      allocate_stack(common, 1);      allocate_stack(common, 1);
6454      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 6459  while (cc < ccend)
6459      case OP_CHAR:      case OP_CHAR:
6460      case OP_CHARI:      case OP_CHARI:
6461      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
6462        cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6463      else      else
6464        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6465      break;      break;
6466    
6467      case OP_STAR:      case OP_STAR:
# Line 5724  while (cc < ccend) Line 6529  while (cc < ccend)
6529      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
6530      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
6531      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6532      cc = compile_iterator_hotpath(common, cc, parent);      cc = compile_iterator_trypath(common, cc, parent);
6533      break;      break;
6534    
6535      case OP_CLASS:      case OP_CLASS:
6536      case OP_NCLASS:      case OP_NCLASS:
6537      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)
6538        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_trypath(common, cc, parent);
6539      else      else
6540        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6541      break;      break;
6542    
6543  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
6544      case OP_XCLASS:      case OP_XCLASS:
6545      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)
6546        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_trypath(common, cc, parent);
6547      else      else
6548        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
6549      break;      break;
6550  #endif  #endif
6551    
6552      case OP_REF:      case OP_REF:
6553      case OP_REFI:      case OP_REFI:
6554      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)
6555        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_trypath(common, cc, parent);
6556      else      else
6557        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);        cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
6558      break;      break;
6559    
6560      case OP_RECURSE:      case OP_RECURSE:
6561      cc = compile_recurse_hotpath(common, cc, parent);      cc = compile_recurse_trypath(common, cc, parent);
6562      break;      break;
6563    
6564      case OP_ASSERT:      case OP_ASSERT:
6565      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
6566      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6567      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6568      PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6569      cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6570      break;      break;
6571    
6572      case OP_BRAMINZERO:      case OP_BRAMINZERO:
6573      PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
6574      cc = bracketend(cc + 1);      cc = bracketend(cc + 1);
6575      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
6576        {        {
# Line 5778  while (cc < ccend) Line 6583  while (cc < ccend)
6583        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6584        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
6585        }        }
6586      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();
6587      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6588        decrease_call_count(common);        decrease_call_count(common);
6589      break;      break;
# Line 5791  while (cc < ccend) Line 6596  while (cc < ccend)
6596      case OP_SBRA:      case OP_SBRA:
6597      case OP_SCBRA:      case OP_SCBRA:
6598      case OP_SCOND:      case OP_SCOND:
6599      cc = compile_bracket_hotpath(common, cc, parent);      cc = compile_bracket_trypath(common, cc, parent);
6600      break;      break;
6601    
6602      case OP_BRAZERO:      case OP_BRAZERO:
6603      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
6604        cc = compile_bracket_hotpath(common, cc, parent);        cc = compile_bracket_trypath(common, cc, parent);
6605      else      else
6606        {        {
6607        PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
6608        cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
6609        }        }
6610      break;      break;
6611    
# Line 5809  while (cc < ccend) Line 6614  while (cc < ccend)
6614      case OP_SBRAPOS:      case OP_SBRAPOS:
6615      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6616      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6617      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_trypath(common, cc, parent);
6618      break;      break;
6619    
6620      case OP_MARK:      case OP_MARK:
6621      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
6622      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
6623      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);
6624      allocate_stack(common, 1);      allocate_stack(common, 1);
# Line 5826  while (cc < ccend) Line 6631  while (cc < ccend)
6631      break;      break;
6632    
6633      case OP_COMMIT:      case OP_COMMIT:
6634      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
6635      cc += 1;      cc += 1;
6636      break;      break;
6637    
6638      case OP_FAIL:      case OP_FAIL:
6639      case OP_ACCEPT:      case OP_ACCEPT:
6640      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6641      cc = compile_fail_accept_hotpath(common, cc, parent);      cc = compile_fail_accept_trypath(common, cc, parent);
6642      break;      break;
6643    
6644      case OP_CLOSE:      case OP_CLOSE:
6645      cc = compile_close_hotpath(common, cc);      cc = compile_close_trypath(common, cc);
6646      break;      break;
6647    
6648      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 5854  while (cc < ccend) Line 6659  while (cc < ccend)
6659  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
6660  }  }
6661    
6662  #undef PUSH_FALLBACK  #undef PUSH_BACKTRACK
6663  #undef PUSH_FALLBACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
6664  #undef FALLBACK_AS  #undef BACKTRACK_AS
6665    
6666  #define COMPILE_FALLBACKPATH(current) \  #define COMPILE_BACKTRACKPATH(current) \
6667    do \    do \
6668      { \      { \
6669      compile_fallbackpath(common, (current)); \      compile_backtrackpath(common, (current)); \
6670      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
6671        return; \        return; \
6672      } \      } \
# Line 5869  SLJIT_ASSERT(cc == ccend); Line 6674  SLJIT_ASSERT(cc == ccend);
6674    
6675  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
6676    
6677  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
6678  {  {
6679  DEFINE_COMPILER;  DEFINE_COMPILER;
6680  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5878  pcre_uchar type; Line 6683  pcre_uchar type;
6683  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
6684  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
6685  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6686    jump_list *jumplist = NULL;
6687    int localptr = PRIV_DATA(cc);
6688    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6689    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6690    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6691    
6692  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
6693    
# Line 5889  switch(opcode) Line 6699  switch(opcode)
6699    case OP_CRRANGE:    case OP_CRRANGE:
6700    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6701      {      {
6702      set_jumps(current->topfallbacks, LABEL());      SLJIT_ASSERT(localptr == 0);
6703        set_jumps(current->topbacktracks, LABEL());
6704      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6705      free_stack(common, 1);      free_stack(common, 1);
6706      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)->trypath);
6707      }      }
6708    else    else
6709      {      {
6710      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_UPTO)
6711        arg2 = 0;        arg2 = 0;
6712      else if (opcode == OP_PLUS)      if (opcode <= OP_PLUS)
6713        arg2 = 1;        {
6714      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6715      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        jump = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, base, offset1);
6716      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        }
6717        else
6718          {
6719          OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6720          OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6721          jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
6722          OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
6723          }
6724      skip_char_back(common);      skip_char_back(common);
6725      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6726      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6727      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6728        set_jumps(current->topfallbacks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6729      JUMPHERE(jump);      JUMPHERE(jump);
6730      free_stack(common, 2);      if (localptr == 0)
6731          free_stack(common, 2);
6732        if (opcode == OP_PLUS)
6733          set_jumps(current->topbacktracks, LABEL());
6734      }      }
6735    break;    break;
6736    
6737    case OP_MINSTAR:    case OP_MINSTAR:
6738    case OP_MINPLUS:    case OP_MINPLUS:
6739    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
6740      compile_char1_trypath(common, type, cc, &jumplist);
6741      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6742      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
6743      set_jumps(jumplist, LABEL());
6744      if (localptr == 0)
6745        free_stack(common, 1);
6746    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6747      {      set_jumps(current->topbacktracks, LABEL());
     set_jumps(current->topfallbacks, LABEL());  
     current->topfallbacks = NULL;  
     }  
   compile_char1_hotpath(common, type, cc, &current->topfallbacks);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
   JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);  
   set_jumps(current->topfallbacks, LABEL());  
   free_stack(common, 1);  
6748    break;    break;
6749    
6750    case OP_MINUPTO:    case OP_MINUPTO:
6751    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6752    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)