/[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 1002 by zherczeg, Tue Aug 14 09:31:00 2012 UTC
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 82  The code generator follows the recursive Line 85  The code generator follows the recursive
85  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
86  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
87  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
88  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
89    
90    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
91    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  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.
95  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  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
97  branches on the hot path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Hot path: match happens.     Matching path: match happens.
101     Fallback path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Hot path: no need to perform a match.     Matching path: no need to perform a match.
104     Fallback path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
107  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 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A hot path   A matching path
115   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B hot path   B matching path
117   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D hot path   D matching path
119   return with successful match   return with successful match
120    
121   D fallback path   D backtrack path
122   ')' 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")
123   B fallback path   B backtrack path
124   C expected path   C expected path
125   jump to D hot path   jump to D matching path
126   C fallback path   C backtrack path
127   A fallback path   A backtrack path
128    
129   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
130   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
131   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
132   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
133   the hot path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  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
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 181  typedef struct stub_list { Line 184  typedef struct stub_list {
184    enum stub_types type;    enum stub_types type;
185    int data;    int data;
186    struct sljit_jump *start;    struct sljit_jump *start;
187    struct sljit_label *leave;    struct sljit_label *quit;
188    struct stub_list *next;    struct stub_list *next;
189  } stub_list;  } stub_list;
190    
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct fallback_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
199    struct fallback_common *prev;    struct backtrack_common *prev;
200    jump_list *nextfallbacks;    jump_list *nextbacktracks;
201    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
202    struct fallback_common *top;    struct backtrack_common *top;
203    jump_list *topfallbacks;    jump_list *topbacktracks;
204    /* Opcode pointer. */    /* Opcode pointer. */
205    pcre_uchar *cc;    pcre_uchar *cc;
206  } fallback_common;  } backtrack_common;
207    
208  typedef struct assert_fallback {  typedef struct assert_backtrack {
209    fallback_common common;    backtrack_common common;
210    jump_list *condfailed;    jump_list *condfailed;
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
217  } assert_fallback;  } assert_backtrack;
218    
219  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
220    fallback_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
230      jump_list *condfailed;      jump_list *condfailed;
231      assert_fallback *assert;      assert_backtrack *assert;
232      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_fallback;  } bracket_backtrack;
238    
239  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
240    fallback_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
246    int stacksize;    int stacksize;
247  } bracketpos_fallback;  } bracketpos_backtrack;
248    
249  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
250    fallback_common common;    backtrack_common common;
251    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
252  } braminzero_fallback;  } braminzero_backtrack;
253    
254  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
255    fallback_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
258  } iterator_fallback;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
261    struct recurse_entry *next;    struct recurse_entry *next;
# Line 264  typedef struct recurse_entry { Line 267  typedef struct recurse_entry {
267    int start;    int start;
268  } recurse_entry;  } recurse_entry;
269    
270  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
271    fallback_common common;    backtrack_common common;
272  } recurse_fallback;  } recurse_backtrack;
273    
274    #define MAX_RANGE_SIZE 6
275    
276  typedef struct compiler_common {  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    
280    /* Local stack area size and variable pointers. */    /* Maps private data offset to each opcode. */
281    int localsize;    int *private_data_ptrs;
   int *localptrs;  
282    int cbraptr;    int cbraptr;
283    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
284    int ovector_start;    int ovector_start;
# Line 291  typedef struct compiler_common { Line 295  typedef struct compiler_common {
295    /* Points to the marked string. */    /* Points to the marked string. */
296    int mark_ptr;    int mark_ptr;
297    
298    /* Other  */    /* Flipped and lower case tables. */
299    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
300    sljit_w lcc;    sljit_w lcc;
301      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
302    int mode;    int mode;
303      /* Newline control. */
304    int nltype;    int nltype;
305    int newline;    int newline;
306    int bsr_nltype;    int bsr_nltype;
307      /* Dollar endonly. */
308    int endonly;    int endonly;
309    BOOL has_set_som;    BOOL has_set_som;
310      /* Tables. */
311    sljit_w ctypes;    sljit_w ctypes;
312      int digits[2 + MAX_RANGE_SIZE];
313      /* Named capturing brackets. */
314    sljit_uw name_table;    sljit_uw name_table;
315    sljit_w name_count;    sljit_w name_count;
316    sljit_w name_entry_size;    sljit_w name_entry_size;
317    
318    /* Labels and jump lists. */    /* Labels and jump lists. */
319    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
320    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
321    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
322    stub_list *stubs;    stub_list *stubs;
323    recurse_entry *entries;    recurse_entry *entries;
324    recurse_entry *currententry;    recurse_entry *currententry;
325    jump_list *partialmatch;    jump_list *partialmatch;
326    jump_list *leave;    jump_list *quit;
327    jump_list *accept;    jump_list *accept;
328    jump_list *calllimit;    jump_list *calllimit;
329    jump_list *stackalloc;    jump_list *stackalloc;
# Line 397  enum { Line 407  enum {
407  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
408  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
409    
410  /* Locals layout. */  /* Local space layout. */
411  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
412  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
413  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 413  the start pointers when the end of the c Line 423  the start pointers when the end of the c
423  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
424  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
425  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
426  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
427    
428  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
429  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
# Line 448  the start pointers when the end of the c Line 458  the start pointers when the end of the c
458    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))
459  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
460    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
461    #define GET_LOCAL_BASE(dst, dstw, offset) \
462      sljit_get_local_base(compiler, (dst), (dstw), (offset))
463    
464  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
465  {  {
# Line 460  return cc; Line 472  return cc;
472    
473  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
474   next_opcode   next_opcode
475   get_localspace   get_private_data_length
476   set_localptrs   set_private_data_ptrs
477   get_framesize   get_framesize
478   init_frame   init_frame
479   get_localsize   get_private_data_length_for_copy
480   copy_locals   copy_private_data
481   compile_hotpath   compile_matchingpath
482   compile_fallbackpath   compile_backtrackingpath
483  */  */
484    
485  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 678  switch(*cc)
678    }    }
679  }  }
680    
681  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
682        case OP_MINSTAR: \
683        case OP_MINPLUS: \
684        case OP_QUERY: \
685        case OP_MINQUERY: \
686        case OP_MINSTARI: \
687        case OP_MINPLUSI: \
688        case OP_QUERYI: \
689        case OP_MINQUERYI: \
690        case OP_NOTMINSTAR: \
691        case OP_NOTMINPLUS: \
692        case OP_NOTQUERY: \
693        case OP_NOTMINQUERY: \
694        case OP_NOTMINSTARI: \
695        case OP_NOTMINPLUSI: \
696        case OP_NOTQUERYI: \
697        case OP_NOTMINQUERYI:
698    
699    #define CASE_ITERATOR_PRIVATE_DATA_2A \
700        case OP_STAR: \
701        case OP_PLUS: \
702        case OP_STARI: \
703        case OP_PLUSI: \
704        case OP_NOTSTAR: \
705        case OP_NOTPLUS: \
706        case OP_NOTSTARI: \
707        case OP_NOTPLUSI:
708    
709    #define CASE_ITERATOR_PRIVATE_DATA_2B \
710        case OP_UPTO: \
711        case OP_MINUPTO: \
712        case OP_UPTOI: \
713        case OP_MINUPTOI: \
714        case OP_NOTUPTO: \
715        case OP_NOTMINUPTO: \
716        case OP_NOTUPTOI: \
717        case OP_NOTMINUPTOI:
718    
719    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
720        case OP_TYPEMINSTAR: \
721        case OP_TYPEMINPLUS: \
722        case OP_TYPEQUERY: \
723        case OP_TYPEMINQUERY:
724    
725    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
726        case OP_TYPESTAR: \
727        case OP_TYPEPLUS:
728    
729    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
730        case OP_TYPEUPTO: \
731        case OP_TYPEMINUPTO:
732    
733    static int get_class_iterator_size(pcre_uchar *cc)
734  {  {
735  int localspace = 0;  switch(*cc)
736      {
737      case OP_CRSTAR:
738      case OP_CRPLUS:
739      return 2;
740    
741      case OP_CRMINSTAR:
742      case OP_CRMINPLUS:
743      case OP_CRQUERY:
744      case OP_CRMINQUERY:
745      return 1;
746    
747      case OP_CRRANGE:
748      case OP_CRMINRANGE:
749      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
750        return 0;
751      return 2;
752    
753      default:
754      return 0;
755      }
756    }
757    
758    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
759    {
760    int private_data_length = 0;
761  pcre_uchar *alternative;  pcre_uchar *alternative;
762    pcre_uchar *end = NULL;
763    int space, size, bracketlen;
764    
765  /* 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. */
766  while (cc < ccend)  while (cc < ccend)
767    {    {
768      space = 0;
769      size = 0;
770      bracketlen = 0;
771    switch(*cc)    switch(*cc)
772      {      {
773      case OP_SET_SOM:      case OP_SET_SOM:
# Line 690  while (cc < ccend) Line 785  while (cc < ccend)
785      case OP_SBRA:      case OP_SBRA:
786      case OP_SBRAPOS:      case OP_SBRAPOS:
787      case OP_SCOND:      case OP_SCOND:
788      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
789      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
790      break;      break;
791    
792      case OP_CBRAPOS:      case OP_CBRAPOS:
793      case OP_SCBRAPOS:      case OP_SCBRAPOS:
794      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
795      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
796      break;      break;
797    
798      case OP_COND:      case OP_COND:
799      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
800      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
801      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
802        localspace += sizeof(sljit_w);        private_data_length += sizeof(sljit_w);
803      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
804        break;
805    
806        case OP_BRA:
807        bracketlen = 1 + LINK_SIZE;
808        break;
809    
810        case OP_CBRA:
811        case OP_SCBRA:
812        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
813      break;      break;
814    
815        CASE_ITERATOR_PRIVATE_DATA_1
816        space = 1;
817        size = -2;
818        break;
819    
820        CASE_ITERATOR_PRIVATE_DATA_2A
821        space = 2;
822        size = -2;
823        break;
824    
825        CASE_ITERATOR_PRIVATE_DATA_2B
826        space = 2;
827        size = -(2 + IMM2_SIZE);
828        break;
829    
830        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
831        space = 1;
832        size = 1;
833        break;
834    
835        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
836        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
837          space = 2;
838        size = 1;
839        break;
840    
841        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
842        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
843          space = 2;
844        size = 1 + IMM2_SIZE;
845        break;
846    
847        case OP_CLASS:
848        case OP_NCLASS:
849        size += 1 + 32 / sizeof(pcre_uchar);
850        space = get_class_iterator_size(cc + size);
851        break;
852    
853    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
854        case OP_XCLASS:
855        size = GET(cc, 1);
856        space = get_class_iterator_size(cc + size);
857        break;
858    #endif
859    
860      case OP_RECURSE:      case OP_RECURSE:
861      /* Set its value only once. */      /* Set its value only once. */
862      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 733  while (cc < ccend) Line 882  while (cc < ccend)
882        return -1;        return -1;
883      break;      break;
884      }      }
885    
886      if (space > 0 && cc >= end)
887        private_data_length += sizeof(sljit_w) * space;
888    
889      if (size != 0)
890        {
891        if (size < 0)
892          {
893          cc += -size;
894    #ifdef SUPPORT_UTF
895          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
896    #endif
897          }
898        else
899          cc += size;
900        }
901    
902      if (bracketlen > 0)
903        {
904        if (cc >= end)
905          {
906          end = bracketend(cc);
907          if (end[-1 - LINK_SIZE] == OP_KET)
908            end = NULL;
909          }
910        cc += bracketlen;
911        }
912    }    }
913  return localspace;  return private_data_length;
914  }  }
915    
916  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
917  {  {
918  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
919  pcre_uchar *alternative;  pcre_uchar *alternative;
920    pcre_uchar *end = NULL;
921    int space, size, bracketlen;
922    
923  while (cc < ccend)  while (cc < ccend)
924    {    {
925      space = 0;
926      size = 0;
927      bracketlen = 0;
928    switch(*cc)    switch(*cc)
929      {      {
930      case OP_ASSERT:      case OP_ASSERT:
# Line 755  while (cc < ccend) Line 937  while (cc < ccend)
937      case OP_SBRA:      case OP_SBRA:
938      case OP_SBRAPOS:      case OP_SBRAPOS:
939      case OP_SCOND:      case OP_SCOND:
940      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
941      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
942      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
943      break;      break;
944    
945      case OP_CBRAPOS:      case OP_CBRAPOS:
946      case OP_SCBRAPOS:      case OP_SCBRAPOS:
947      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
948      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
949      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
950      break;      break;
951    
952      case OP_COND:      case OP_COND:
# Line 772  while (cc < ccend) Line 954  while (cc < ccend)
954      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
955      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
956        {        {
957        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
958        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
959        }        }
960      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
961      break;      break;
962    
963        case OP_BRA:
964        bracketlen = 1 + LINK_SIZE;
965        break;
966    
967        case OP_CBRA:
968        case OP_SCBRA:
969        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
970        break;
971    
972        CASE_ITERATOR_PRIVATE_DATA_1
973        space = 1;
974        size = -2;
975        break;
976    
977        CASE_ITERATOR_PRIVATE_DATA_2A
978        space = 2;
979        size = -2;
980        break;
981    
982        CASE_ITERATOR_PRIVATE_DATA_2B
983        space = 2;
984        size = -(2 + IMM2_SIZE);
985        break;
986    
987        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
988        space = 1;
989        size = 1;
990        break;
991    
992        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
993        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
994          space = 2;
995        size = 1;
996        break;
997    
998        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
999        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1000          space = 2;
1001        size = 1 + IMM2_SIZE;
1002        break;
1003    
1004        case OP_CLASS:
1005        case OP_NCLASS:
1006        size += 1 + 32 / sizeof(pcre_uchar);
1007        space = get_class_iterator_size(cc + size);
1008        break;
1009    
1010    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1011        case OP_XCLASS:
1012        size = GET(cc, 1);
1013        space = get_class_iterator_size(cc + size);
1014        break;
1015    #endif
1016    
1017      default:      default:
1018      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1019      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1020      break;      break;
1021      }      }
1022    
1023      if (space > 0 && cc >= end)
1024        {
1025        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1026        private_data_ptr += sizeof(sljit_w) * space;
1027        }
1028    
1029      if (size != 0)
1030        {
1031        if (size < 0)
1032          {
1033          cc += -size;
1034    #ifdef SUPPORT_UTF
1035          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1036    #endif
1037          }
1038        else
1039          cc += size;
1040        }
1041    
1042      if (bracketlen > 0)
1043        {
1044        if (cc >= end)
1045          {
1046          end = bracketend(cc);
1047          if (end[-1 - LINK_SIZE] == OP_KET)
1048            end = NULL;
1049          }
1050        cc += bracketlen;
1051        }
1052    }    }
1053  }  }
1054    
# Line 959  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1225  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1225  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1226  }  }
1227    
1228  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1229  {  {
1230  int localsize = 2;  int private_data_length = 2;
1231    int size;
1232  pcre_uchar *alternative;  pcre_uchar *alternative;
1233  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1234  while (cc < ccend)  while (cc < ccend)
1235    {    {
1236      size = 0;
1237    switch(*cc)    switch(*cc)
1238      {      {
1239      case OP_ASSERT:      case OP_ASSERT:
# Line 978  while (cc < ccend) Line 1246  while (cc < ccend)
1246      case OP_SBRA:      case OP_SBRA:
1247      case OP_SBRAPOS:      case OP_SBRAPOS:
1248      case OP_SCOND:      case OP_SCOND:
1249      localsize++;      private_data_length++;
1250      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1251      break;      break;
1252    
1253      case OP_CBRA:      case OP_CBRA:
1254      case OP_SCBRA:      case OP_SCBRA:
1255      localsize++;      private_data_length++;
1256      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1257      break;      break;
1258    
1259      case OP_CBRAPOS:      case OP_CBRAPOS:
1260      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1261      localsize += 2;      private_data_length += 2;
1262      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1263      break;      break;
1264    
# Line 998  while (cc < ccend) Line 1266  while (cc < ccend)
1266      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1267      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1268      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1269        localsize++;        private_data_length++;
1270      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1271      break;      break;
1272    
1273        CASE_ITERATOR_PRIVATE_DATA_1
1274        if (PRIVATE_DATA(cc))
1275          private_data_length++;
1276        cc += 2;
1277    #ifdef SUPPORT_UTF
1278        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1279    #endif
1280        break;
1281    
1282        CASE_ITERATOR_PRIVATE_DATA_2A
1283        if (PRIVATE_DATA(cc))
1284          private_data_length += 2;
1285        cc += 2;
1286    #ifdef SUPPORT_UTF
1287        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1288    #endif
1289        break;
1290    
1291        CASE_ITERATOR_PRIVATE_DATA_2B
1292        if (PRIVATE_DATA(cc))
1293          private_data_length += 2;
1294        cc += 2 + IMM2_SIZE;
1295    #ifdef SUPPORT_UTF
1296        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1297    #endif
1298        break;
1299    
1300        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1301        if (PRIVATE_DATA(cc))
1302          private_data_length++;
1303        cc += 1;
1304        break;
1305    
1306        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1307        if (PRIVATE_DATA(cc))
1308          private_data_length += 2;
1309        cc += 1;
1310        break;
1311    
1312        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1313        if (PRIVATE_DATA(cc))
1314          private_data_length += 2;
1315        cc += 1 + IMM2_SIZE;
1316        break;
1317    
1318        case OP_CLASS:
1319        case OP_NCLASS:
1320    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1321        case OP_XCLASS:
1322        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1323    #else
1324        size = 1 + 32 / (int)sizeof(pcre_uchar);
1325    #endif
1326        if (PRIVATE_DATA(cc))
1327          private_data_length += get_class_iterator_size(cc + size);
1328        cc += size;
1329        break;
1330    
1331      default:      default:
1332      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1333      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1009  while (cc < ccend) Line 1335  while (cc < ccend)
1335      }      }
1336    }    }
1337  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1338  return localsize;  return private_data_length;
1339  }  }
1340    
1341  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1342    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1343  {  {
1344  DEFINE_COMPILER;  DEFINE_COMPILER;
1345  int srcw[2];  int srcw[2];
1346  int count;  int count, size;
1347  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1348  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1349  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1082  while (status != end) Line 1408  while (status != end)
1408        case OP_SBRAPOS:        case OP_SBRAPOS:
1409        case OP_SCOND:        case OP_SCOND:
1410        count = 1;        count = 1;
1411        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1412        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1413        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1414        break;        break;
# Line 1097  while (status != end) Line 1423  while (status != end)
1423        case OP_CBRAPOS:        case OP_CBRAPOS:
1424        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1425        count = 2;        count = 2;
1426        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1427        srcw[0] = PRIV_DATA(cc);        srcw[1] = PRIVATE_DATA(cc);
1428        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1429        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1430        break;        break;
# Line 1109  while (status != end) Line 1435  while (status != end)
1435        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1436          {          {
1437          count = 1;          count = 1;
1438          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1439          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1440          }          }
1441        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1442        break;        break;
1443    
1444          CASE_ITERATOR_PRIVATE_DATA_1
1445          if (PRIVATE_DATA(cc))
1446            {
1447            count = 1;
1448            srcw[0] = PRIVATE_DATA(cc);
1449            }
1450          cc += 2;
1451    #ifdef SUPPORT_UTF
1452          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1453    #endif
1454          break;
1455    
1456          CASE_ITERATOR_PRIVATE_DATA_2A
1457          if (PRIVATE_DATA(cc))
1458            {
1459            count = 2;
1460            srcw[0] = PRIVATE_DATA(cc);
1461            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1462            }
1463          cc += 2;
1464    #ifdef SUPPORT_UTF
1465          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1466    #endif
1467          break;
1468    
1469          CASE_ITERATOR_PRIVATE_DATA_2B
1470          if (PRIVATE_DATA(cc))
1471            {
1472            count = 2;
1473            srcw[0] = PRIVATE_DATA(cc);
1474            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1475            }
1476          cc += 2 + IMM2_SIZE;
1477    #ifdef SUPPORT_UTF
1478          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1479    #endif
1480          break;
1481    
1482          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1483          if (PRIVATE_DATA(cc))
1484            {
1485            count = 1;
1486            srcw[0] = PRIVATE_DATA(cc);
1487            }
1488          cc += 1;
1489          break;
1490    
1491          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1492          if (PRIVATE_DATA(cc))
1493            {
1494            count = 2;
1495            srcw[0] = PRIVATE_DATA(cc);
1496            srcw[1] = srcw[0] + sizeof(sljit_w);
1497            }
1498          cc += 1;
1499          break;
1500    
1501          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1502          if (PRIVATE_DATA(cc))
1503            {
1504            count = 2;
1505            srcw[0] = PRIVATE_DATA(cc);
1506            srcw[1] = srcw[0] + sizeof(sljit_w);
1507            }
1508          cc += 1 + IMM2_SIZE;
1509          break;
1510    
1511          case OP_CLASS:
1512          case OP_NCLASS:
1513    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1514          case OP_XCLASS:
1515          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1516    #else
1517          size = 1 + 32 / (int)sizeof(pcre_uchar);
1518    #endif
1519          if (PRIVATE_DATA(cc))
1520            switch(get_class_iterator_size(cc + size))
1521              {
1522              case 1:
1523              count = 1;
1524              srcw[0] = PRIVATE_DATA(cc);
1525              break;
1526    
1527              case 2:
1528              count = 2;
1529              srcw[0] = PRIVATE_DATA(cc);
1530              srcw[1] = srcw[0] + sizeof(sljit_w);
1531              break;
1532    
1533              default:
1534              SLJIT_ASSERT_STOP();
1535              break;
1536              }
1537          cc += size;
1538          break;
1539    
1540        default:        default:
1541        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1542        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1217  if (save) Line 1639  if (save)
1639  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1640  }  }
1641    
1642    #undef CASE_ITERATOR_PRIVATE_DATA_1
1643    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1644    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1645    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1646    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1647    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1648    
1649  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1650  {  {
1651  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1227  static SLJIT_INLINE void set_jumps(jump_ Line 1656  static SLJIT_INLINE void set_jumps(jump_
1656  while (list)  while (list)
1657    {    {
1658    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1659    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1660    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1661    list = list->next;    list = list->next;
1662    }    }
# Line 1254  if (list_item) Line 1683  if (list_item)
1683    list_item->type = type;    list_item->type = type;
1684    list_item->data = data;    list_item->data = data;
1685    list_item->start = start;    list_item->start = start;
1686    list_item->leave = LABEL();    list_item->quit = LABEL();
1687    list_item->next = common->stubs;    list_item->next = common->stubs;
1688    common->stubs = list_item;    common->stubs = list_item;
1689    }    }
# Line 1274  while (list_item) Line 1703  while (list_item)
1703      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1704      break;      break;
1705      }      }
1706    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1707    list_item = list_item->next;    list_item = list_item->next;
1708    }    }
1709  common->stubs = NULL;  common->stubs = NULL;
# Line 1325  if (length < 8) Line 1754  if (length < 8)
1754    }    }
1755  else  else
1756    {    {
1757    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));
1758    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1759    loop = LABEL();    loop = LABEL();
1760    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 1781  if (common->mark_ptr != 0)
1781    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);
1782  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));
1783  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));
1784  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1785  /* Unlikely, but possible */  /* Unlikely, but possible */
1786  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1787  loop = LABEL();  loop = LABEL();
# Line 1370  JUMPHERE(earlyexit); Line 1799  JUMPHERE(earlyexit);
1799  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1800  if (topbracket > 1)  if (topbracket > 1)
1801    {    {
1802    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));
1803    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1804    
1805    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
# Line 1384  else Line 1813  else
1813    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1814  }  }
1815    
1816  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)
1817  {  {
1818  DEFINE_COMPILER;  DEFINE_COMPILER;
1819    
# Line 1394  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1823  SLJIT_ASSERT(common->start_used_ptr != 0
1823  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1824  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1825  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));
1826  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1827    
1828  /* Store match begin and end. */  /* Store match begin and end. */
1829  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 1841  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1841  #endif  #endif
1842  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);
1843    
1844  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1845  }  }
1846    
1847  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 2050  JUMPHERE(jump);
2050  return return_value;  return return_value;
2051  }  }
2052    
2053  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2054  {  {
2055  DEFINE_COMPILER;  DEFINE_COMPILER;
2056  struct sljit_jump *jump;  struct sljit_jump *jump;
2057    
2058  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2059    {    {
2060    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));
2061    return;    return;
2062    }    }
2063    
2064  /* Partial matching mode. */  /* Partial matching mode. */
2065  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2066  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));
2067  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2068    {    {
2069    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);
2070    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2071    }    }
2072  else  else
2073    {    {
# Line 1788  if (common->utf) Line 2217  if (common->utf)
2217  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));
2218  }  }
2219    
2220  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)
2221  {  {
2222  /* 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. */
2223  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1796  DEFINE_COMPILER; Line 2225  DEFINE_COMPILER;
2225  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2226    {    {
2227    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2228    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));
2229    }    }
2230  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2231    {    {
# Line 1804  else if (nltype == NLTYPE_ANYCRLF) Line 2233  else if (nltype == NLTYPE_ANYCRLF)
2233    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2234    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);
2235    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2236    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));
2237    }    }
2238  else  else
2239    {    {
2240    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2241    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));
2242    }    }
2243  }  }
2244    
# Line 1823  of the character (>= 0xc0). Return char Line 2252  of the character (>= 0xc0). Return char
2252  DEFINE_COMPILER;  DEFINE_COMPILER;
2253  struct sljit_jump *jump;  struct sljit_jump *jump;
2254    
2255  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2256  /* Searching for the first zero. */  /* Searching for the first zero. */
2257  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);
2258  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1882  DEFINE_COMPILER; Line 2311  DEFINE_COMPILER;
2311  struct sljit_jump *jump;  struct sljit_jump *jump;
2312  struct sljit_jump *compare;  struct sljit_jump *compare;
2313    
2314  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2315    
2316  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);
2317  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1919  of the character (>= 0xd800). Return cha Line 2348  of the character (>= 0xd800). Return cha
2348  DEFINE_COMPILER;  DEFINE_COMPILER;
2349  struct sljit_jump *jump;  struct sljit_jump *jump;
2350    
2351  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2352  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2353  /* Do nothing, only return. */  /* Do nothing, only return. */
2354  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1956  DEFINE_COMPILER; Line 2385  DEFINE_COMPILER;
2385    
2386  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2387    
2388  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2389  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2390  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));
2391  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
# Line 1993  if (firstline) Line 2422  if (firstline)
2422    {    {
2423    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2424    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2425    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2426    
2427    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2428      {      {
# Line 2005  if (firstline) Line 2433  if (firstline)
2433      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2434      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2435      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2436        JUMPHERE(end);
2437      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2438      }      }
2439    else    else
# Line 2016  if (firstline) Line 2445  if (firstline)
2445      read_char(common);      read_char(common);
2446      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2447      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2448        JUMPHERE(end);
2449      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2450      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2451      }      }
2452    
2453    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2454    }    }
2455    
2456  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2041  if (newlinecheck) Line 2470  if (newlinecheck)
2470    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2471    }    }
2472    
2473  mainloop = LABEL();  mainloop = LABEL();
2474    
2475    /* Increasing the STR_PTR here requires one less jump in the most common case. */
2476    #ifdef SUPPORT_UTF
2477    if (common->utf) readuchar = TRUE;
2478    #endif
2479    if (newlinecheck) readuchar = TRUE;
2480    
2481    if (readuchar)
2482      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2483    
2484    if (newlinecheck)
2485      CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2486    
2487    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2488    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2489    if (common->utf)
2490      {
2491      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2492      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2493      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2494      JUMPHERE(singlechar);
2495      }
2496    #endif
2497    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2498    if (common->utf)
2499      {
2500      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2501      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2502      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2503      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2504      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2505      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2506      JUMPHERE(singlechar);
2507      }
2508    #endif
2509    JUMPHERE(start);
2510    
2511    if (newlinecheck)
2512      {
2513      JUMPHERE(end);
2514      JUMPHERE(nl);
2515      }
2516    
2517    return mainloop;
2518    }
2519    
2520    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2521    {
2522    DEFINE_COMPILER;
2523    struct sljit_label *start;
2524    struct sljit_jump *quit;
2525    struct sljit_jump *found;
2526    pcre_int32 chars[4];
2527    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2528    int location = 0;
2529    pcre_int32 len, c, bit, caseless;
2530    BOOL must_end;
2531    
2532    #ifdef COMPILE_PCRE8
2533    union {
2534        sljit_uh ascombined;
2535        sljit_ub asuchars[2];
2536    } pair;
2537    #else
2538    union {
2539        sljit_ui ascombined;
2540        sljit_uh asuchars[2];
2541    } pair;
2542    #endif
2543    
2544    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2545      return FALSE;
2546    
2547    while (TRUE)
2548      {
2549      caseless = 0;
2550      must_end = TRUE;
2551      switch(*cc)
2552        {
2553        case OP_CHAR:
2554        must_end = FALSE;
2555        cc++;
2556        break;
2557    
2558        case OP_CHARI:
2559        caseless = 1;
2560        must_end = FALSE;
2561        cc++;
2562        break;
2563    
2564        case OP_SOD:
2565        case OP_SOM:
2566        case OP_SET_SOM:
2567        case OP_NOT_WORD_BOUNDARY:
2568        case OP_WORD_BOUNDARY:
2569        case OP_EODN:
2570        case OP_EOD:
2571        case OP_CIRC:
2572        case OP_CIRCM:
2573        case OP_DOLL:
2574        case OP_DOLLM:
2575        /* Zero width assertions. */
2576        cc++;
2577        continue;
2578    
2579        case OP_PLUS:
2580        case OP_MINPLUS:
2581        case OP_POSPLUS:
2582        cc++;
2583        break;
2584    
2585        case OP_EXACT:
2586        cc += 1 + IMM2_SIZE;
2587        break;
2588    
2589        case OP_PLUSI:
2590        case OP_MINPLUSI:
2591        case OP_POSPLUSI:
2592        caseless = 1;
2593        cc++;
2594        break;
2595    
2596        case OP_EXACTI:
2597        caseless = 1;
2598        cc += 1 + IMM2_SIZE;
2599        break;
2600    
2601        default:
2602        return FALSE;
2603        }
2604    
2605      len = 1;
2606    #ifdef SUPPORT_UTF
2607      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2608    #endif
2609    
2610      if (caseless && char_has_othercase(common, cc))
2611        {
2612        caseless = char_get_othercase_bit(common, cc);
2613        if (caseless == 0)
2614          return FALSE;
2615    #ifdef COMPILE_PCRE8
2616        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2617    #else
2618        if ((caseless & 0x100) != 0)
2619          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2620        else
2621          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2622    #endif
2623        }
2624      else
2625        caseless = 0;
2626    
2627      while (len > 0 && location < 2 * 2)
2628        {
2629        c = *cc;
2630        bit = 0;
2631        if (len == (caseless & 0xff))
2632          {
2633          bit = caseless >> 8;
2634          c |= bit;
2635          }
2636    
2637        chars[location] = c;
2638        chars[location + 1] = bit;
2639    
2640        len--;
2641        location += 2;
2642        cc++;
2643        }
2644    
2645      if (location == 2 * 2)
2646        break;
2647      else if (must_end)
2648        return FALSE;
2649      }
2650    
2651    if (firstline)
2652      {
2653      SLJIT_ASSERT(common->first_line_end != 0);
2654      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2655      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2656      }
2657    else
2658      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2659    
2660  /* Increasing the STR_PTR here requires one less jump in the most common case. */  start = LABEL();
2661  #ifdef SUPPORT_UTF  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2662  if (common->utf) readuchar = TRUE;  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2663    #ifdef COMPILE_PCRE8
2664    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2665    #else /* COMPILE_PCRE8 */
2666    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2667  #endif  #endif
 if (newlinecheck) readuchar = TRUE;  
2668    
2669  if (readuchar)  #else /* SLJIT_UNALIGNED */
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
2670    
2671  if (newlinecheck)  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2672    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2673    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2674    #else /* SLJIT_BIG_ENDIAN */
2675    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2676    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2677    #endif /* SLJIT_BIG_ENDIAN */
2678    
2679  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #ifdef COMPILE_PCRE8
2680  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2681  if (common->utf)  #else /* COMPILE_PCRE8 */
2682    {  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);  
   }  
2683  #endif  #endif
2684  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2685  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);  
   }  
2686  #endif  #endif
 JUMPHERE(start);  
2687    
2688  if (newlinecheck)  if (chars[1] != 0 || chars[3] != 0)
2689    {    {
2690    JUMPHERE(end);    pair.asuchars[0] = chars[1];
2691    JUMPHERE(nl);    pair.asuchars[1] = chars[3];
2692      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2693    }    }
2694    
2695  return mainloop;  pair.asuchars[0] = chars[0];
2696    pair.asuchars[1] = chars[2];
2697    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2698    
2699    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2700    JUMPTO(SLJIT_JUMP, start);
2701    JUMPHERE(found);
2702    JUMPHERE(quit);
2703    
2704    if (firstline)
2705      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2706    else
2707      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2708    return TRUE;
2709  }  }
2710    
2711  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)
2712  {  {
2713  DEFINE_COMPILER;  DEFINE_COMPILER;
2714  struct sljit_label *start;  struct sljit_label *start;
2715  struct sljit_jump *leave;  struct sljit_jump *quit;
2716  struct sljit_jump *found;  struct sljit_jump *found;
2717  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2718    
2719  if (firstline)  if (firstline)
2720    {    {
2721    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2722      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2723    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2724    }    }
2725    
2726  start = LABEL();  start = LABEL();
2727  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2728  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2729    
2730  oc = first_char;  oc = first_char;
# Line 2136  else Line 2757  else
2757    }    }
2758    
2759  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  
2760  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2761  JUMPHERE(found);  JUMPHERE(found);
2762  JUMPHERE(leave);  JUMPHERE(quit);
2763    
2764  if (firstline)  if (firstline)
2765    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2766  }  }
2767    
2768  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2169  DEFINE_COMPILER; Line 2771  DEFINE_COMPILER;
2771  struct sljit_label *loop;  struct sljit_label *loop;
2772  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2773  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2774  struct sljit_jump *leave;  struct sljit_jump *quit;
2775  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2776  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2777  jump_list *newline = NULL;  jump_list *newline = NULL;
2778    
2779  if (firstline)  if (firstline)
2780    {    {
2781    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2782      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2783    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2784    }    }
2785    
# Line 2198  if (common->nltype == NLTYPE_FIXED && co Line 2801  if (common->nltype == NLTYPE_FIXED && co
2801    
2802    loop = LABEL();    loop = LABEL();
2803    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));
2804    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2805    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2806    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2807    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);
2808    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);
2809    
2810    JUMPHERE(leave);    JUMPHERE(quit);
2811    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2812    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2813    
# Line 2228  set_jumps(newline, loop); Line 2831  set_jumps(newline, loop);
2831    
2832  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2833    {    {
2834    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2835    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2836    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2837    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 2842  if (common->nltype == NLTYPE_ANY || comm
2842  #endif  #endif
2843    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2844    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2845    JUMPHERE(leave);    JUMPHERE(quit);
2846    }    }
2847  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2848  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2849    
2850  if (firstline)  if (firstline)
2851    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2852  }  }
2853    
2854  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2855  {  {
2856  DEFINE_COMPILER;  DEFINE_COMPILER;
2857  struct sljit_label *start;  struct sljit_label *start;
2858  struct sljit_jump *leave;  struct sljit_jump *quit;
2859  struct sljit_jump *found;  struct sljit_jump *found;
2860  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2861  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2260  struct sljit_jump *jump; Line 2863  struct sljit_jump *jump;
2863    
2864  if (firstline)  if (firstline)
2865    {    {
2866    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2867      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2868    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2869    }    }
2870    
2871  start = LABEL();  start = LABEL();
2872  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2873  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2874  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2875  if (common->utf)  if (common->utf)
# Line 2309  if (common->utf) Line 2913  if (common->utf)
2913  #endif  #endif
2914  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2915  JUMPHERE(found);  JUMPHERE(found);
2916  JUMPHERE(leave);  JUMPHERE(quit);
2917    
2918  if (firstline)  if (firstline)
2919    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2920  }  }
2921    
2922  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2384  DEFINE_COMPILER; Line 2988  DEFINE_COMPILER;
2988  struct sljit_jump *jump;  struct sljit_jump *jump;
2989  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2990    
2991  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2992  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2993    GET_LOCAL_BASE(TMP3, 0, 0);
2994    
2995  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2996  mainloop = LABEL();  mainloop = LABEL();
2997  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2998  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);
2999  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3000  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));
3001  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));
3002  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 3042  struct sljit_jump *jump;
3042    
3043  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3044    
3045  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);
3046  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3047  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3048  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 3140  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3140  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3141  }  }
3142    
3143    /*
3144      range format:
3145    
3146      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3147      ranges[1] = first bit (0 or 1)
3148      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3149    */
3150    
3151    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3152    {
3153    DEFINE_COMPILER;
3154    struct sljit_jump *jump;
3155    
3156    if (ranges[0] < 0)
3157      return FALSE;
3158    
3159    switch(ranges[0])
3160      {
3161      case 1:
3162      if (readch)
3163        read_char(common);
3164      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3165      return TRUE;
3166    
3167      case 2:
3168      if (readch)
3169        read_char(common);
3170      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3171      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3172      return TRUE;
3173    
3174      case 4:
3175      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3176        {
3177        if (readch)
3178          read_char(common);
3179        if (ranges[1] != 0)
3180          {
3181          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3182          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3183          }
3184        else
3185          {
3186          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3187          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3188          JUMPHERE(jump);
3189          }
3190        return TRUE;
3191        }
3192      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3193        {
3194        if (readch)
3195          read_char(common);
3196        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3197        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3198        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3199        return TRUE;
3200        }
3201      return FALSE;
3202    
3203      default:
3204      return FALSE;
3205      }
3206    }
3207    
3208    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3209    {
3210    int i, bit, length;
3211    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3212    
3213    bit = ctypes[0] & flag;
3214    ranges[0] = -1;
3215    ranges[1] = bit != 0 ? 1 : 0;
3216    length = 0;
3217    
3218    for (i = 1; i < 256; i++)
3219      if ((ctypes[i] & flag) != bit)
3220        {
3221        if (length >= MAX_RANGE_SIZE)
3222          return;
3223        ranges[2 + length] = i;
3224        length++;
3225        bit ^= flag;
3226        }
3227    
3228    if (bit != 0)
3229      {
3230      if (length >= MAX_RANGE_SIZE)
3231        return;
3232      ranges[2 + length] = 256;
3233      length++;
3234      }
3235    ranges[0] = length;
3236    }
3237    
3238    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3239    {
3240    int ranges[2 + MAX_RANGE_SIZE];
3241    pcre_uint8 bit, cbit, all;
3242    int i, byte, length = 0;
3243    
3244    bit = bits[0] & 0x1;
3245    ranges[1] = bit;
3246    /* Can be 0 or 255. */
3247    all = -bit;
3248    
3249    for (i = 0; i < 256; )
3250      {
3251      byte = i >> 3;
3252      if ((i & 0x7) == 0 && bits[byte] == all)
3253        i += 8;
3254      else
3255        {
3256        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3257        if (cbit != bit)
3258          {
3259          if (length >= MAX_RANGE_SIZE)
3260            return FALSE;
3261          ranges[2 + length] = i;
3262          length++;
3263          bit = cbit;
3264          all = -cbit;
3265          }
3266        i++;
3267        }
3268      }
3269    
3270    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3271      {
3272      if (length >= MAX_RANGE_SIZE)
3273        return FALSE;
3274      ranges[2 + length] = 256;
3275      length++;
3276      }
3277    ranges[0] = length;
3278    
3279    return check_ranges(common, ranges, backtracks, FALSE);
3280    }
3281    
3282  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3283  {  {
3284  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3285  DEFINE_COMPILER;  DEFINE_COMPILER;
3286    
3287  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3288    
3289  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3290  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 3311  static void check_hspace(compiler_common
3311  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3312  DEFINE_COMPILER;  DEFINE_COMPILER;
3313    
3314  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3315    
3316  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);
3317  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 3350  static void check_vspace(compiler_common
3350  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3351  DEFINE_COMPILER;  DEFINE_COMPILER;
3352    
3353  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3354    
3355  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3356  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 3382  DEFINE_COMPILER;
3382  struct sljit_jump *jump;  struct sljit_jump *jump;
3383  struct sljit_label *label;  struct sljit_label *label;
3384    
3385  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3386  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3387  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3388  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 3411  DEFINE_COMPILER;
3411  struct sljit_jump *jump;  struct sljit_jump *jump;
3412  struct sljit_label *label;  struct sljit_label *label;
3413    
3414  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3415  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3416    
3417  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2731  return src2; Line 3475  return src2;
3475  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3476    
3477  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,
3478      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3479  {  {
3480  DEFINE_COMPILER;  DEFINE_COMPILER;
3481  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2832  do Line 3576  do
3576        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3577        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3578          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);
3579        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));
3580        break;        break;
3581    
3582        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3583        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3584          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);
3585        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));
3586        break;        break;
3587    
3588  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3589        case 1:        case 1:
3590        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3591          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);
3592        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));
3593        break;        break;
3594  #endif  #endif
3595    
# Line 2871  do Line 3615  do
3615    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3616      {      {
3617      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3618      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));
3619      }      }
3620    else    else
3621      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));
3622    
3623  #endif  #endif
3624    
# Line 2910  return cc; Line 3654  return cc;
3654      } \      } \
3655    charoffset = (value);    charoffset = (value);
3656    
3657  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3658  {  {
3659  DEFINE_COMPILER;  DEFINE_COMPILER;
3660  jump_list *found = NULL;  jump_list *found = NULL;
3661  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3662  unsigned int c;  unsigned int c;
3663  int compares;  int compares;
3664  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2928  unsigned int typeoffset; Line 3672  unsigned int typeoffset;
3672  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3673  unsigned int charoffset;  unsigned int charoffset;
3674    
3675  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3676  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3677    detect_partial_match(common, backtracks);
3678  read_char(common);  read_char(common);
3679    
3680  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2942  if ((*cc++ & XCL_MAP) != 0) Line 3687  if ((*cc++ & XCL_MAP) != 0)
3687      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3688  #endif  #endif
3689    
3690    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3691    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3692    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3693    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3694    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);
3695    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3696        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3697        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3698        }
3699    
3700  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3701    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3080  typeoffset = 0; Line 3828  typeoffset = 0;
3828  while (*cc != XCL_END)  while (*cc != XCL_END)
3829    {    {
3830    compares--;    compares--;
3831    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3832    jump = NULL;    jump = NULL;
3833    
3834    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3162  while (*cc != XCL_END) Line 3910  while (*cc != XCL_END)
3910      switch(*cc)      switch(*cc)
3911        {        {
3912        case PT_ANY:        case PT_ANY:
3913        if (list != fallbacks)        if (list != backtracks)
3914          {          {
3915          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))
3916            continue;            continue;
# Line 3235  while (*cc != XCL_END) Line 3983  while (*cc != XCL_END)
3983  #endif  #endif
3984    
3985    if (jump != NULL)    if (jump != NULL)
3986      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3987    }    }
3988    
3989  if (found != NULL)  if (found != NULL)
# Line 3247  if (found != NULL) Line 3995  if (found != NULL)
3995    
3996  #endif  #endif
3997    
3998  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3999  {  {
4000  DEFINE_COMPILER;  DEFINE_COMPILER;
4001  int length;  int length;
# Line 3266  switch(type) Line 4014  switch(type)
4014    case OP_SOD:    case OP_SOD:
4015    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4016    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));
4017    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));
4018    return cc;    return cc;
4019    
4020    case OP_SOM:    case OP_SOM:
4021    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4022    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));
4023    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));
4024    return cc;    return cc;
4025    
4026    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4027    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4028    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4029    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));
4030    return cc;    return cc;
4031    
4032    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4033    case OP_DIGIT:    case OP_DIGIT:
4034    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4035    read_char8_type(common);    if (common->digits[0] == -2)
4036    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4037    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4038      /* Flip the starting bit in the negative case. */
4039      if (type == OP_NOT_DIGIT)
4040        common->digits[1] ^= 1;
4041      if (!check_ranges(common, common->digits, backtracks, TRUE))
4042        {
4043        read_char8_type(common);
4044        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4045        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4046        }
4047      if (type == OP_NOT_DIGIT)
4048        common->digits[1] ^= 1;
4049    return cc;    return cc;
4050    
4051    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4052    case OP_WHITESPACE:    case OP_WHITESPACE:
4053    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4054    read_char8_type(common);    read_char8_type(common);
4055    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);
4056    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));
4057    return cc;    return cc;
4058    
4059    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4060    case OP_WORDCHAR:    case OP_WORDCHAR:
4061    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4062    read_char8_type(common);    read_char8_type(common);
4063    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);
4064    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));
4065    return cc;    return cc;
4066    
4067    case OP_ANY:    case OP_ANY:
4068    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4069    read_char(common);    read_char(common);
4070    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4071      {      {
# Line 3317  switch(type) Line 4076  switch(type)
4076        jump[1] = check_str_end(common);        jump[1] = check_str_end(common);
4077    
4078      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4079      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));
4080      if (jump[1] != NULL)      if (jump[1] != NULL)
4081        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4082      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4083      }      }
4084    else    else
4085      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4086    return cc;    return cc;
4087    
4088    case OP_ALLANY:    case OP_ALLANY:
4089    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4090  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4091    if (common->utf)    if (common->utf)
4092      {      {
# Line 3355  switch(type) Line 4114  switch(type)
4114    return cc;    return cc;
4115    
4116    case OP_ANYBYTE:    case OP_ANYBYTE:
4117    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4118    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));
4119    return cc;    return cc;
4120    
# Line 3368  switch(type) Line 4127  switch(type)
4127    propdata[2] = cc[0];    propdata[2] = cc[0];
4128    propdata[3] = cc[1];    propdata[3] = cc[1];
4129    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4130    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4131    return cc + 2;    return cc + 2;
4132  #endif  #endif
4133  #endif  #endif
4134    
4135    case OP_ANYNL:    case OP_ANYNL:
4136    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4137    read_char(common);    read_char(common);
4138    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);
4139    /* 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 4146  switch(type)
4146    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));
4147    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4148    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4149    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4150    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4151    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4152    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3395  switch(type) Line 4154  switch(type)
4154    
4155    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4156    case OP_HSPACE:    case OP_HSPACE:
4157    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4158    read_char(common);    read_char(common);
4159    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4160    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));
4161    return cc;    return cc;
4162    
4163    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4164    case OP_VSPACE:    case OP_VSPACE:
4165    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4166    read_char(common);    read_char(common);
4167    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4168    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));
4169    return cc;    return cc;
4170    
4171  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4172    case OP_EXTUNI:    case OP_EXTUNI:
4173    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4174    read_char(common);    read_char(common);
4175    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4176    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
4177    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));
4178    
4179    label = LABEL();    label = LABEL();
4180    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 4204  switch(type)
4204      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));
4205      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4206      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4207        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));
4208      else      else
4209        {        {
4210        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 4212  switch(type)
4212        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4213        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);
4214        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);
4215        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4216        check_partial(common, TRUE);        check_partial(common, TRUE);
4217        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4218        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4219        }        }
4220      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4221      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));
4222      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));
4223      }      }
4224    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4225      {      {
4226      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));
4227      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4228      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));
4229      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));
4230      }      }
4231    else    else
4232      {      {
# Line 3476  switch(type) Line 4235  switch(type)
4235      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));
4236      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);
4237      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4238      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4239      /* Equal. */      /* Equal. */
4240      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4241      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4242      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4243    
4244      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4245      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4246        {        {
4247        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));
4248        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));
4249        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));
4250        }        }
4251      else      else
4252        {        {
4253        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4254        read_char(common);        read_char(common);
4255        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));
4256        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4257        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4258        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4259        }        }
4260      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
# Line 3506  switch(type) Line 4265  switch(type)
4265    return cc;    return cc;
4266    
4267    case OP_EOD:    case OP_EOD:
4268    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));
4269    check_partial(common, FALSE);    check_partial(common, FALSE);
4270    return cc;    return cc;
4271    
4272    case OP_CIRC:    case OP_CIRC:
4273    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4274    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));
4275    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));
4276    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));
4277    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));
4278    return cc;    return cc;
4279    
4280    case OP_CIRCM:    case OP_CIRCM:
# Line 3523  switch(type) Line 4282  switch(type)
4282    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));
4283    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4284    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));
4285    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));
4286    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4287    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4288    
4289    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));
4290    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4291      {      {
4292      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));
4293      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4294      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4295      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4296      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));
4297      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));
4298      }      }
4299    else    else
4300      {      {
4301      skip_char_back(common);      skip_char_back(common);
4302      read_char(common);      read_char(common);
4303      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4304      }      }
4305    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4306    return cc;    return cc;
# Line 3549  switch(type) Line 4308  switch(type)
4308    case OP_DOLL:    case OP_DOLL:
4309    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4310    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));
4311    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));
4312    
4313    if (!common->endonly)    if (!common->endonly)
4314      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4315    else    else
4316      {      {
4317      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));
4318      check_partial(common, FALSE);      check_partial(common, FALSE);
4319      }      }
4320    return cc;    return cc;
# Line 3564  switch(type) Line 4323  switch(type)
4323    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4324    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4325    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));
4326    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));
4327    check_partial(common, FALSE);    check_partial(common, FALSE);
4328    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4329    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3574  switch(type) Line 4333  switch(type)
4333      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));
4334      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4335      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4336        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));
4337      else      else
4338        {        {
4339        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4340        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
4341        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));
4342        check_partial(common, TRUE);        check_partial(common, TRUE);
4343        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4344        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4345        }        }
4346    
4347      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4348      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));
4349      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));
4350      }      }
4351    else    else
4352      {      {
4353      peek_char(common);      peek_char(common);
4354      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4355      }      }
4356    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4357    return cc;    return cc;
# Line 3606  switch(type) Line 4365  switch(type)
4365    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))
4366      {      {
4367      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));
4368      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));
4369    
4370      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4371      context.sourcereg = -1;      context.sourcereg = -1;
4372  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4373      context.ucharptr = 0;      context.ucharptr = 0;
4374  #endif  #endif
4375      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4376      }      }
4377    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4378    read_char(common);    read_char(common);
4379  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4380    if (common->utf)    if (common->utf)
# Line 3627  switch(type) Line 4386  switch(type)
4386      c = *cc;      c = *cc;
4387    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4388      {      {
4389      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));
4390      return cc + length;      return cc + length;
4391      }      }
4392    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 3635  switch(type) Line 4394  switch(type)
4394    if (ispowerof2(bit))    if (ispowerof2(bit))
4395      {      {
4396      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4397      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));
4398      return cc + length;      return cc + length;
4399      }      }
4400    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);
4401    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4402    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4403    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4404    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4405    return cc + length;    return cc + length;
4406    
4407    case OP_NOT:    case OP_NOT:
4408    case OP_NOTI:    case OP_NOTI:
4409    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4410    length = 1;    length = 1;
4411  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4412    if (common->utf)    if (common->utf)
# Line 3658  switch(type) Line 4417  switch(type)
4417        {        {
4418        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4419        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4420          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));
4421        else        else
4422          {          {
4423          /* 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. */
4424          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4425          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));
4426          }          }
4427        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4428        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 4447  switch(type)
4447      }      }
4448    
4449    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
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    else    else
4452      {      {
4453      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3696  switch(type) Line 4455  switch(type)
4455      if (ispowerof2(bit))      if (ispowerof2(bit))
4456        {        {
4457        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4458        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));
4459        }        }
4460      else      else
4461        {        {
4462        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));
4463        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));
4464        }        }
4465      }      }
4466    return cc + length;    return cc + length;
4467    
4468    case OP_CLASS:    case OP_CLASS:
4469    case OP_NCLASS:    case OP_NCLASS:
4470    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4471    read_char(common);    read_char(common);
4472      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4473        return cc + 32 / sizeof(pcre_uchar);
4474    
4475  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4476    jump[0] = NULL;    jump[0] = NULL;
4477  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3721  switch(type) Line 4483  switch(type)
4483      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4484      if (type == OP_CLASS)      if (type == OP_CLASS)
4485        {        {
4486        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4487        jump[0] = NULL;        jump[0] = NULL;
4488        }        }
4489      }      }
# Line 3731  switch(type) Line 4493  switch(type)
4493    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4494    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4495    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);
4496    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4497  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4498    if (jump[0] != NULL)    if (jump[0] != NULL)
4499      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3740  switch(type) Line 4502  switch(type)
4502    
4503  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4504    case OP_XCLASS:    case OP_XCLASS:
4505    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4506    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4507  #endif  #endif
4508    
4509    case OP_REVERSE:    case OP_REVERSE:
4510    length = GET(cc, 0);    length = GET(cc, 0);
4511    SLJIT_ASSERT(length > 0);    if (length == 0)
4512        return cc + LINK_SIZE;
4513    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4514  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4515    if (common->utf)    if (common->utf)
# Line 3754  switch(type) Line 4517  switch(type)
4517      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));
4518      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4519      label = LABEL();      label = LABEL();
4520      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));
4521      skip_char_back(common);      skip_char_back(common);
4522      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);
4523      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3764  switch(type) Line 4527  switch(type)
4527      {      {
4528      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));
4529      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));
4530      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));
4531      }      }
4532    check_start_used_ptr(common);    check_start_used_ptr(common);
4533    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3773  SLJIT_ASSERT_STOP(); Line 4536  SLJIT_ASSERT_STOP();
4536  return cc;  return cc;
4537  }  }
4538    
4539  static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4540  {  {
4541  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4542  /* 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 4588  if (context.length > 0)
4588    {    {
4589    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4590    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);
4591    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));
4592    
4593    context.sourcereg = -1;    context.sourcereg = -1;
4594  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4595    context.ucharptr = 0;    context.ucharptr = 0;
4596  #endif  #endif
4597    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);
4598    return cc;    return cc;
4599    }    }
4600    
4601  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4602  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4603  }  }
4604    
4605  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)
4606  {  {
4607  DEFINE_COMPILER;  DEFINE_COMPILER;
4608  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3847  int offset = GET2(cc, 1) << 1; Line 4610  int offset = GET2(cc, 1) << 1;
4610  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4611  if (!common->jscript_compat)  if (!common->jscript_compat)
4612    {    {
4613    if (fallbacks == NULL)    if (backtracks == NULL)
4614      {      {
4615      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4616      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 4619  if (!common->jscript_compat)
4619      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4620      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4621      }      }
4622    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)));
4623    }    }
4624  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));
4625  }  }
4626    
4627  /* Forward definitions. */  /* Forward definitions. */
4628  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4629  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4630    
4631  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4632    do \    do \
4633      { \      { \
4634      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4635      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4636        return error; \        return error; \
4637      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4638      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4639      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4640      parent->top = fallback; \      parent->top = backtrack; \
4641      } \      } \
4642    while (0)    while (0)
4643    
4644  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4645    do \    do \
4646      { \      { \
4647      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4648      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4649        return; \        return; \
4650      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4651      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4652      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4653      parent->top = fallback; \      parent->top = backtrack; \
4654      } \      } \
4655    while (0)    while (0)
4656    
4657  #define FALLBACK_AS(type) ((type *)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4658    
4659  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4660  {  {
4661  DEFINE_COMPILER;  DEFINE_COMPILER;
4662  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3904  struct sljit_jump *nopartial; Line 4667  struct sljit_jump *nopartial;
4667  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4668  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
4669  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4670    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)));
4671    
4672  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4673  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3921  if (common->utf && *cc == OP_REFI) Line 4684  if (common->utf && *cc == OP_REFI)
4684    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));
4685    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4686    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4687      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));
4688    else    else
4689      {      {
4690      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));
4691      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);
4692      check_partial(common, FALSE);      check_partial(common, FALSE);
4693      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4694      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4695      }      }
4696    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3942  else Line 4705  else
4705    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4706    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4707    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4708      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
4709    
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    
4713    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
4714      {      {
# Line 3957  else Line 4720  else
4720      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4721      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4722      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));
4723      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));
4724      JUMPHERE(partial);      JUMPHERE(partial);
4725      check_partial(common, FALSE);      check_partial(common, FALSE);
4726      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4727      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4728      }      }
4729    }    }
# Line 3968  else Line 4731  else
4731  if (jump != NULL)  if (jump != NULL)
4732    {    {
4733    if (emptyfail)    if (emptyfail)
4734      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4735    else    else
4736      JUMPHERE(jump);      JUMPHERE(jump);
4737    }    }
4738  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4739  }  }
4740    
4741  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4742  {  {
4743  DEFINE_COMPILER;  DEFINE_COMPILER;
4744  fallback_common *fallback;  backtrack_common *backtrack;
4745  pcre_uchar type;  pcre_uchar type;
4746  struct sljit_label *label;  struct sljit_label *label;
4747  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3987  pcre_uchar *ccbegin = cc; Line 4750  pcre_uchar *ccbegin = cc;
4750  int min = 0, max = 0;  int min = 0, max = 0;
4751  BOOL minimize;  BOOL minimize;
4752    
4753  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4754    
4755  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4756  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 4039  if (!minimize) Line 4802  if (!minimize)
4802      {      {
4803      allocate_stack(common, 1);      allocate_stack(common, 1);
4804      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4805      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4806      }      }
4807    
4808    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4809      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4810    
4811    label = LABEL();    label = LABEL();
4812    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4813    
4814    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4815      {      {
# Line 4074  if (!minimize) Line 4837  if (!minimize)
4837      }      }
4838    
4839    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4840    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4841    
4842    decrease_call_count(common);    decrease_call_count(common);
4843    return cc;    return cc;
# Line 4092  if (min == 0) Line 4855  if (min == 0)
4855    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4856    }    }
4857  else  else
4858    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4859    
4860  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4861  if (max > 0)  if (max > 0)
4862    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));
4863    
4864  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4865  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4866    
4867  if (min > 1)  if (min > 1)
# Line 4106  if (min > 1) Line 4869  if (min > 1)
4869    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4870    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4871    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4872    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->matchingpath);
4873    }    }
4874  else if (max > 0)  else if (max > 0)
4875    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 4882  decrease_call_count(common);
4882  return cc;  return cc;
4883  }  }
4884    
4885  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4886  {  {
4887  DEFINE_COMPILER;  DEFINE_COMPILER;
4888  fallback_common *fallback;  backtrack_common *backtrack;
4889  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4890  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4891  int start = GET(cc, 1);  int start = GET(cc, 1);
4892    
4893  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4894  while (entry != NULL)  while (entry != NULL)
4895    {    {
4896    if (entry->start == start)    if (entry->start == start)
# Line 4172  if (entry->entry == NULL) Line 4935  if (entry->entry == NULL)
4935  else  else
4936    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4937  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4938  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));
4939  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4940  }  }
4941    
4942  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4943  {  {
4944  DEFINE_COMPILER;  DEFINE_COMPILER;
4945  int framesize;  int framesize;
4946  int localptr;  int private_data_ptr;
4947  fallback_common altfallback;  backtrack_common altbacktrack;
4948  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4949  pcre_uchar opcode;  pcre_uchar opcode;
4950  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4951  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4952  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4953  jump_list **found;  jump_list **found;
4954  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4955  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
4956  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4957  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
4958  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
4959  struct sljit_jump *jump;  struct sljit_jump *jump;
4960  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4202  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4965  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4965    bra = *cc;    bra = *cc;
4966    cc++;    cc++;
4967    }    }
4968  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
4969  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
4970  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4971  fallback->framesize = framesize;  backtrack->framesize = framesize;
4972  fallback->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
4973  opcode = *cc;  opcode = *cc;
4974  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4975  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 4978  cc += GET(cc, 1);
4978    
4979  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4980    {    {
4981    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
4982    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4983    free_stack(common, 1);    free_stack(common, 1);
4984    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 4223  if (bra == OP_BRAMINZERO) Line 4986  if (bra == OP_BRAMINZERO)
4986    
4987  if (framesize < 0)  if (framesize < 0)
4988    {    {
4989    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
4990    allocate_stack(common, 1);    allocate_stack(common, 1);
4991    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4992    }    }
4993  else  else
4994    {    {
4995    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
4996    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
4997    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
4998    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
4999    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5000    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5001    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5002    }    }
5003    
5004  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5005  common->leavelabel = NULL;  common->quitlabel = NULL;
5006  common->leave = NULL;  common->quit = NULL;
5007  while (1)  while (1)
5008    {    {
5009    common->acceptlabel = NULL;    common->acceptlabel = NULL;
5010    common->accept = NULL;    common->accept = NULL;
5011    altfallback.top = NULL;    altbacktrack.top = NULL;
5012    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5013    
5014    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5015      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5016    
5017    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5018    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5019    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5020      {      {
5021      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5022      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5023      common->leave = save_leave;      common->quit = save_quit;
5024      common->accept = save_accept;      common->accept = save_accept;
5025      return NULL;      return NULL;
5026      }      }
# Line 4267  while (1) Line 5030  while (1)
5030    
5031    /* Reset stack. */    /* Reset stack. */
5032    if (framesize < 0)    if (framesize < 0)
5033      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5034    else {    else {
5035      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5036        {        {
5037        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5038        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5039        }        }
5040      else      else
5041        {        {
5042        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5043        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5044        }        }
5045    }    }
# Line 4294  while (1) Line 5057  while (1)
5057          {          {
5058          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5059          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
5060          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5061          }          }
5062        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5063        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 4302  while (1) Line 5065  while (1)
5065      else if (framesize >= 0)      else if (framesize >= 0)
5066        {        {
5067        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5068        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), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5069        }        }
5070      }      }
5071    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5072    
5073    compile_fallbackpath(common, altfallback.top);    compile_backtrackingpath(common, altbacktrack.top);
5074    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5075      {      {
5076      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5077      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5078      common->leave = save_leave;      common->quit = save_quit;
5079      common->accept = save_accept;      common->accept = save_accept;
5080      return NULL;      return NULL;
5081      }      }
5082    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5083    
5084    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5085      break;      break;
# Line 4325  while (1) Line 5088  while (1)
5088    cc += GET(cc, 1);    cc += GET(cc, 1);
5089    }    }
5090  /* None of them matched. */  /* None of them matched. */
5091  if (common->leave != NULL)  if (common->quit != NULL)
5092    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5093    
5094  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5095    {    {
# Line 4353  if (opcode == OP_ASSERT || opcode == OP_ Line 5116  if (opcode == OP_ASSERT || opcode == OP_
5116        }        }
5117      else      else
5118        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5119      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5120      }      }
5121    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5122    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4378  if (opcode == OP_ASSERT || opcode == OP_ Line 5141  if (opcode == OP_ASSERT || opcode == OP_
5141      {      {
5142      if (bra == OP_BRA)      if (bra == OP_BRA)
5143        {        {
5144        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5145        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5146        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5147        }        }
5148      else      else
5149        {        {
5150        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5151        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5152        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5153        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5154        }        }
# Line 4393  if (opcode == OP_ASSERT || opcode == OP_ Line 5156  if (opcode == OP_ASSERT || opcode == OP_
5156    
5157    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5158      {      {
5159      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5160      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->matchingpath);
5161      }      }
5162    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5163      {      {
5164      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5165      JUMPHERE(brajump);      JUMPHERE(brajump);
5166      if (framesize >= 0)      if (framesize >= 0)
5167        {        {
5168        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5169        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5170        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), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5171        }        }
5172      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5173      }      }
5174    }    }
5175  else  else
# Line 4432  else Line 5195  else
5195        }        }
5196      else      else
5197        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5198      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5199      }      }
5200    
5201    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5202      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5203    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5204      {      {
5205      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5206      JUMPHERE(brajump);      JUMPHERE(brajump);
5207      }      }
5208    
5209    if (bra != OP_BRA)    if (bra != OP_BRA)
5210      {      {
5211      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5212      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5213      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5214      }      }
5215    }    }
5216    
5217  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5218  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5219  common->leave = save_leave;  common->quit = save_quit;
5220  common->accept = save_accept;  common->accept = save_accept;
5221  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5222  }  }
# Line 4622  return condition; Line 5385  return condition;
5385                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5386  */  */
5387    
5388  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5389  {  {
5390  DEFINE_COMPILER;  DEFINE_COMPILER;
5391  fallback_common *fallback;  backtrack_common *backtrack;
5392  pcre_uchar opcode;  pcre_uchar opcode;
5393  int localptr = 0;  int private_data_ptr = 0;
5394  int offset = 0;  int offset = 0;
5395  int stacksize;  int stacksize;
5396  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5397  pcre_uchar *hotpath;  pcre_uchar *matchingpath;
5398  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5399  pcre_uchar ket;  pcre_uchar ket;
5400  assert_fallback *assert;  assert_backtrack *assert;
5401  BOOL has_alternatives;  BOOL has_alternatives;
5402  struct sljit_jump *jump;  struct sljit_jump *jump;
5403  struct sljit_jump *skip;  struct sljit_jump *skip;
5404  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
5405  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
5406    
5407  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5408    
5409  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5410    {    {
# Line 4652  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5415  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5415    
5416  opcode = *cc;  opcode = *cc;
5417  ccbegin = cc;  ccbegin = cc;
5418  hotpath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5419    
5420  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)
5421    {    {
5422    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
5423    parent->top = fallback->prev;    parent->top = backtrack->prev;
5424    return bracketend(cc);    return bracketend(cc);
5425    }    }
5426    
# Line 4669  cc += GET(cc, 1); Line 5432  cc += GET(cc, 1);
5432  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5433  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5434    {    {
5435    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5436    if (*hotpath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5437      {      {
5438      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5439      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5440        has_alternatives = FALSE;        has_alternatives = FALSE;
5441      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4691  if (opcode == OP_CBRA || opcode == OP_SC Line 5454  if (opcode == OP_CBRA || opcode == OP_SC
5454    {    {
5455    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5456    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5457    localptr = OVECTOR_PRIV(offset);    private_data_ptr = OVECTOR_PRIV(offset);
5458    offset <<= 1;    offset <<= 1;
5459    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5460    hotpath += IMM2_SIZE;    matchingpath += IMM2_SIZE;
5461    }    }
5462  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5463    {    {
5464    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5465    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5466    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5467    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5468    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5469      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5470    }    }
5471    
5472  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4728  if (bra == OP_BRAZERO) Line 5491  if (bra == OP_BRAZERO)
5491    
5492  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5493    {    {
5494    /* 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) */
5495    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5496    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
5497      {      {
# Line 4745  if (bra == OP_BRAMINZERO) Line 5508  if (bra == OP_BRAMINZERO)
5508        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
5509        JUMPHERE(jump);        JUMPHERE(jump);
5510        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5511        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5512          {          {
5513          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5514          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), private_data_ptr);
5515          }          }
5516        else        else
5517          {          {
5518          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5519          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5520          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));
5521          }          }
5522        JUMPHERE(skip);        JUMPHERE(skip);
5523        }        }
# Line 4768  if (bra == OP_BRAMINZERO) Line 5531  if (bra == OP_BRAMINZERO)
5531    }    }
5532    
5533  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5534    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5535    
5536  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5537    {    {
5538    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5539    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5540      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5541    }    }
5542    
5543  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
5544  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5545    {    {
5546    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5547      {      {
5548      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5549      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5550        {        {
5551        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5552        allocate_stack(common, 2);        allocate_stack(common, 2);
5553        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5554        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5555        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5556        }        }
5557      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5558        {        {
5559        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5560        allocate_stack(common, 1);        allocate_stack(common, 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        }        }
5563      else      else
5564        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5565      }      }
5566    else    else
5567      {      {
5568      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5569        {        {
5570        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5571        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5572        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));
5573        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5574        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5575        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5576        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);
5577        }        }
5578      else      else
5579        {        {
5580        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5581        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5582        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));
5583        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5584        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5585        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5586        }        }
5587      }      }
5588    }    }
# Line 4831  else if (opcode == OP_CBRA || opcode == Line 5594  else if (opcode == OP_CBRA || opcode ==
5594    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5595    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5596    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5597    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5598    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5599    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5600    }    }
5601  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5602    {    {
5603    /* Saving the previous value. */    /* Saving the previous value. */
5604    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5605    allocate_stack(common, 1);    allocate_stack(common, 1);
5606    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5607    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5608    }    }
5609  else if (has_alternatives)  else if (has_alternatives)
# Line 4853  else if (has_alternatives) Line 5616  else if (has_alternatives)
5616  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5617  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5618    {    {
5619    if (*hotpath == OP_CREF)    if (*matchingpath == OP_CREF)
5620      {      {
5621      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5622      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5623        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5624      hotpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5625      }      }
5626    else if (*hotpath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5627      {      {
5628      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5629      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5630      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));
5631    
5632      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5633      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);
5634      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);
5635      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)));
5636      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5637      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5638      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));
5639      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5640      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));
5641    
5642      JUMPHERE(jump);      JUMPHERE(jump);
5643      hotpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5644      }      }
5645    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5646      {      {
5647      /* Never has other case. */      /* Never has other case. */
5648      FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5649    
5650      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5651      if (common->currententry == NULL)      if (common->currententry == NULL)
5652        stacksize = 0;        stacksize = 0;
5653      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4894  if (opcode == OP_COND || opcode == OP_SC Line 5657  if (opcode == OP_COND || opcode == OP_SC
5657      else      else
5658        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5659    
5660      if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5661        {        {
5662        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5663        if (stacksize != 0)        if (stacksize != 0)
5664          hotpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5665        else        else
5666          {          {
5667          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5668            {            {
5669            hotpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5670            cc += GET(cc, 1);            cc += GET(cc, 1);
5671            }            }
5672          else          else
5673            hotpath = cc;            matchingpath = cc;
5674          }          }
5675        }        }
5676      else      else
5677        {        {
5678        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5679    
5680        stacksize = GET2(hotpath, 1);        stacksize = GET2(matchingpath, 1);
5681        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5682        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);
5683        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);
5684        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));
5685        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
5686        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5687        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5688        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));
5689        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5690        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));
5691        hotpath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5692        }        }
5693      }      }
5694    else    else
5695      {      {
5696      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5697      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5698      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5699      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5700        return NULL;        return NULL;
5701      memset(assert, 0, sizeof(assert_fallback));      memset(assert, 0, sizeof(assert_backtrack));
5702      assert->common.cc = hotpath;      assert->common.cc = matchingpath;
5703      FALLBACK_AS(bracket_fallback)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5704      hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5705      }      }
5706    }    }
5707    
5708  compile_hotpath(common, hotpath, cc, fallback);  compile_matchingpath(common, matchingpath, cc, backtrack);
5709  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5710    return NULL;    return NULL;
5711    
5712  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5713    {    {
5714    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5715      {      {
5716      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5717      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5718      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5719        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5720      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5721        {        {
5722        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5723        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5724        }        }
5725      }      }
5726    else    else
5727      {      {
5728      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5729      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), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5730      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5731        {        {
5732        /* 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 5761  if (has_alternatives)
5761    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5762      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5763    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5764      FALLBACK_AS(bracket_fallback)->althotpath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5765    }    }
5766    
5767  /* Must be after the hotpath label. */  /* Must be after the matchingpath label. */
5768  if (offset != 0)  if (offset != 0)
5769    {    {
5770    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5771    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5772    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5773    }    }
# Line 5014  if (ket == OP_KETRMAX) Line 5777  if (ket == OP_KETRMAX)
5777    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5778      {      {
5779      if (has_alternatives)      if (has_alternatives)
5780        FALLBACK_AS(bracket_fallback)->althotpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5781      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5782      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5783        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        {
5784          CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5785          /* Drop STR_PTR for greedy plus quantifier. */
5786          if (bra != OP_BRAZERO)
5787            free_stack(common, 1);
5788          }
5789      else      else
5790        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5791        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5792      }      }
5793    else    else
5794      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5795    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5796    }    }
5797    
5798  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5799    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5800    
5801  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5802    {    {
5803    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5804    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5805    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5806      {      {
5807      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5808      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5809      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5810      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5811      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5812        {        {
5813        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5814        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5815        }        }
5816      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5817        free_stack(common, 1);        free_stack(common, 1);
5818      }      }
5819    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5820    }    }
5821    
5822  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 5829  cc += 1 + LINK_SIZE;
5829  return cc;  return cc;
5830  }  }
5831    
5832  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5833  {  {
5834  DEFINE_COMPILER;  DEFINE_COMPILER;
5835  fallback_common *fallback;  backtrack_common *backtrack;
5836  pcre_uchar opcode;  pcre_uchar opcode;
5837  int localptr;  int private_data_ptr;
5838  int cbraprivptr = 0;  int cbraprivptr = 0;
5839  int framesize;  int framesize;
5840  int stacksize;  int stacksize;
# Line 5077  int stack; Line 5845  int stack;
5845  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5846  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5847    
5848  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5849  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5850    {    {
5851    zero = TRUE;    zero = TRUE;
# Line 5085  if (*cc == OP_BRAPOSZERO) Line 5853  if (*cc == OP_BRAPOSZERO)
5853    }    }
5854    
5855  opcode = *cc;  opcode = *cc;
5856  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5857  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5858  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5859  switch(opcode)  switch(opcode)
5860    {    {
5861    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5109  switch(opcode) Line 5877  switch(opcode)
5877    }    }
5878    
5879  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5880  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5881  if (framesize < 0)  if (framesize < 0)
5882    {    {
5883    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5884    if (!zero)    if (!zero)
5885      stacksize++;      stacksize++;
5886    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5887    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5888    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5889    
5890    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5891      {      {
# Line 5139  else Line 5907  else
5907      stacksize++;      stacksize++;
5908    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5909      stacksize++;      stacksize++;
5910    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5911    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5912    
5913    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5914    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
5915    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5916    stack = 0;    stack = 0;
5917    if (!zero)    if (!zero)
5918      {      {
# Line 5166  if (opcode == OP_CBRAPOS || opcode == OP Line 5934  if (opcode == OP_CBRAPOS || opcode == OP
5934  loop = LABEL();  loop = LABEL();
5935  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
5936    {    {
5937    fallback->top = NULL;    backtrack->top = NULL;
5938    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
5939    cc += GET(cc, 1);    cc += GET(cc, 1);
5940    
5941    compile_hotpath(common, ccbegin, cc, fallback);    compile_matchingpath(common, ccbegin, cc, backtrack);
5942    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5943      return NULL;      return NULL;
5944    
5945    if (framesize < 0)    if (framesize < 0)
5946      {      {
5947      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5948    
5949      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5950        {        {
# Line 5202  while (*cc != OP_KETRPOS) Line 5970  while (*cc != OP_KETRPOS)
5970      {      {
5971      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5972        {        {
5973        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
5974        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
5975        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5976        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5210  while (*cc != OP_KETRPOS) Line 5978  while (*cc != OP_KETRPOS)
5978        }        }
5979      else      else
5980        {        {
5981        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5982        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
5983        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
5984          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
# Line 5231  while (*cc != OP_KETRPOS) Line 5999  while (*cc != OP_KETRPOS)
5999    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6000    flush_stubs(common);    flush_stubs(common);
6001    
6002    compile_fallbackpath(common, fallback->top);    compile_backtrackingpath(common, backtrack->top);
6003    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6004      return NULL;      return NULL;
6005    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
6006    
6007    if (framesize < 0)    if (framesize < 0)
6008      {      {
# Line 5249  while (*cc != OP_KETRPOS) Line 6017  while (*cc != OP_KETRPOS)
6017        {        {
6018        /* Last alternative. */        /* Last alternative. */
6019        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6020          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6021        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6022        }        }
6023      else      else
6024        {        {
6025        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6026        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6027        }        }
6028      }      }
# Line 5264  while (*cc != OP_KETRPOS) Line 6032  while (*cc != OP_KETRPOS)
6032    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6033    }    }
6034    
6035  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
6036  if (!zero)  if (!zero)
6037    {    {
6038    if (framesize < 0)    if (framesize < 0)
6039      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));
6040    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6041      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));
6042    }    }
6043    
6044  /* None of them matched. */  /* None of them matched. */
# Line 5371  if (end != NULL) Line 6139  if (end != NULL)
6139  return cc;  return cc;
6140  }  }
6141    
6142  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6143  {  {
6144  DEFINE_COMPILER;  DEFINE_COMPILER;
6145  fallback_common *fallback;  backtrack_common *backtrack;
6146  pcre_uchar opcode;  pcre_uchar opcode;
6147  pcre_uchar type;  pcre_uchar type;
6148  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 5382  pcre_uchar* end; Line 6150  pcre_uchar* end;
6150  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6151  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6152  struct sljit_label *label;  struct sljit_label *label;
6153    int private_data_ptr = PRIVATE_DATA(cc);
6154    int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6155    int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6156    int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6157    int tmp_base, tmp_offset;
6158    
6159  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6160    
6161  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6162    
6163    switch (type)
6164      {
6165      case OP_NOT_DIGIT:
6166      case OP_DIGIT:
6167      case OP_NOT_WHITESPACE:
6168      case OP_WHITESPACE:
6169      case OP_NOT_WORDCHAR:
6170      case OP_WORDCHAR:
6171      case OP_ANY:
6172      case OP_ALLANY:
6173      case OP_ANYBYTE:
6174      case OP_ANYNL:
6175      case OP_NOT_HSPACE:
6176      case OP_HSPACE:
6177      case OP_NOT_VSPACE:
6178      case OP_VSPACE:
6179      case OP_CHAR:
6180      case OP_CHARI:
6181      case OP_NOT:
6182      case OP_NOTI:
6183      case OP_CLASS:
6184      case OP_NCLASS:
6185      tmp_base = TMP3;
6186      tmp_offset = 0;
6187      break;
6188    
6189      default:
6190      SLJIT_ASSERT_STOP();
6191      /* Fall through. */
6192    
6193      case OP_EXTUNI:
6194      case OP_XCLASS:
6195      case OP_NOTPROP:
6196      case OP_PROP:
6197      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6198      tmp_offset = POSSESSIVE0;
6199      break;
6200      }
6201    
6202  switch(opcode)  switch(opcode)
6203    {    {
6204    case OP_STAR:    case OP_STAR:
# Line 5395  switch(opcode) Line 6207  switch(opcode)
6207    case OP_CRRANGE:    case OP_CRRANGE:
6208    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6209      {      {
6210        SLJIT_ASSERT(private_data_ptr == 0);
6211      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6212        {        {
6213        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5406  switch(opcode) Line 6219  switch(opcode)
6219        allocate_stack(common, 1);        allocate_stack(common, 1);
6220        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6221        }        }
6222    
6223      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6224        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6225    
6226      label = LABEL();      label = LABEL();
6227      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6228      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6229        {        {
6230        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 6236  switch(opcode)
6236        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6237        }        }
6238    
6239        /* We cannot use TMP3 because of this allocate_stack. */
6240      allocate_stack(common, 1);      allocate_stack(common, 1);
6241      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6242      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5430  switch(opcode) Line 6245  switch(opcode)
6245      }      }
6246    else    else
6247      {      {
6248      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6249      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6250      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (private_data_ptr == 0)
6251          allocate_stack(common, 2);
6252        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6253        if (opcode <= OP_PLUS)
6254          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6255        else
6256          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6257      label = LABEL();      label = LABEL();
6258      compile_char1_hotpath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6259      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6260      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6261          JUMPTO(SLJIT_JUMP, label);
6262        else if (opcode == OP_CRRANGE && arg1 == 0)
6263        {        {
6264        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);
6265        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6266        }        }
6267      else      else
6268        {        {
6269        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6270        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6271        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6272        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6273        }        }
6274      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6275      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6276        add_jump(compiler, &fallback->topfallbacks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6277          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));  
6278      }      }
6279    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6280    break;    break;
6281    
6282    case OP_MINSTAR:    case OP_MINSTAR:
6283    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6284    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6285      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6286    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    if (private_data_ptr == 0)
6287        allocate_stack(common, 1);
6288      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6289