/[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 850 by zherczeg, Wed Jan 4 17:29:11 2012 UTC revision 970 by zherczeg, Sun May 27 05:28:19 2012 UTC
# Line 82  The code generator follows the recursive Line 82  The code generator follows the recursive
82  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
83  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
84  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
85  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
86    
87    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
88    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
92  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the try path (expected path), and the other is called as
93  the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94  branches on the hot path.  branches on the try path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Hot path: match happens.     Try path: match happens.
98     Fallback path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Hot path: no need to perform a match.     Try path: no need to perform a match.
101     Fallback path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
104  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# Line 108  we have the following regular expression Line 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A hot path   A try path
112   '(' hot path (pushing arguments to the stack)   '(' try path (pushing arguments to the stack)
113   B hot path   B try path
114   ')' hot path (pushing arguments to the stack)   ')' try path (pushing arguments to the stack)
115   D hot path   D try path
116   return with successful match   return with successful match
117    
118   D fallback path   D backtrack path
119   ')' fallback path (If we arrived from "C" jump to the fallback of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120   B fallback path   B backtrack path
121   C expected path   C expected path
122   jump to D hot path   jump to D try path
123   C fallback path   C backtrack path
124   A fallback path   A backtrack path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of backtrack code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
129   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
130   the hot path eventually. Otherwise it needs to clear out its own stack   the try path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
134  /*  /*
135  Saved stack frames:  Saved stack frames:
136    
137  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of local variables
138  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the locals
139  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
140  mechanism.  mechanism.
141    
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    const pcre_uchar *begin;    const pcre_uchar *begin;
153    const pcre_uchar *end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    pcre_uchar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
# Line 162  typedef struct jit_arguments { Line 163  typedef struct jit_arguments {
163    pcre_uint8 notempty_atstart;    pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    pcre_jit_callback callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171  } executable_function;  } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 187  typedef struct stub_list { Line 188  typedef struct stub_list {
188  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189    
190  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
191  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_trypath, and contains
192  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackpath. Must be the first member
193  of its descendants. */  of its descendants. */
194  typedef struct fallback_common {  typedef struct backtrack_common {
195    /* Concatenation stack. */    /* Concatenation stack. */
196    struct fallback_common *prev;    struct backtrack_common *prev;
197    jump_list *nextfallbacks;    jump_list *nextbacktracks;
198    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
199    struct fallback_common *top;    struct backtrack_common *top;
200    jump_list *topfallbacks;    jump_list *topbacktracks;
201    /* Opcode pointer. */    /* Opcode pointer. */
202    pcre_uchar *cc;    pcre_uchar *cc;
203  } fallback_common;  } backtrack_common;
204    
205  typedef struct assert_fallback {  typedef struct assert_backtrack {
206    fallback_common common;    backtrack_common common;
207    jump_list *condfailed;    jump_list *condfailed;
208    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
209    int framesize;    int framesize;
210    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
211    int localptr;    int localptr;
212    /* For iterators. */    /* For iterators. */
213    struct sljit_label *hotpath;    struct sljit_label *trypath;
214  } assert_fallback;  } assert_backtrack;
215    
216  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
217    fallback_common common;    backtrack_common common;
218    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
219    struct sljit_label *althotpath;    struct sljit_label *alttrypath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivehotpath;    struct sljit_label *recursivetrypath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerohotpath;    struct sljit_label *zerotrypath;
224    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
225    union {    union {
226      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
227      jump_list *condfailed;      jump_list *condfailed;
228      assert_fallback *assert;      assert_backtrack *assert;
229      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
230      int framesize;      int framesize;
231    } u;    } u;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int localptr;    int localptr;
234  } bracket_fallback;  } bracket_backtrack;
235    
236  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
237    fallback_common common;    backtrack_common common;
238    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
239    int localptr;    int localptr;
240    /* Reverting stack is needed. */    /* Reverting stack is needed. */
241    int framesize;    int framesize;
242    /* Allocated stack size. */    /* Allocated stack size. */
243    int stacksize;    int stacksize;
244  } bracketpos_fallback;  } bracketpos_backtrack;
245    
246  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
247    fallback_common common;    backtrack_common common;
248    struct sljit_label *hotpath;    struct sljit_label *trypath;
249  } braminzero_fallback;  } braminzero_backtrack;
250    
251  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
252    fallback_common common;    backtrack_common common;
253    /* Next iteration. */    /* Next iteration. */
254    struct sljit_label *hotpath;    struct sljit_label *trypath;
255  } iterator_fallback;  } iterator_backtrack;
256    
257  typedef struct recurse_entry {  typedef struct recurse_entry {
258    struct recurse_entry *next;    struct recurse_entry *next;
# Line 263  typedef struct recurse_entry { Line 264  typedef struct recurse_entry {
264    int start;    int start;
265  } recurse_entry;  } recurse_entry;
266    
267  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
268    fallback_common common;    backtrack_common common;
269  } recurse_fallback;  } recurse_backtrack;
270    
271  typedef struct compiler_common {  typedef struct compiler_common {
272    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
273    pcre_uchar *start;    pcre_uchar *start;
274    int localsize;  
275      /* Opcode local area direct map. */
276    int *localptrs;    int *localptrs;
277      int cbraptr;
278      /* OVector starting point. Must be divisible by 2. */
279      int ovector_start;
280      /* Last known position of the requested byte. */
281      int req_char_ptr;
282      /* Head of the last recursion. */
283      int recursive_head;
284      /* First inspected character for partial matching. */
285      int start_used_ptr;
286      /* Starting pointer for partial soft matches. */
287      int hit_start;
288      /* End pointer of the first line. */
289      int first_line_end;
290      /* Points to the marked string. */
291      int mark_ptr;
292    
293      /* Other  */
294    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
295    sljit_w lcc;    sljit_w lcc;
296    int cbraptr;    int mode;
297    int nltype;    int nltype;
298    int newline;    int newline;
299    int bsr_nltype;    int bsr_nltype;
300    int endonly;    int endonly;
301      BOOL has_set_som;
302    sljit_w ctypes;    sljit_w ctypes;
303    sljit_uw name_table;    sljit_uw name_table;
304    sljit_w name_count;    sljit_w name_count;
305    sljit_w name_entry_size;    sljit_w name_entry_size;
306    
307      /* Labels and jump lists. */
308      struct sljit_label *partialmatchlabel;
309      struct sljit_label *leavelabel;
310    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
311    stub_list *stubs;    stub_list *stubs;
312    recurse_entry *entries;    recurse_entry *entries;
313    recurse_entry *currententry;    recurse_entry *currententry;
314      jump_list *partialmatch;
315      jump_list *leave;
316    jump_list *accept;    jump_list *accept;
317    jump_list *calllimit;    jump_list *calllimit;
318    jump_list *stackalloc;    jump_list *stackalloc;
# Line 349  typedef struct compare_context { Line 375  typedef struct compare_context {
375    
376  enum {  enum {
377    frame_end = 0,    frame_end = 0,
378    frame_setstrbegin = -1    frame_setstrbegin = -1,
379      frame_setmark = -2
380  };  };
381    
382    /* Undefine sljit macros. */
383    #undef CMP
384    
385  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
386  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
387    
388  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
389  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
390  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
391  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
392  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
393  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
394  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
395  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
396  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
397  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
398    
399  /* Locals layout. */  /* Locals layout. */
# Line 373  enum { Line 403  enum {
403  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
404  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
405  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
406  /* Max limit of recursions. */  /* Max limit of recursions. */
407  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
408  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
409  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
410  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
411  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
412  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
413  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
414  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
415  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
# Line 423  the start pointers when the end of the c Line 447  the start pointers when the end of the c
447    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))
448  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
449    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
450    #define GET_LOCAL_BASE(dst, dstw, offset) \
451      sljit_get_local_base(compiler, (dst), (dstw), (offset))
452    
453  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
454  {  {
# Line 441  return cc; Line 467  return cc;
467   init_frame   init_frame
468   get_localsize   get_localsize
469   copy_locals   copy_locals
470   compile_hotpath   compile_trypath
471   compile_fallbackpath   compile_backtrackpath
472  */  */
473    
474  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 494  switch(*cc) Line 520  switch(*cc)
520    case OP_BRAZERO:    case OP_BRAZERO:
521    case OP_BRAMINZERO:    case OP_BRAMINZERO:
522    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
523      case OP_COMMIT:
524    case OP_FAIL:    case OP_FAIL:
525    case OP_ACCEPT:    case OP_ACCEPT:
526    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 632  switch(*cc) Line 659  switch(*cc)
659    case OP_SCBRAPOS:    case OP_SCBRAPOS:
660    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
661    
662      case OP_MARK:
663      return cc + 1 + 2 + cc[1];
664    
665    default:    default:
666    return NULL;    return NULL;
667    }    }
# Line 646  while (cc < ccend) Line 676  while (cc < ccend)
676    {    {
677    switch(*cc)    switch(*cc)
678      {      {
679        case OP_SET_SOM:
680        common->has_set_som = TRUE;
681        cc += 1;
682        break;
683    
684      case OP_ASSERT:      case OP_ASSERT:
685      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
686      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 674  while (cc < ccend) Line 709  while (cc < ccend)
709      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
710      break;      break;
711    
712        case OP_RECURSE:
713        /* Set its value only once. */
714        if (common->recursive_head == 0)
715          {
716          common->recursive_head = common->ovector_start;
717          common->ovector_start += sizeof(sljit_w);
718          }
719        cc += 1 + LINK_SIZE;
720        break;
721    
722        case OP_MARK:
723        if (common->mark_ptr == 0)
724          {
725          common->mark_ptr = common->ovector_start;
726          common->ovector_start += sizeof(sljit_w);
727          }
728        cc += 1 + 2 + cc[1];
729        break;
730    
731      default:      default:
732      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
733      if (cc == NULL)      if (cc == NULL)
# Line 739  static int get_framesize(compiler_common Line 793  static int get_framesize(compiler_common
793  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
794  int length = 0;  int length = 0;
795  BOOL possessive = FALSE;  BOOL possessive = FALSE;
796  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
797    BOOL setmark_found = recursive;
798    
799  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
800    {    {
# Line 753  while (cc < ccend) Line 808  while (cc < ccend)
808    switch(*cc)    switch(*cc)
809      {      {
810      case OP_SET_SOM:      case OP_SET_SOM:
811      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
812      if (!setsom_found)      if (!setsom_found)
813        {        {
814        length += 2;        length += 2;
815        setsom_found = TRUE;        setsom_found = TRUE;
816        }        }
817      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
818        break;
819    
820        case OP_MARK:
821        SLJIT_ASSERT(common->mark_ptr != 0);
822        if (!setmark_found)
823          {
824          length += 2;
825          setmark_found = TRUE;
826          }
827        cc += 1 + 2 + cc[1];
828        break;
829    
830        case OP_RECURSE:
831        if (common->has_set_som && !setsom_found)
832          {
833          length += 2;
834          setsom_found = TRUE;
835          }
836        if (common->mark_ptr != 0 && !setmark_found)
837          {
838          length += 2;
839          setmark_found = TRUE;
840          }
841        cc += 1 + LINK_SIZE;
842      break;      break;
843    
844      case OP_CBRA:      case OP_CBRA:
# Line 789  static void init_frame(compiler_common * Line 868  static void init_frame(compiler_common *
868  {  {
869  DEFINE_COMPILER;  DEFINE_COMPILER;
870  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
871  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
872    BOOL setmark_found = recursive;
873  int offset;  int offset;
874    
875  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
876    SLJIT_UNUSED_ARG(stacktop);
877  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
878    
879  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 803  while (cc < ccend) Line 884  while (cc < ccend)
884    switch(*cc)    switch(*cc)
885      {      {
886      case OP_SET_SOM:      case OP_SET_SOM:
887      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
888      if (!setsom_found)      if (!setsom_found)
889        {        {
890        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 813  while (cc < ccend) Line 894  while (cc < ccend)
894        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
895        setsom_found = TRUE;        setsom_found = TRUE;
896        }        }
897      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
898        break;
899    
900        case OP_MARK:
901        SLJIT_ASSERT(common->mark_ptr != 0);
902        if (!setmark_found)
903          {
904          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
905          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
906          stackpos += (int)sizeof(sljit_w);
907          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
908          stackpos += (int)sizeof(sljit_w);
909          setmark_found = TRUE;
910          }
911        cc += 1 + 2 + cc[1];
912        break;
913    
914        case OP_RECURSE:
915        if (common->has_set_som && !setsom_found)
916          {
917          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
918          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
919          stackpos += (int)sizeof(sljit_w);
920          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
921          stackpos += (int)sizeof(sljit_w);
922          setsom_found = TRUE;
923          }
924        if (common->mark_ptr != 0 && !setmark_found)
925          {
926          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
927          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
928          stackpos += (int)sizeof(sljit_w);
929          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
930          stackpos += (int)sizeof(sljit_w);
931          setmark_found = TRUE;
932          }
933        cc += 1 + LINK_SIZE;
934      break;      break;
935    
936      case OP_CBRA:      case OP_CBRA:
# Line 940  while (status != end) Line 1057  while (status != end)
1057    switch(status)    switch(status)
1058      {      {
1059      case start:      case start:
1060      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1061      count = 1;      count = 1;
1062      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1063      status = loop;      status = loop;
1064      break;      break;
1065    
# Line 1201  struct sljit_label *loop; Line 1318  struct sljit_label *loop;
1318  int i;  int i;
1319  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1320  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1321  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1322  if (length < 8)  if (length < 8)
1323    {    {
1324    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1209  if (length < 8) Line 1326  if (length < 8)
1326    }    }
1327  else  else
1328    {    {
1329    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));
1330    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1331    loop = LABEL();    loop = LABEL();
1332    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 1225  struct sljit_label *loop; Line 1342  struct sljit_label *loop;
1342  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1343    
1344  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1345  OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1346  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1347    
1348  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1349    if (common->mark_ptr != 0)
1350      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1351  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1352    if (common->mark_ptr != 0)
1353      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1354  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));
1355  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));
1356  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1357  /* Unlikely, but possible */  /* Unlikely, but possible */
1358  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1359  loop = LABEL();  loop = LABEL();
1360  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1361  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1362  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1363  #ifdef COMPILE_PCRE16  #ifdef COMPILE_PCRE16
1364  OP2(SLJIT_ASHR, SLJIT_GENERAL_REG2, 0, SLJIT_GENERAL_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1365  #endif  #endif
1366  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1367  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1368  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1369  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1250  JUMPHERE(earlyexit); Line 1371  JUMPHERE(earlyexit);
1371  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1372  if (topbracket > 1)  if (topbracket > 1)
1373    {    {
1374    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));
1375    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1376    
1377    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1378    loop = LABEL();    loop = LABEL();
1379    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1380    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1381    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1382    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1383    }    }
1384  else  else
1385    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1386  }  }
1387    
1388    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1389    {
1390    DEFINE_COMPILER;
1391    
1392    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1393    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1394    
1395    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1396    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1397    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1398    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1399    
1400    /* Store match begin and end. */
1401    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1402    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1403    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1404    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1405    #ifdef COMPILE_PCRE16
1406    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1407    #endif
1408    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1409    
1410    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1411    #ifdef COMPILE_PCRE16
1412    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1413    #endif
1414    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1415    
1416    JUMPTO(SLJIT_JUMP, leave);
1417    }
1418    
1419    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1420    {
1421    /* May destroy TMP1. */
1422    DEFINE_COMPILER;
1423    struct sljit_jump *jump;
1424    
1425    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1426      {
1427      /* The value of -1 must be kept for start_used_ptr! */
1428      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1429      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1430      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1431      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1432      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1433      JUMPHERE(jump);
1434      }
1435    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1436      {
1437      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1438      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1439      JUMPHERE(jump);
1440      }
1441    }
1442    
1443  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1444  {  {
1445  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1385  return (bit < 256) ? ((0 << 8) | bit) : Line 1561  return (bit < 256) ? ((0 << 8) | bit) :
1561  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
1562  }  }
1563    
1564  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
1565    {
1566    /* Checks whether a partial matching is occured. Does not modify registers. */
1567    DEFINE_COMPILER;
1568    struct sljit_jump *jump = NULL;
1569    
1570    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1571    
1572    if (common->mode == JIT_COMPILE)
1573      return;
1574    
1575    if (!force)
1576      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1577    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1578      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1579    
1580    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1581      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1582    else
1583      {
1584      if (common->partialmatchlabel != NULL)
1585        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1586      else
1587        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1588      }
1589    
1590    if (jump != NULL)
1591      JUMPHERE(jump);
1592    }
1593    
1594    static struct sljit_jump *check_str_end(compiler_common *common)
1595  {  {
1596    /* Does not affect registers. Usually used in a tight spot. */
1597  DEFINE_COMPILER;  DEFINE_COMPILER;
1598  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1599    struct sljit_jump *nohit;
1600    struct sljit_jump *return_value;
1601    
1602    if (common->mode == JIT_COMPILE)
1603      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1604    
1605    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1606    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1607      {
1608      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1609      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1610      JUMPHERE(nohit);
1611      return_value = JUMP(SLJIT_JUMP);
1612      }
1613    else
1614      {
1615      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1616      if (common->partialmatchlabel != NULL)
1617        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1618      else
1619        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1620      }
1621    JUMPHERE(jump);
1622    return return_value;
1623    }
1624    
1625    static void detect_partial_match(compiler_common *common, jump_list **backtracks)
1626    {
1627    DEFINE_COMPILER;
1628    struct sljit_jump *jump;
1629    
1630    if (common->mode == JIT_COMPILE)
1631      {
1632      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1633      return;
1634      }
1635    
1636    /* Partial matching mode. */
1637    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1638    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1639    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1640      {
1641      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1642      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
1643      }
1644    else
1645      {
1646      if (common->partialmatchlabel != NULL)
1647        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1648      else
1649        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1650      }
1651    JUMPHERE(jump);
1652  }  }
1653    
1654  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1529  if (common->utf) Line 1789  if (common->utf)
1789  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));
1790  }  }
1791    
1792  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)
1793  {  {
1794  /* 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. */
1795  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1537  DEFINE_COMPILER; Line 1797  DEFINE_COMPILER;
1797  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
1798    {    {
1799    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1800    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));
1801    }    }
1802  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
1803    {    {
# Line 1545  else if (nltype == NLTYPE_ANYCRLF) Line 1805  else if (nltype == NLTYPE_ANYCRLF)
1805    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1806    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);
1807    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1808    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));
1809    }    }
1810  else  else
1811    {    {
1812    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1813    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));
1814    }    }
1815  }  }
1816    
# Line 1564  of the character (>= 0xc0). Return char Line 1824  of the character (>= 0xc0). Return char
1824  DEFINE_COMPILER;  DEFINE_COMPILER;
1825  struct sljit_jump *jump;  struct sljit_jump *jump;
1826    
1827  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1828  /* Searching for the first zero. */  /* Searching for the first zero. */
1829  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);
1830  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1623  DEFINE_COMPILER; Line 1883  DEFINE_COMPILER;
1883  struct sljit_jump *jump;  struct sljit_jump *jump;
1884  struct sljit_jump *compare;  struct sljit_jump *compare;
1885    
1886  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1887    
1888  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);
1889  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1660  of the character (>= 0xd800). Return cha Line 1920  of the character (>= 0xd800). Return cha
1920  DEFINE_COMPILER;  DEFINE_COMPILER;
1921  struct sljit_jump *jump;  struct sljit_jump *jump;
1922    
1923  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1924  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1925  /* Do nothing, only return. */  /* Do nothing, only return. */
1926  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1697  DEFINE_COMPILER; Line 1957  DEFINE_COMPILER;
1957    
1958  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
1959    
1960  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1961  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1962  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));
1963  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 1733  if (!(hascrorlf || firstline) && (common Line 1993  if (!(hascrorlf || firstline) && (common
1993  if (firstline)  if (firstline)
1994    {    {
1995    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1996      SLJIT_ASSERT(common->first_line_end != 0);
1997    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1998    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
1999    
2000    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2001      {      {
# Line 1745  if (firstline) Line 2006  if (firstline)
2006      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2007      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);
2008      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);
2009      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_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));
2010      }      }
2011    else    else
2012      {      {
2013      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2014      mainloop = LABEL();      mainloop = LABEL();
2015      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2016      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2017      read_char(common);      read_char(common);
2018      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2019      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2020      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2021      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2022      }      }
2023    
# Line 1839  pcre_uchar oc, bit; Line 2100  pcre_uchar oc, bit;
2100  if (firstline)  if (firstline)
2101    {    {
2102    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2103    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2104    }    }
2105    
2106  start = LABEL();  start = LABEL();
# Line 1917  jump_list *newline = NULL; Line 2178  jump_list *newline = NULL;
2178  if (firstline)  if (firstline)
2179    {    {
2180    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2181    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2182    }    }
2183    
2184  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 2001  struct sljit_jump *jump; Line 2262  struct sljit_jump *jump;
2262  if (firstline)  if (firstline)
2263    {    {
2264    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2265    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2266    }    }
2267    
2268  start = LABEL();  start = LABEL();
# Line 2066  struct sljit_jump *foundoc = NULL; Line 2327  struct sljit_jump *foundoc = NULL;
2327  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2328  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2329    
2330  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2331    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2332  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2333  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2334  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2111  JUMPTO(SLJIT_JUMP, loop); Line 2373  JUMPTO(SLJIT_JUMP, loop);
2373  JUMPHERE(found);  JUMPHERE(found);
2374  if (foundoc)  if (foundoc)
2375    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2376  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2377  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2378  JUMPHERE(toolong);  JUMPHERE(toolong);
2379  return notfound;  return notfound;
# Line 2123  DEFINE_COMPILER; Line 2385  DEFINE_COMPILER;
2385  struct sljit_jump *jump;  struct sljit_jump *jump;
2386  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2387    
2388  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2389  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2390    GET_LOCAL_BASE(TMP3, 0, 0);
2391    
2392  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2393  mainloop = LABEL();  mainloop = LABEL();
2394  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2395  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);
2396  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2397  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));
2398  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));
2399  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 2150  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2413  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2413  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2414    
2415  JUMPHERE(jump);  JUMPHERE(jump);
2416    if (common->mark_ptr != 0)
2417      {
2418      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2419      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2420      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2421      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2422      JUMPTO(SLJIT_JUMP, mainloop);
2423    
2424      JUMPHERE(jump);
2425      }
2426    
2427  /* Unknown command. */  /* Unknown command. */
2428  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2429  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2158  JUMPTO(SLJIT_JUMP, mainloop); Line 2432  JUMPTO(SLJIT_JUMP, mainloop);
2432  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2433  {  {
2434  DEFINE_COMPILER;  DEFINE_COMPILER;
2435  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2436  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2437  struct sljit_jump *jump;  struct sljit_jump *jump;
2438  #endif  #endif
2439    
2440  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2441    
2442  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);
2443  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2444  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2445  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));
2446  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2447  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2448  skip_char_back(common);  skip_char_back(common);
2449    check_start_used_ptr(common);
2450  read_char(common);  read_char(common);
2451    
2452  /* Testing char type. */  /* Testing char type. */
# Line 2212  else Line 2487  else
2487      JUMPHERE(jump);      JUMPHERE(jump);
2488  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2489    }    }
2490  JUMPHERE(beginend);  JUMPHERE(skipread);
2491    
2492  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2493  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2494  peek_char(common);  peek_char(common);
2495    
2496  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2256  else Line 2531  else
2531      JUMPHERE(jump);      JUMPHERE(jump);
2532  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
2533    }    }
2534  JUMPHERE(beginend);  JUMPHERE(skipread);
2535    
2536  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2537  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2267  static void check_anynewline(compiler_co Line 2542  static void check_anynewline(compiler_co
2542  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2543  DEFINE_COMPILER;  DEFINE_COMPILER;
2544    
2545  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2546    
2547  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2548  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 2294  static void check_hspace(compiler_common Line 2569  static void check_hspace(compiler_common
2569  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571    
2572  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2573    
2574  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);
2575  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
# Line 2333  static void check_vspace(compiler_common Line 2608  static void check_vspace(compiler_common
2608  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2609  DEFINE_COMPILER;  DEFINE_COMPILER;
2610    
2611  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2612    
2613  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2614  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 2365  DEFINE_COMPILER; Line 2640  DEFINE_COMPILER;
2640  struct sljit_jump *jump;  struct sljit_jump *jump;
2641  struct sljit_label *label;  struct sljit_label *label;
2642    
2643  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2644  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2645  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2646  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2394  DEFINE_COMPILER; Line 2669  DEFINE_COMPILER;
2669  struct sljit_jump *jump;  struct sljit_jump *jump;
2670  struct sljit_label *label;  struct sljit_label *label;
2671    
2672  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2673  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2674    
2675  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2441  static const pcre_uchar *SLJIT_CALL do_u Line 2716  static const pcre_uchar *SLJIT_CALL do_u
2716  {  {
2717  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2718  int c1, c2;  int c1, c2;
2719  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2720  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
2721    
2722  while (src1 < end1)  while (src1 < end1)
2723    {    {
2724    if (src2 >= end2)    if (src2 >= end2)
2725      return 0;      return (pcre_uchar*)1;
2726    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2727    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2728    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2729    }    }
2730  return src2;  return src2;
2731  }  }
# Line 2458  return src2; Line 2733  return src2;
2733  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
2734    
2735  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,
2736      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
2737  {  {
2738  DEFINE_COMPILER;  DEFINE_COMPILER;
2739  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2559  do Line 2834  do
2834        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
2835        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2836          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);
2837        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));
2838        break;        break;
2839    
2840        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
2841        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
2842          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);
2843        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));
2844        break;        break;
2845    
2846  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
2847        case 1:        case 1:
2848        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2849          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);
2850        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));
2851        break;        break;
2852  #endif  #endif
2853    
# Line 2598  do Line 2873  do
2873    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
2874      {      {
2875      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2876      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));
2877      }      }
2878    else    else
2879      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));
2880    
2881  #endif  #endif
2882    
# Line 2637  return cc; Line 2912  return cc;
2912      } \      } \
2913    charoffset = (value);    charoffset = (value);
2914    
2915  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
2916  {  {
2917  DEFINE_COMPILER;  DEFINE_COMPILER;
2918  jump_list *found = NULL;  jump_list *found = NULL;
2919  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
2920  unsigned int c;  unsigned int c;
2921  int compares;  int compares;
2922  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2656  int invertcmp, numberofcmps; Line 2931  int invertcmp, numberofcmps;
2931  unsigned int charoffset;  unsigned int charoffset;
2932    
2933  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2934  check_input_end(common, fallbacks);  detect_partial_match(common, backtracks);
2935  read_char(common);  read_char(common);
2936    
2937  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2807  typeoffset = 0; Line 3082  typeoffset = 0;
3082  while (*cc != XCL_END)  while (*cc != XCL_END)
3083    {    {
3084    compares--;    compares--;
3085    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3086    jump = NULL;    jump = NULL;
3087    
3088    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 2889  while (*cc != XCL_END) Line 3164  while (*cc != XCL_END)
3164      switch(*cc)      switch(*cc)
3165        {        {
3166        case PT_ANY:        case PT_ANY:
3167        if (list != fallbacks)        if (list != backtracks)
3168          {          {
3169          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))
3170            continue;            continue;
# Line 2962  while (*cc != XCL_END) Line 3237  while (*cc != XCL_END)
3237  #endif  #endif
3238    
3239    if (jump != NULL)    if (jump != NULL)
3240      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3241    }    }
3242    
3243  if (found != NULL)  if (found != NULL)
# Line 2974  if (found != NULL) Line 3249  if (found != NULL)
3249    
3250  #endif  #endif
3251    
3252  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3253  {  {
3254  DEFINE_COMPILER;  DEFINE_COMPILER;
3255  int length;  int length;
# Line 2993  switch(type) Line 3268  switch(type)
3268    case OP_SOD:    case OP_SOD:
3269    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3270    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));
3271    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));
3272    return cc;    return cc;
3273    
3274    case OP_SOM:    case OP_SOM:
3275    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3276    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));
3277    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));
3278    return cc;    return cc;
3279    
3280    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
3281    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
3282    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3283    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));
3284    return cc;    return cc;
3285    
3286    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3287    case OP_DIGIT:    case OP_DIGIT:
3288    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3289    read_char8_type(common);    read_char8_type(common);
3290    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3291    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3292    return cc;    return cc;
3293    
3294    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3295    case OP_WHITESPACE:    case OP_WHITESPACE:
3296    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3297    read_char8_type(common);    read_char8_type(common);
3298    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);
3299    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));
3300    return cc;    return cc;
3301    
3302    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3303    case OP_WORDCHAR:    case OP_WORDCHAR:
3304    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3305    read_char8_type(common);    read_char8_type(common);
3306    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);
3307    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));
3308    return cc;    return cc;
3309    
3310    case OP_ANY:    case OP_ANY:
3311    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3312    read_char(common);    read_char(common);
3313    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3314      {      {
3315      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3316      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3317          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3318        else
3319          jump[1] = check_str_end(common);
3320    
3321      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3322      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));
3323      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3324          JUMPHERE(jump[1]);
3325      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3326      }      }
3327    else    else
3328      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
3329    return cc;    return cc;
3330    
3331    case OP_ALLANY:    case OP_ALLANY:
3332    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3333  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3334    if (common->utf)    if (common->utf)
3335      {      {
# Line 3077  switch(type) Line 3357  switch(type)
3357    return cc;    return cc;
3358    
3359    case OP_ANYBYTE:    case OP_ANYBYTE:
3360    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3361    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));
3362    return cc;    return cc;
3363    
# Line 3090  switch(type) Line 3370  switch(type)
3370    propdata[2] = cc[0];    propdata[2] = cc[0];
3371    propdata[3] = cc[1];    propdata[3] = cc[1];
3372    propdata[4] = XCL_END;    propdata[4] = XCL_END;
3373    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_trypath(common, propdata, backtracks);
3374    return cc + 2;    return cc + 2;
3375  #endif  #endif
3376  #endif  #endif
3377    
3378    case OP_ANYNL:    case OP_ANYNL:
3379    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3380    read_char(common);    read_char(common);
3381    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);
3382    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3383      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3384        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3385      else
3386        jump[1] = check_str_end(common);
3387    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3388    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3389    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));
3390    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3391    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3392    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
3393    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3394    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
3395    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3113  switch(type) Line 3397  switch(type)
3397    
3398    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3399    case OP_HSPACE:    case OP_HSPACE:
3400    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3401    read_char(common);    read_char(common);
3402    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3403    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));
3404    return cc;    return cc;
3405    
3406    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3407    case OP_VSPACE:    case OP_VSPACE:
3408    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3409    read_char(common);    read_char(common);
3410    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3411    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));
3412    return cc;    return cc;
3413    
3414  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3415    case OP_EXTUNI:    case OP_EXTUNI:
3416    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3417    read_char(common);    read_char(common);
3418    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3419    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3420    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));
3421    
3422    label = LABEL();    label = LABEL();
3423    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 3145  switch(type) Line 3429  switch(type)
3429    
3430    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3431    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3432      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3433        {
3434        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3435        /* Since we successfully read a char above, partial matching must occure. */
3436        check_partial(common, TRUE);
3437        JUMPHERE(jump[0]);
3438        }
3439    return cc;    return cc;
3440  #endif  #endif
3441    
3442    case OP_EODN:    case OP_EODN:
3443      /* Requires rather complex checks. */
3444    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);
3445    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3446      {      {
3447      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));
3448      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3449      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3450          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3451        else
3452          {
3453          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3454          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3455          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3456          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3457          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3458          add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
3459          check_partial(common, TRUE);
3460          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3461          JUMPHERE(jump[1]);
3462          }
3463      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3464      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));
3465      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));
3466      }      }
3467    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3468      {      {
3469      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));
3470      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3471      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));
3472      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));
3473      }      }
3474    else    else
3475      {      {
# Line 3173  switch(type) Line 3478  switch(type)
3478      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));
3479      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);
3480      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3481      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
3482      /* Equal. */      /* Equal. */
3483      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3484      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3485      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3486    
3487      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3488      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3489        {        {
3490        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));
3491        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));
3492        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));
3493        }        }
3494      else      else
3495        {        {
3496        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
3497        read_char(common);        read_char(common);
3498        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));
3499        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3500        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3501        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3502        }        }
3503      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
3504      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3505      }      }
3506    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3507      check_partial(common, FALSE);
3508    return cc;    return cc;
3509    
3510    case OP_EOD:    case OP_EOD:
3511    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3512      check_partial(common, FALSE);
3513    return cc;    return cc;
3514    
3515    case OP_CIRC:    case OP_CIRC:
3516    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3517    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));
3518    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));
3519    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));
3520    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));
3521    return cc;    return cc;
3522    
3523    case OP_CIRCM:    case OP_CIRCM:
# Line 3218  switch(type) Line 3525  switch(type)
3525    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));
3526    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
3527    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));
3528    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));
3529    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3530    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3531    
3532    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
3533    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3534      {      {
3535      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));
3536      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3537      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3538      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3539      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));
3540      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));
3541      }      }
3542    else    else
3543      {      {
3544      skip_char_back(common);      skip_char_back(common);
3545      read_char(common);      read_char(common);
3546      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
3547      }      }
3548    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3549    return cc;    return cc;
# Line 3244  switch(type) Line 3551  switch(type)
3551    case OP_DOLL:    case OP_DOLL:
3552    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3553    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));
3554    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));
3555    
3556    if (!common->endonly)    if (!common->endonly)
3557      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_trypath(common, OP_EODN, cc, backtracks);
3558    else    else
3559      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      {
3560        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3561        check_partial(common, FALSE);
3562        }
3563    return cc;    return cc;
3564    
3565    case OP_DOLLM:    case OP_DOLLM:
3566    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3567    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3568    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));
3569    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));
3570      check_partial(common, FALSE);
3571    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3572    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3573    
3574    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3575      {      {
3576      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));
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));  
3577      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3578        if (common->mode == JIT_COMPILE)
3579          add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3580        else
3581          {
3582          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3583          /* STR_PTR = STR_END - IN_UCHARS(1) */
3584          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3585          check_partial(common, TRUE);
3586          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3587          JUMPHERE(jump[1]);
3588          }
3589    
3590      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3591      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));
3592      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));
3593      }      }
3594    else    else
3595      {      {
3596      peek_char(common);      peek_char(common);
3597      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
3598      }      }
3599    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3600    return cc;    return cc;
# Line 3283  switch(type) Line 3605  switch(type)
3605  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3606    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3607  #endif  #endif
3608    if (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))
3609      {      {
3610      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));
3611      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));
3612    
3613      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
3614      context.sourcereg = -1;      context.sourcereg = -1;
3615  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3616      context.ucharptr = 0;      context.ucharptr = 0;
3617  #endif  #endif
3618      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
3619      }      }
3620    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3621    read_char(common);    read_char(common);
3622  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3623    if (common->utf)    if (common->utf)
# Line 3305  switch(type) Line 3627  switch(type)
3627    else    else
3628  #endif  #endif
3629      c = *cc;      c = *cc;
3630      if (type == OP_CHAR || !char_has_othercase(common, cc))
3631        {
3632        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3633        return cc + length;
3634        }
3635      oc = char_othercase(common, c);
3636      bit = c ^ oc;
3637      if (ispowerof2(bit))
3638        {
3639        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3640        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3641        return cc + length;
3642        }
3643    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);
3644    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3645    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
3646    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3647    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3648    return cc + length;    return cc + length;
3649    
3650    case OP_NOT:    case OP_NOT:
3651    case OP_NOTI:    case OP_NOTI:
3652    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3653    length = 1;    length = 1;
3654  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3655    if (common->utf)    if (common->utf)
# Line 3325  switch(type) Line 3660  switch(type)
3660        {        {
3661        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3662        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3663          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));
3664        else        else
3665          {          {
3666          /* 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. */
3667          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3668          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));
3669          }          }
3670        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3671        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 3355  switch(type) Line 3690  switch(type)
3690      }      }
3691    
3692    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
3693      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));
3694    else    else
3695      {      {
3696      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3363  switch(type) Line 3698  switch(type)
3698      if (ispowerof2(bit))      if (ispowerof2(bit))
3699        {        {
3700        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3701        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));
3702        }        }
3703      else      else
3704        {        {
3705        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));
3706        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));
3707        }        }
3708      }      }
3709    return cc + 1;    return cc + length;
3710    
3711    case OP_CLASS:    case OP_CLASS:
3712    case OP_NCLASS:    case OP_NCLASS:
3713    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3714    read_char(common);    read_char(common);
3715  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3716    jump[0] = NULL;    jump[0] = NULL;
# Line 3388  switch(type) Line 3723  switch(type)
3723      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3724      if (type == OP_CLASS)      if (type == OP_CLASS)
3725        {        {
3726        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
3727        jump[0] = NULL;        jump[0] = NULL;
3728        }        }
3729      }      }
# Line 3398  switch(type) Line 3733  switch(type)
3733    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3734    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3735    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);
3736    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3737  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3738    if (jump[0] != NULL)    if (jump[0] != NULL)
3739      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3407  switch(type) Line 3742  switch(type)
3742    
3743  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3744    case OP_XCLASS:    case OP_XCLASS:
3745    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
3746    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
3747  #endif  #endif
3748    
3749    case OP_REVERSE:    case OP_REVERSE:
3750    length = GET(cc, 0);    length = GET(cc, 0);
3751    SLJIT_ASSERT(length > 0);    if (length == 0)
3752        return cc + LINK_SIZE;
3753    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3754  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3755    if (common->utf)    if (common->utf)
# Line 3421  switch(type) Line 3757  switch(type)
3757      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));
3758      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3759      label = LABEL();      label = LABEL();
3760      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));
3761      skip_char_back(common);      skip_char_back(common);
3762      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);
3763      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3764      }      }
3765      else
3766  #endif  #endif
3767    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      {
3768    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3769    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3770        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3771        }
3772      check_start_used_ptr(common);
3773    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3774    }    }
3775  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3776  return cc;  return cc;
3777  }  }
3778    
3779  static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
3780  {  {
3781  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3782  /* 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 3489  if (context.length > 0) Line 3828  if (context.length > 0)
3828    {    {
3829    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
3830    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);
3831    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));
3832    
3833    context.sourcereg = -1;    context.sourcereg = -1;
3834  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3835    context.ucharptr = 0;    context.ucharptr = 0;
3836  #endif  #endif
3837    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);
3838    return cc;    return cc;
3839    }    }
3840    
3841  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
3842  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_trypath(common, *cc, cc + 1, backtracks);
3843  }  }
3844    
3845  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)
3846  {  {
3847  DEFINE_COMPILER;  DEFINE_COMPILER;
3848  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3511  int offset = GET2(cc, 1) << 1; Line 3850  int offset = GET2(cc, 1) << 1;
3850  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3851  if (!common->jscript_compat)  if (!common->jscript_compat)
3852    {    {
3853    if (fallbacks == NULL)    if (backtracks == NULL)
3854      {      {
3855        /* OVECTOR(1) contains the "string begin - 1" constant. */
3856      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));
3857      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3858      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3859      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3860      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
3861      }      }
3862    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)));
3863    }    }
3864  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));
3865  }  }
3866    
3867  /* Forward definitions. */  /* Forward definitions. */
3868  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
3869  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
3870    
3871  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
3872    do \    do \
3873      { \      { \
3874      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
3875      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3876        return error; \        return error; \
3877      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
3878      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
3879      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
3880      parent->top = fallback; \      parent->top = backtrack; \
3881      } \      } \
3882    while (0)    while (0)
3883    
3884  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
3885    do \    do \
3886      { \      { \
3887      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
3888      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3889        return; \        return; \
3890      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
3891      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
3892      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
3893      parent->top = fallback; \      parent->top = backtrack; \
3894      } \      } \
3895    while (0)    while (0)
3896    
3897  #define FALLBACK_AS(type) ((type*)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
3898    
3899  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
3900  {  {
3901  DEFINE_COMPILER;  DEFINE_COMPILER;
3902  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3903  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3904    struct sljit_jump *partial;
3905    struct sljit_jump *nopartial;
3906    
3907  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3908    /* OVECTOR(1) contains the "string begin - 1" constant. */
3909  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3910    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)));
3911    
3912  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3913  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3577  if (common->utf && *cc == OP_REFI) Line 3920  if (common->utf && *cc == OP_REFI)
3920    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3921    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3922    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3923    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
3924    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));
3925    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3926    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3927        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3928      else
3929        {
3930        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3931        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3932        check_partial(common, FALSE);
3933        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3934        JUMPHERE(nopartial);
3935        }
3936    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3937    }    }
3938  else  else
# Line 3589  else Line 3941  else
3941    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3942    if (withchecks)    if (withchecks)
3943      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3944    
3945    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3946      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3947      if (common->mode == JIT_COMPILE)
3948        add_jump(compiler, backtracks, partial);
3949    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3950    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));
3951    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));
3952    
3953      if (common->mode != JIT_COMPILE)
3954        {
3955        nopartial = JUMP(SLJIT_JUMP);
3956        JUMPHERE(partial);
3957        /* TMP2 -= STR_END - STR_PTR */
3958        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3959        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3960        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3961        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3962        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3963        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3964        JUMPHERE(partial);
3965        check_partial(common, FALSE);
3966        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3967        JUMPHERE(nopartial);
3968        }
3969    }    }
3970    
3971  if (jump != NULL)  if (jump != NULL)
3972    {    {
3973    if (emptyfail)    if (emptyfail)
3974      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
3975    else    else
3976      JUMPHERE(jump);      JUMPHERE(jump);
3977    }    }
3978  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
3979  }  }
3980    
3981  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
3982  {  {
3983  DEFINE_COMPILER;  DEFINE_COMPILER;
3984  fallback_common *fallback;  backtrack_common *backtrack;
3985  pcre_uchar type;  pcre_uchar type;
3986  struct sljit_label *label;  struct sljit_label *label;
3987  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3618  pcre_uchar *ccbegin = cc; Line 3990  pcre_uchar *ccbegin = cc;
3990  int min = 0, max = 0;  int min = 0, max = 0;
3991  BOOL minimize;  BOOL minimize;
3992    
3993  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
3994    
3995  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
3996  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 3670  if (!minimize) Line 4042  if (!minimize)
4042      {      {
4043      allocate_stack(common, 1);      allocate_stack(common, 1);
4044      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4045      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4046      }      }
4047    
4048    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4049      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4050    
4051    label = LABEL();    label = LABEL();
4052    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4053    
4054    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4055      {      {
# Line 3705  if (!minimize) Line 4077  if (!minimize)
4077      }      }
4078    
4079    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4080    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4081    
4082    decrease_call_count(common);    decrease_call_count(common);
4083    return cc;    return cc;
# Line 3723  if (min == 0) Line 4095  if (min == 0)
4095    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4096    }    }
4097  else  else
4098    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4099    
4100  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4101  if (max > 0)  if (max > 0)
4102    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));
4103    
4104  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4105  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4106    
4107  if (min > 1)  if (min > 1)
# Line 3737  if (min > 1) Line 4109  if (min > 1)
4109    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4110    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4111    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4112    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);
4113    }    }
4114  else if (max > 0)  else if (max > 0)
4115    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 3750  decrease_call_count(common); Line 4122  decrease_call_count(common);
4122  return cc;  return cc;
4123  }  }
4124    
4125  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4126  {  {
4127  DEFINE_COMPILER;  DEFINE_COMPILER;
4128  fallback_common *fallback;  backtrack_common *backtrack;
4129  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4130  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4131  int start = GET(cc, 1);  int start = GET(cc, 1);
4132    
4133  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4134  while (entry != NULL)  while (entry != NULL)
4135    {    {
4136    if (entry->start == start)    if (entry->start == start)
# Line 3783  if (entry == NULL) Line 4155  if (entry == NULL)
4155      common->entries = entry;      common->entries = entry;
4156    }    }
4157    
4158  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4159  allocate_stack(common, 1);    {
4160  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4161      allocate_stack(common, 2);
4162      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4163      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4164      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4165      }
4166    else if (common->has_set_som || common->mark_ptr != 0)
4167      {
4168      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4169      allocate_stack(common, 1);
4170      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4171      }
4172    
4173  if (entry->entry == NULL)  if (entry->entry == NULL)
4174    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
4175  else  else
4176    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4177  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4178  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));
4179  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4180  }  }
4181    
4182  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4183  {  {
4184  DEFINE_COMPILER;  DEFINE_COMPILER;
4185  int framesize;  int framesize;
4186  int localptr;  int localptr;
4187  fallback_common altfallback;  backtrack_common altbacktrack;
4188  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4189  pcre_uchar opcode;  pcre_uchar opcode;
4190  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4191  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4192  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4193  jump_list **found;  jump_list **found;
4194  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4195    struct sljit_label *save_leavelabel = common->leavelabel;
4196  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4197    jump_list *save_leave = common->leave;
4198    jump_list *save_accept = common->accept;
4199  struct sljit_jump *jump;  struct sljit_jump *jump;
4200  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4201    
4202  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4203    {    {
# Line 3823  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4208  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4208  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
4209  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4210  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4211  fallback->framesize = framesize;  backtrack->framesize = framesize;
4212  fallback->localptr = localptr;  backtrack->localptr = localptr;
4213  opcode = *cc;  opcode = *cc;
4214  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4215  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 3833  cc += GET(cc, 1); Line 4218  cc += GET(cc, 1);
4218    
4219  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4220    {    {
4221    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
4222    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4223    free_stack(common, 1);    free_stack(common, 1);
4224    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 3856  else Line 4241  else
4241    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
4242    }    }
4243    
4244  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
4245    common->leavelabel = NULL;
4246    common->leave = NULL;
4247  while (1)  while (1)
4248    {    {
4249    common->acceptlabel = NULL;    common->acceptlabel = NULL;
4250    common->accept = NULL;    common->accept = NULL;
4251    altfallback.top = NULL;    altbacktrack.top = NULL;
4252    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
4253    
4254    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
4255      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4256    
4257    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
4258    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
4259    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4260      {      {
4261        common->leavelabel = save_leavelabel;
4262      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4263        common->leave = save_leave;
4264      common->accept = save_accept;      common->accept = save_accept;
4265      return NULL;      return NULL;
4266      }      }
# Line 3921  while (1) Line 4310  while (1)
4310      }      }
4311    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
4312    
4313    compile_fallbackpath(common, altfallback.top);    compile_backtrackpath(common, altbacktrack.top);
4314    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4315      {      {
4316        common->leavelabel = save_leavelabel;
4317      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
4318        common->leave = save_leave;
4319      common->accept = save_accept;      common->accept = save_accept;
4320      return NULL;      return NULL;
4321      }      }
4322    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
4323    
4324    if (*cc != OP_ALT)    if (*cc != OP_ALT)
4325      break;      break;
# Line 3937  while (1) Line 4328  while (1)
4328    cc += GET(cc, 1);    cc += GET(cc, 1);
4329    }    }
4330  /* None of them matched. */  /* None of them matched. */
4331    if (common->leave != NULL)
4332      set_jumps(common->leave, LABEL());
4333    
4334  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
4335    {    {
# Line 4003  if (opcode == OP_ASSERT || opcode == OP_ Line 4396  if (opcode == OP_ASSERT || opcode == OP_
4396    
4397    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
4398      {      {
4399      fallback->hotpath = LABEL();      backtrack->trypath = LABEL();
4400      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->trypath);
4401      }      }
4402    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
4403      {      {
4404      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->trypath);
4405      JUMPHERE(brajump);      JUMPHERE(brajump);
4406      if (framesize >= 0)      if (framesize >= 0)
4407        {        {
# Line 4016  if (opcode == OP_ASSERT || opcode == OP_ Line 4409  if (opcode == OP_ASSERT || opcode == OP_
4409        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4410        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4411        }        }
4412      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
4413      }      }
4414    }    }
4415  else  else
# Line 4046  else Line 4439  else
4439      }      }
4440    
4441    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
4442      fallback->hotpath = LABEL();      backtrack->trypath = LABEL();
4443    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
4444      {      {
4445      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->trypath);
4446      JUMPHERE(brajump);      JUMPHERE(brajump);
4447      }      }
4448    
4449    if (bra != OP_BRA)    if (bra != OP_BRA)
4450      {      {
4451      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
4452      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
4453      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
4454      }      }
4455    }    }
4456    
4457    common->leavelabel = save_leavelabel;
4458  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
4459    common->leave = save_leave;
4460  common->accept = save_accept;  common->accept = save_accept;
4461  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4462  }  }
# Line 4076  sljit_w name_entry_size = locals[LOCALS1 Line 4471  sljit_w name_entry_size = locals[LOCALS1
4471  sljit_w no_capture;  sljit_w no_capture;
4472  int i;  int i;
4473    
4474  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4475    refno >>= 8;
4476  no_capture = locals[1];  no_capture = locals[1];
4477    
4478  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4229  return condition; Line 4625  return condition;
4625                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
4626  */  */
4627    
4628  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4629  {  {
4630  DEFINE_COMPILER;  DEFINE_COMPILER;
4631  fallback_common *fallback;  backtrack_common *backtrack;
4632  pcre_uchar opcode;  pcre_uchar opcode;
4633  int localptr = 0;  int localptr = 0;
4634  int offset = 0;  int offset = 0;
4635  int stacksize;  int stacksize;
4636  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4637  pcre_uchar *hotpath;  pcre_uchar *trypath;
4638  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4639  pcre_uchar ket;  pcre_uchar ket;
4640  assert_fallback *assert;  assert_backtrack *assert;
4641  BOOL has_alternatives;  BOOL has_alternatives;
4642  struct sljit_jump *jump;  struct sljit_jump *jump;
4643  struct sljit_jump *skip;  struct sljit_jump *skip;
4644  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
4645  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
4646    
4647  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
4648    
4649  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4650    {    {
# Line 4259  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4655    
4656  opcode = *cc;  opcode = *cc;
4657  ccbegin = cc;  ccbegin = cc;
4658  hotpath = ccbegin + 1 + LINK_SIZE;  trypath = ccbegin + 1 + LINK_SIZE;
4659    
4660  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)
4661    {    {
4662    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
4663    parent->top = fallback->prev;    parent->top = backtrack->prev;
4664    return bracketend(cc);    return bracketend(cc);
4665    }    }
4666    
# Line 4276  cc += GET(cc, 1); Line 4672  cc += GET(cc, 1);
4672  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
4673  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4674    {    {
4675    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;
4676    if (*hotpath == OP_NRREF)    if (*trypath == OP_NRREF)
4677      {      {
4678      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
4679      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
4680        has_alternatives = FALSE;        has_alternatives = FALSE;
4681      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4300  if (opcode == OP_CBRA || opcode == OP_SC Line 4696  if (opcode == OP_CBRA || opcode == OP_SC
4696    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
4697    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4698    offset <<= 1;    offset <<= 1;
4699    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
4700    hotpath += IMM2_SIZE;    trypath += IMM2_SIZE;
4701    }    }
4702  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4703    {    {
4704    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4705    localptr = PRIV_DATA(ccbegin);    localptr = PRIV_DATA(ccbegin);
4706    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4707    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
4708    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
4709      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
4710    }    }
4711    
4712  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4335  if (bra == OP_BRAZERO) Line 4731  if (bra == OP_BRAZERO)
4731    
4732  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4733    {    {
4734    /* 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) */
4735    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4736    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
4737      {      {
# Line 4352  if (bra == OP_BRAMINZERO) Line 4748  if (bra == OP_BRAMINZERO)
4748        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
4749        JUMPHERE(jump);        JUMPHERE(jump);
4750        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
4751        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
4752          {          {
4753          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, localptr contains the previous STR_PTR. */
4754          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4361  if (bra == OP_BRAMINZERO) Line 4757  if (bra == OP_BRAMINZERO)
4757          {          {
4758          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
4759          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4760          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));
4761          }          }
4762        JUMPHERE(skip);        JUMPHERE(skip);
4763        }        }
# Line 4375  if (bra == OP_BRAMINZERO) Line 4771  if (bra == OP_BRAMINZERO)
4771    }    }
4772    
4773  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
4774    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
4775    
4776  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
4777    {    {
4778    rmaxlabel = LABEL();    rmaxlabel = LABEL();
4779    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
4780      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;
4781    }    }
4782    
4783  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
4784  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
4785    {    {
4786    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
4787      {      {
4788      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
4789      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
# Line 4411  if (opcode == OP_ONCE) Line 4807  if (opcode == OP_ONCE)
4807      {      {
4808      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
4809        {        {
4810        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
4811        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4812        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));
4813        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4814        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4815        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4816        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);
4817        }        }
4818      else      else
4819        {        {
4820        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
4821        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4822        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));
4823        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
4824        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4825        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
4826        }        }
4827      }      }
4828    }    }
# Line 4460  else if (has_alternatives) Line 4856  else if (has_alternatives)
4856  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
4857  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4858    {    {
4859    if (*hotpath == OP_CREF)    if (*trypath == OP_CREF)
4860      {      {
4861      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
4862      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
4863        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4864      hotpath += 1 + IMM2_SIZE;      trypath += 1 + IMM2_SIZE;
4865      }      }
4866    else if (*hotpath == OP_NCREF)    else if (*trypath == OP_NCREF)
4867      {      {
4868      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
4869      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
4870      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));
4871    
4872      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4873      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);
4874      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);
4875      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
4876      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
4877      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4878      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));
4879      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4880      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));
4881    
4882      JUMPHERE(jump);      JUMPHERE(jump);
4883      hotpath += 1 + IMM2_SIZE;      trypath += 1 + IMM2_SIZE;
4884      }      }
4885    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*trypath == OP_RREF || *trypath == OP_NRREF)
4886      {      {
4887      /* Never has other case. */      /* Never has other case. */
4888      FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
4889    
4890      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
4891      if (common->currententry == NULL)      if (common->currententry == NULL)
4892        stacksize = 0;        stacksize = 0;
4893      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4501  if (opcode == OP_COND || opcode == OP_SC Line 4897  if (opcode == OP_COND || opcode == OP_SC
4897      else      else
4898        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4899    
4900      if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)
4901        {        {
4902        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
4903        if (stacksize != 0)        if (stacksize != 0)
4904          hotpath += 1 + IMM2_SIZE;          trypath += 1 + IMM2_SIZE;
4905        else        else
4906          {          {
4907          if (*cc == OP_ALT)          if (*cc == OP_ALT)
4908            {            {
4909            hotpath = cc + 1 + LINK_SIZE;            trypath = cc + 1 + LINK_SIZE;
4910            cc += GET(cc, 1);            cc += GET(cc, 1);
4911            }            }
4912          else          else
4913            hotpath = cc;            trypath = cc;
4914          }          }
4915        }        }
4916      else      else
4917        {        {
4918        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
4919    
4920        stacksize = GET2(hotpath, 1);        stacksize = GET2(trypath, 1);
4921        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4922        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);
4923        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);
4924        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));
4925        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4926        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
4927        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4928        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));
4929        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4930        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));
4931        hotpath += 1 + IMM2_SIZE;        trypath += 1 + IMM2_SIZE;
4932        }        }
4933      }      }
4934    else    else
4935      {      {
4936      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);
4937      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
4938      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
4939      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4940        return NULL;        return NULL;
4941      memset(assert, 0, sizeof(assert_fallback));      memset(assert, 0, sizeof(assert_backtrack));
4942      assert->common.cc = hotpath;      assert->common.cc = trypath;
4943      FALLBACK_AS(bracket_fallback)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
4944      hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);      trypath = compile_assert_trypath(common, trypath, assert, TRUE);
4945      }      }
4946    }    }
4947    
4948  compile_hotpath(common, hotpath, cc, fallback);  compile_trypath(common, trypath, cc, backtrack);
4949  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4950    return NULL;    return NULL;
4951    
4952  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
4953    {    {
4954    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
4955      {      {
4956      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4957      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 4570  if (opcode == OP_ONCE) Line 4966  if (opcode == OP_ONCE)
4966    else    else
4967      {      {
4968      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4969      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
4970      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
4971        {        {
4972        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 4605  if (has_alternatives) Line 5001  if (has_alternatives)
5001    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5002      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5003    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5004      FALLBACK_AS(bracket_fallback)->althotpath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5005    }    }
5006    
5007  /* Must be after the hotpath label. */  /* Must be after the trypath label. */
5008  if (offset != 0)  if (offset != 0)
5009    {    {
5010    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4621  if (ket == OP_KETRMAX) Line 5017  if (ket == OP_KETRMAX)
5017    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5018      {      {
5019      if (has_alternatives)      if (has_alternatives)
5020        FALLBACK_AS(bracket_fallback)->althotpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5021      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5022      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5023        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
# Line 4631  if (ket == OP_KETRMAX) Line 5027  if (ket == OP_KETRMAX)
5027      }      }
5028    else    else
5029      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5030    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5031    }    }
5032    
5033  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5034    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
5035    
5036  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5037    {    {
5038    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5039    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
5040    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5041      {      {
5042      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5043      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5044      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5045      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5046      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5047        {        {
5048        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5049        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 4655  if (bra == OP_BRAMINZERO) Line 5051  if (bra == OP_BRAMINZERO)
5051      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5052        free_stack(common, 1);        free_stack(common, 1);
5053      }      }
5054    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5055    }    }
5056    
5057  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
# Line 4668  cc += 1 + LINK_SIZE; Line 5064  cc += 1 + LINK_SIZE;
5064  return cc;  return cc;
5065  }  }
5066    
5067  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5068  {  {
5069  DEFINE_COMPILER;  DEFINE_COMPILER;
5070  fallback_common *fallback;  backtrack_common *backtrack;
5071  pcre_uchar opcode;  pcre_uchar opcode;
5072  int localptr;  int localptr;
5073  int cbraprivptr = 0;  int cbraprivptr = 0;
# Line 4684  int stack; Line 5080  int stack;
5080  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5081  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5082    
5083  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5084  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5085    {    {
5086    zero = TRUE;    zero = TRUE;
# Line 4694  if (*cc == OP_BRAPOSZERO) Line 5090  if (*cc == OP_BRAPOSZERO)
5090  opcode = *cc;  opcode = *cc;
5091  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
5092  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
5093  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
5094  switch(opcode)  switch(opcode)
5095    {    {
5096    case OP_BRAPOS:    case OP_BRAPOS:
# Line 4716  switch(opcode) Line 5112  switch(opcode)
5112    }    }
5113    
5114  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5115  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5116  if (framesize < 0)  if (framesize < 0)
5117    {    {
5118    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5119    if (!zero)    if (!zero)
5120      stacksize++;      stacksize++;
5121    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5122    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5123    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
5124    
# Line 4746  else Line 5142  else
5142      stacksize++;      stacksize++;
5143    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5144      stacksize++;      stacksize++;
5145    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5146    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5147    
5148    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4773  if (opcode == OP_CBRAPOS || opcode == OP Line 5169  if (opcode == OP_CBRAPOS || opcode == OP
5169  loop = LABEL();  loop = LABEL();
5170  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
5171    {    {
5172    fallback->top = NULL;    backtrack->top = NULL;
5173    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
5174    cc += GET(cc, 1);    cc += GET(cc, 1);
5175    
5176    compile_hotpath(common, ccbegin, cc, fallback);    compile_trypath(common, ccbegin, cc, backtrack);
5177    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5178      return NULL;      return NULL;
5179    
# Line 4838  while (*cc != OP_KETRPOS) Line 5234  while (*cc != OP_KETRPOS)
5234    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5235    flush_stubs(common);    flush_stubs(common);
5236    
5237    compile_fallbackpath(common, fallback->top);    compile_backtrackpath(common, backtrack->top);
5238    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5239      return NULL;      return NULL;
5240    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
5241    
5242    if (framesize < 0)    if (framesize < 0)
5243      {      {
# Line 4871  while (*cc != OP_KETRPOS) Line 5267  while (*cc != OP_KETRPOS)
5267    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
5268    }    }
5269    
5270  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
5271  if (!zero)  if (!zero)
5272    {    {
5273    if (framesize < 0)    if (framesize < 0)
5274      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));
5275    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [localptr] above. */
5276      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));
5277    }    }
5278    
5279  /* None of them matched. */  /* None of them matched. */
# Line 4925  else Line 5321  else
5321    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5322    *type = *opcode;    *type = *opcode;
5323    cc++;    cc++;
5324    class_len = (*type < OP_XCLASS) ? (1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5325    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5326    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5327      {      {
# Line 4978  if (end != NULL) Line 5374  if (end != NULL)
5374  return cc;  return cc;
5375  }  }
5376    
5377  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5378  {  {
5379  DEFINE_COMPILER;  DEFINE_COMPILER;
5380  fallback_common *fallback;  backtrack_common *backtrack;
5381  pcre_uchar opcode;  pcre_uchar opcode;
5382  pcre_uchar type;  pcre_uchar type;
5383  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 4990  jump_list *nomatch = NULL; Line 5386  jump_list *nomatch = NULL;
5386  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5387  struct sljit_label *label;  struct sljit_label *label;
5388    
5389  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5390    
5391  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
5392    
# Line 5017  switch(opcode) Line 5413  switch(opcode)
5413        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5414    
5415      label = LABEL();      label = LABEL();
5416      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5417      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
5418        {        {
5419        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5041  switch(opcode) Line 5437  switch(opcode)
5437      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5438      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5439      label = LABEL();      label = LABEL();
5440      compile_char1_hotpath(common, type, cc, &nomatch);      compile_char1_trypath(common, type, cc, &nomatch);
5441      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5442      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
5443        {        {
# Line 5057  switch(opcode) Line 5453  switch(opcode)
5453        }        }
5454      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
5455      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_PLUS || opcode == OP_CRRANGE)
5456        add_jump(compiler, &fallback->topfallbacks,        add_jump(compiler, &backtrack->topbacktracks,
5457          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));
5458      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5459      }      }
5460    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5461    break;    break;
5462    
5463    case OP_MINSTAR:    case OP_MINSTAR:
# Line 5069  switch(opcode) Line 5465  switch(opcode)
5465    allocate_stack(common, 1);    allocate_stack(common, 1);
5466    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5467    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
5468      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5469    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5470    break;    break;
5471    
5472    case OP_MINUPTO:    case OP_MINUPTO:
# Line 5079  switch(opcode) Line 5475  switch(opcode)
5475    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5476    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5477    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
5478      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5479    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5480    break;    break;
5481    
5482    case OP_QUERY:    case OP_QUERY:
# Line 5088  switch(opcode) Line 5484  switch(opcode)
5484    allocate_stack(common, 1);    allocate_stack(common, 1);
5485    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5486    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
5487      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5488    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5489    break;    break;
5490    
5491    case OP_EXACT:    case OP_EXACT:
5492    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5493    label = LABEL();    label = LABEL();
5494    compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5495    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5496    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5497    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
# Line 5109  switch(opcode) Line 5505  switch(opcode)
5505      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5506    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5507    label = LABEL();    label = LABEL();
5508    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
5509    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5510    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
5511      {      {
# Line 5126  switch(opcode) Line 5522  switch(opcode)
5522      }      }
5523    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
5524    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
5525      add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));
5526    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5527    break;    break;
5528    
5529    case OP_POSQUERY:    case OP_POSQUERY:
5530    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5531    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
5532    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5533    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
5534    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
# Line 5147  decrease_call_count(common); Line 5543  decrease_call_count(common);
5543  return end;  return end;
5544  }  }
5545    
5546  static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5547  {  {
5548  DEFINE_COMPILER;  DEFINE_COMPILER;
5549  fallback_common *fallback;  backtrack_common *backtrack;
5550    
5551  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5552    
5553  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
5554    {    {
5555    add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5556    return cc + 1;    return cc + 1;
5557    }    }
5558    
# Line 5176  else Line 5572  else
5572    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);
5573  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5574  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
5575  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
5576  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
5577  if (common->acceptlabel == NULL)  if (common->acceptlabel == NULL)
5578    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
# Line 5187  if (common->acceptlabel == NULL) Line 5583  if (common->acceptlabel == NULL)
5583    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
5584  else  else
5585    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
5586  add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5587  return cc + 1;  return cc + 1;
5588  }  }
5589    
5590  static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_trypath(compiler_common *common, pcre_uchar *cc)
5591  {  {
5592  DEFINE_COMPILER;  DEFINE_COMPILER;
5593  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 5207  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5603  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5603  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
5604  }  }
5605    
5606  static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)  static void compile_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
5607  {  {
5608  DEFINE_COMPILER;  DEFINE_COMPILER;
5609  fallback_common *fallback;  backtrack_common *backtrack;
5610    
5611  while (cc < ccend)  while (cc < ccend)
5612    {    {
# Line 5246  while (cc < ccend) Line 5642  while (cc < ccend)
5642      case OP_NOT:      case OP_NOT:
5643      case OP_NOTI:      case OP_NOTI:
5644      case OP_REVERSE:      case OP_REVERSE:
5645      cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5646      break;      break;
5647    
5648      case OP_SET_SOM:      case OP_SET_SOM:
5649      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5650        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5651      allocate_stack(common, 1);      allocate_stack(common, 1);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
5652      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
5653      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5654      cc++;      cc++;
5655      break;      break;
5656    
5657      case OP_CHAR:      case OP_CHAR:
5658      case OP_CHARI:      case OP_CHARI:
5659      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5660          cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5661        else
5662          cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5663      break;      break;
5664    
5665      case OP_STAR:      case OP_STAR:
# Line 5328  while (cc < ccend) Line 5727  while (cc < ccend)
5727      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
5728      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
5729      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
5730      cc = compile_iterator_hotpath(common, cc, parent);      cc = compile_iterator_trypath(common, cc, parent);
5731      break;      break;
5732    
5733      case OP_CLASS:      case OP_CLASS:
5734      case OP_NCLASS:      case OP_NCLASS:
5735      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
5736        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_trypath(common, cc, parent);
5737      else      else
5738        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5739      break;      break;
5740    
5741  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5742      case OP_XCLASS:      case OP_XCLASS:
5743      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
5744        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_trypath(common, cc, parent);
5745      else      else
5746        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_trypath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5747      break;      break;
5748  #endif  #endif
5749    
5750      case OP_REF:      case OP_REF:
5751      case OP_REFI:      case OP_REFI:
5752      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5753        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_trypath(common, cc, parent);
5754      else      else
5755        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);        cc = compile_ref_trypath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
5756      break;      break;
5757    
5758      case OP_RECURSE:      case OP_RECURSE:
5759      cc = compile_recurse_hotpath(common, cc, parent);      cc = compile_recurse_trypath(common, cc, parent);
5760      break;      break;
5761    
5762      case OP_ASSERT:      case OP_ASSERT:
5763      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
5764      case OP_ASSERTBACK:      case OP_ASSERTBACK:
5765      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
5766      PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
5767      cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
5768      break;      break;
5769    
5770      case OP_BRAMINZERO:      case OP_BRAMINZERO:
5771      PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
5772      cc = bracketend(cc + 1);      cc = bracketend(cc + 1);
5773      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
5774        {        {
# Line 5382  while (cc < ccend) Line 5781  while (cc < ccend)
5781        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5782        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
5783        }        }
5784      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();
5785      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
5786        decrease_call_count(common);        decrease_call_count(common);
5787      break;      break;
# Line 5395  while (cc < ccend) Line 5794  while (cc < ccend)
5794      case OP_SBRA:      case OP_SBRA:
5795      case OP_SCBRA:      case OP_SCBRA:
5796      case OP_SCOND:      case OP_SCOND:
5797      cc = compile_bracket_hotpath(common, cc, parent);      cc = compile_bracket_trypath(common, cc, parent);
5798      break;      break;
5799    
5800      case OP_BRAZERO:      case OP_BRAZERO:
5801      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
5802        cc = compile_bracket_hotpath(common, cc, parent);        cc = compile_bracket_trypath(common, cc, parent);
5803      else      else
5804        {        {
5805        PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
5806        cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
5807        }        }
5808      break;      break;
5809    
# Line 5413  while (cc < ccend) Line 5812  while (cc < ccend)
5812      case OP_SBRAPOS:      case OP_SBRAPOS:
5813      case OP_SCBRAPOS:      case OP_SCBRAPOS:
5814      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
5815      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_trypath(common, cc, parent);
5816        break;
5817    
5818        case OP_MARK:
5819        PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5820        SLJIT_ASSERT(common->mark_ptr != 0);
5821        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5822        allocate_stack(common, 1);
5823        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5824        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5825        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5826        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5827        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5828        cc += 1 + 2 + cc[1];
5829        break;
5830    
5831        case OP_COMMIT:
5832        PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5833        cc += 1;
5834      break;      break;
5835    
5836      case OP_FAIL:      case OP_FAIL:
5837      case OP_ACCEPT:      case OP_ACCEPT:
5838      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
5839      cc = compile_fail_accept_hotpath(common, cc, parent);      cc = compile_fail_accept_trypath(common, cc, parent);
5840      break;      break;
5841    
5842      case OP_CLOSE:      case OP_CLOSE:
5843      cc = compile_close_hotpath(common, cc);      cc = compile_close_trypath(common, cc);
5844      break;      break;
5845    
5846      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 5440  while (cc < ccend) Line 5857  while (cc < ccend)
5857  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
5858  }  }
5859    
5860  #undef PUSH_FALLBACK  #undef PUSH_BACKTRACK
5861  #undef PUSH_FALLBACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
5862  #undef FALLBACK_AS  #undef BACKTRACK_AS
5863    
5864  #define COMPILE_FALLBACKPATH(current) \  #define COMPILE_BACKTRACKPATH(current) \
5865    do \    do \
5866      { \      { \
5867      compile_fallbackpath(common, (current)); \      compile_backtrackpath(common, (current)); \
5868      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
5869        return; \        return; \
5870      } \      } \
5871    while (0)    while (0)
5872    
5873  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5874    
5875  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
5876  {  {
5877  DEFINE_COMPILER;  DEFINE_COMPILER;
5878  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5475  switch(opcode) Line 5892  switch(opcode)
5892    case OP_CRRANGE:    case OP_CRRANGE:
5893    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
5894      {      {
5895      set_jumps(current->topfallbacks, LABEL());      set_jumps(current->topbacktracks, LABEL());
5896      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5897      free_stack(common, 1);      free_stack(common, 1);
5898      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
5899      }      }
5900    else    else
5901      {      {
# Line 5491  switch(opcode) Line 5908  switch(opcode)
5908      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5909      skip_char_back(common);      skip_char_back(common);
5910      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5911      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5912      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_PLUS || opcode == OP_CRRANGE)
5913        set_jumps(current->topfallbacks, LABEL());        set_jumps(current->topbacktracks, LABEL());
5914      JUMPHERE(jump);      JUMPHERE(jump);
5915      free_stack(common, 2);      free_stack(common, 2);
5916      }      }
# Line 5504  switch(opcode) Line 5921  switch(opcode)
5921    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5922    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
5923      {      {
5924      set_jumps(current->topfallbacks, LABEL());      set_jumps(current->topbacktracks, LABEL());
5925      current->topfallbacks = NULL;      current->topbacktracks = NULL;
5926      }      }
5927    compile_char1_hotpath(common, type, cc, &current->topfallbacks);    compile_char1_trypath(common, type, cc, &current->topbacktracks);
5928    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5929    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5930    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5931    free_stack(common, 1);    free_stack(common, 1);
5932    break;    break;
5933    
# Line 5518  switch(opcode) Line 5935  switch(opcode)
5935    case OP_CRMINRANGE:    case OP_CRMINRANGE:
5936    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
5937      {      {
5938      set_jumps(current->topfallbacks, LABEL());      set_jumps(current->topbacktracks, LABEL());
5939      current->topfallbacks = NULL;      current->topbacktracks = NULL;
5940      label = LABEL();      label = LABEL();
5941      }      }
5942    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5943    compile_char1_hotpath(common, type, cc, &current->topfallbacks);    compile_char1_trypath(common, type, cc, &current->topbacktracks);
5944    
5945    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5946    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 5534  switch(opcode) Line 5951  switch(opcode)
5951      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
5952    
5953    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
5954      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5955    else    else
5956      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_fallback)->hotpath);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->trypath);
5957    
5958    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5959    free_stack(common, 2);    free_stack(common, 2);
5960    break;    break;
5961    
5962    case OP_QUERY:    case OP_QUERY:
5963    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5964    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5965    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
5966    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5967    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5968    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5969    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5970    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5971    JUMPHERE(jump);    JUMPHERE(jump);
5972    free_stack(common, 1);    free_stack(common, 1);
5973    break;    break;
# Line 5559  switch(opcode) Line 5976  switch(opcode)
5976    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5977    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5978    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
5979    compile_char1_hotpath(common, type, cc, &current->topfallbacks);    compile_char1_trypath(common, type, cc, &current->topbacktracks);
5980    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5981    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5982    JUMPHERE(jump);    JUMPHERE(jump);
5983    free_stack(common, 1);    free_stack(common, 1);
5984    break;    break;
5985    
5986    case OP_EXACT:    case OP_EXACT:
5987    case OP_POSPLUS:    case OP_POSPLUS:
5988    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5989    break;    break;
5990    
5991    case OP_POSSTAR:    case OP_POSSTAR:
# Line 5582  switch(opcode) Line 5999  switch(opcode)
5999    }    }
6000  }  }
6001    
6002  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_ref_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
6003  {  {
6004  DEFINE_COMPILER;  DEFINE_COMPILER;
6005  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5591  pcre_uchar type; Line 6008  pcre_uchar type;
6008  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
6009  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
6010    {    {
6011    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6012    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6013    free_stack(common, 1);    free_stack(common, 1);
6014    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
6015    return;    return;
6016    }    }
6017    
6018  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6019  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_fallback)->hotpath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->trypath);
6020  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6021  free_stack(common, 2);  free_stack(common, 2);
6022  }  }
6023    
6024  static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)
6025  {  {
6026  DEFINE_COMPILER;  DEFINE_COMPILER;
6027    
6028  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6029  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6030  free_stack(common, 1);  if (common->has_set_som && common->mark_ptr != 0)
6031  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);    {
6032      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6033      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6034      free_stack(common, 2);
6035      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6036      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6037      }
6038    else if (common->has_set_som || common->mark_ptr != 0)
6039      {
6040      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6041      free_stack(common, 1);
6042      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6043      }
6044  }  }
6045    
6046  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)
6047  {  {
6048  DEFINE_COMPILER;  DEFINE_COMPILER;
6049  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5630  if (*cc == OP_BRAZERO) Line 6059  if (*cc == OP_BRAZERO)
6059    
6060  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6061    {    {
6062    SLJIT_ASSERT(current->topfallbacks == NULL);    SLJIT_ASSERT(current->topbacktracks == NULL);
6063    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6064    }    }
6065    
6066  if (CURRENT_AS(assert_fallback)->framesize < 0)  if (CURRENT_AS(assert_backtrack)->framesize < 0)
6067    {    {
6068    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6069    
6070    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6071      {      {
6072      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6073      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
6074      free_stack(common, 1);      free_stack(common, 1);
6075      }      }
6076    return;    return;
# Line 5652  if (bra == OP_BRAZERO) Line 6081  if (bra == OP_BRAZERO)
6081    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6082      {      {
6083      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6084      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_fallback)->hotpath);      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(assert_backtrack)->trypath);
6085      free_stack(common, 1);      free_stack(common, 1);
6086      return;      return;
6087      }      }
# Line 5662  if (bra == OP_BRAZERO) Line 6091  if (bra == OP_BRAZERO)
6091    
6092  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
6093    {    {
6094    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr);
6095    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6096    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_backtrack)->framesize * sizeof(sljit_w));
6097    
6098    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6099    }    }
6100  else  else
6101    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6102    
6103  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6104    {    {
6105    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
6106    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));
6107    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6108    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);
6109    JUMPHERE(brajump);    JUMPHERE(brajump);
6110    }    }
6111  }  }
6112    
6113  static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)
6114  {  {
6115  DEFINE_COMPILER;  DEFINE_COMPILER;
6116  int opcode;  int opcode;
6117  int offset = 0;  int offset = 0;
6118  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_backtrack)->localptr;
6119  int stacksize;  int stacksize;
6120  int count;  int count;
6121  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5696  jump_list *jumplist = NULL; Line 6125  jump_list *jumplist = NULL;
6125  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
6126  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6127  pcre_uchar ket;  pcre_uchar ket;
6128  assert_fallback *assert;  assert_backtrack *assert;
6129  BOOL has_alternatives;  BOOL has_alternatives;
6130  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
6131  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
# Line 5715  ket = *(bracketend(ccbegin) - 1 - LINK_S Line 6144  ket = *(bracketend(ccbegin) - 1 - LINK_S
6144  cc += GET(cc, 1);  cc += GET(cc, 1);
6145  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6146  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6147    has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;    has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_backtrack)->u.condfailed != NULL;
6148  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
6149    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
6150  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
# Line 5742  else if (ket == OP_KETRMIN) Line 6171  else if (ket == OP_KETRMIN)
6171      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (opcode >= OP_SBRA || opcode == OP_ONCE)
6172        {        {
6173        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
6174        if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
6175          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_fallback)->recursivehotpath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6176        else        else
6177          {          {
6178          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6179          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_fallback)->recursivehotpath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w), CURRENT_AS(bracket_backtrack)->recursivetrypath);
6180          }          }
6181        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
6182          free_stack(common, 1);          free_stack(common, 1);
6183        }        }
6184      else      else
6185        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6186      }      }
6187    rminlabel = LABEL();    rminlabel = LABEL();
6188    }    }
# Line 5766  else if (bra == OP_BRAZERO) Line 6195  else if (bra == OP_BRAZERO)
6195    
6196  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
6197    {    {
6198    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6199      {      {
6200      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6201      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5821  else if (*cc == OP_ALT) Line 6250  else if (*cc == OP_ALT)
6250    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
6251    }    }
6252    
6253  COMPILE_FALLBACKPATH(current->top);  COMPILE_BACKTRACKPATH(current->top);
6254  if (current->topfallbacks)  if (current->topbacktracks)
6255    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6256    
6257  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6258    {    {
# Line 5831  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 6260  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
6260    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
6261      {      {
6262      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
6263      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
6264      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
6265        {        {
6266        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
# Line 5839  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 6268  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
6268        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr, SLJIT_MEM1(STACK_TOP), assert->framesize * sizeof(sljit_w));
6269        }        }
6270      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
6271      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
6272      }      }
6273    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)    else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
6274      {      {
6275      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
6276      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
6277      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
6278      }      }
6279    else    else
6280      SLJIT_ASSERT(!has_alternatives);      SLJIT_ASSERT(!has_alternatives);
# Line 5857  if (has_alternatives) Line 6286  if (has_alternatives)
6286    do    do
6287      {      {
6288      current->top = NULL;      current->top = NULL;
6289      current->topfallbacks = NULL;      current->topbacktracks = NULL;
6290      current->nextfallbacks = NULL;      current->nextbacktracks = NULL;
6291      if (*cc == OP_ALT)      if (*cc == OP_ALT)
6292        {        {
6293        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
# Line 5870  if (has_alternatives) Line 6299  if (has_alternatives)
6299          else          else
6300            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6301          }          }
6302        compile_hotpath(common, ccprev, cc, current);        compile_trypath(common, ccprev, cc, current);
6303        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6304          return;          return;
6305        }        }
6306    
6307      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
6308      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_trypath. */
6309      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
6310        {        {
6311        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
6312          {          {
6313          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6314          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5893  if (has_alternatives) Line 6322  if (has_alternatives)
6322          }          }
6323        else        else
6324          {          {
6325          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_w));
6326          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
6327            {            {
6328            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5909  if (has_alternatives) Line 6338  if (has_alternatives)
6338        stacksize++;        stacksize++;
6339    
6340      if (stacksize > 0) {      if (stacksize > 0) {
6341        if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6342          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
6343        else        else
6344          {          {
# Line 5939  if (has_alternatives) Line 6368  if (has_alternatives)
6368        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);
6369        }        }
6370    
6371      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);
6372    
6373      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
6374        {        {
# Line 5948  if (has_alternatives) Line 6377  if (has_alternatives)
6377        jumplist = jumplist->next;        jumplist = jumplist->next;
6378        }        }
6379    
6380      COMPILE_FALLBACKPATH(current->top);      COMPILE_BACKTRACKPATH(current->top);
6381      if (current->topfallbacks)      if (current->topbacktracks)
6382        set_jumps(current->topfallbacks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6383      SLJIT_ASSERT(!current->nextfallbacks);      SLJIT_ASSERT(!current->nextbacktracks);
6384      }      }
6385    while (*cc == OP_ALT);    while (*cc == OP_ALT);
6386    SLJIT_ASSERT(!jumplist);    SLJIT_ASSERT(!jumplist);
# Line 5959  if (has_alternatives) Line 6388  if (has_alternatives)
6388    if (cond != NULL)    if (cond != NULL)
6389      {      {
6390      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
6391      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
6392      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
6393    
6394        {        {
# Line 5993  else if (opcode == OP_SBRA || opcode == Line 6422  else if (opcode == OP_SBRA || opcode ==
6422  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
6423    {    {
6424    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
6425    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6426      {      {
6427      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
6428      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
6429      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);      free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize);
6430      }      }
6431    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
6432      {      {
# Line 6007  else if (opcode == OP_ONCE) Line 6436  else if (opcode == OP_ONCE)
6436    
6437    JUMPHERE(once);    JUMPHERE(once);
6438    /* Restore previous localptr */    /* Restore previous localptr */
6439    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6440      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_fallback)->u.framesize * sizeof(sljit_w));      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracket_backtrack)->u.framesize * sizeof(sljit_w));
6441    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
6442      {      {
6443      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
# Line 6021  else if (opcode == OP_ONCE) Line 6450  else if (opcode == OP_ONCE)
6450  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6451    {    {
6452    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6453    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6454    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6455      {      {
6456      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6457      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
6458      JUMPHERE(brazero);      JUMPHERE(brazero);
6459      }      }
6460    free_stack(common, 1);    free_stack(common, 1);
# Line 6034  else if (ket == OP_KETRMIN) Line 6463  else if (ket == OP_KETRMIN)
6463    {    {
6464    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6465    
6466    /* OP_ONCE removes everything in case of a fallback, so we don't    /* OP_ONCE removes everything in case of a backtrack, so we don't
6467    need to explicitly release the STR_PTR. The extra release would    need to explicitly release the STR_PTR. The extra release would
6468    affect badly the free_stack(2) above. */    affect badly the free_stack(2) above. */
6469    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
# Line 6048  else if (ket == OP_KETRMIN) Line 6477  else if (ket == OP_KETRMIN)
6477  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
6478    {    {
6479    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6480    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
6481    JUMPHERE(brazero);    JUMPHERE(brazero);
6482    }    }
6483  }  }
6484    
6485  static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)
6486  {  {
6487  DEFINE_COMPILER;  DEFINE_COMPILER;
6488  int offset;  int offset;
6489  struct sljit_jump *jump;  struct sljit_jump *jump;
6490    
6491  if (CURRENT_AS(bracketpos_fallback)->framesize < 0)  if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
6492    {    {
6493    if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)    if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
6494      {      {
# Line 6069  if (CURRENT_AS(bracketpos_fallback)->fra Line 6498  if (CURRENT_AS(bracketpos_fallback)->fra
6498      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6499      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
6500      }      }
6501    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6502    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
6503    return;    return;
6504    }    }
6505    
6506  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr);
6507  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6508    
6509  if (current->topfallbacks)  if (current->topbacktracks)
6510    {    {
6511    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6512    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6513    /* Drop the stack frame. */    /* Drop the stack frame. */
6514    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
6515    JUMPHERE(jump);    JUMPHERE(jump);
6516    }    }
6517  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_fallback)->framesize * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_w));
6518  }  }
6519    
6520  static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)
6521  {  {
6522  assert_fallback fallback;  assert_backtrack backtrack;
6523    
6524  current->top = NULL;  current->top = NULL;
6525  current->topfallbacks = NULL;  current->topbacktracks = NULL;
6526  current->nextfallbacks = NULL;  current->nextbacktracks = NULL;
6527  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
6528    {    {
6529    /* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */
6530    compile_bracket_hotpath(common, current->cc, current);    compile_bracket_trypath(common, current->cc, current);
6531    compile_bracket_fallbackpath(common, current->top);    compile_bracket_backtrackpath(common, current->top);
6532    }    }
6533  else  else
6534    {    {
6535    memset(&fallback, 0, sizeof(fallback));    memset(&backtrack, 0, sizeof(backtrack));
6536    fallback.common.cc = current->cc;    backtrack.common.cc = current->cc;
6537    fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath;    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;
6538    /* Manual call of compile_assert_hotpath. */    /* Manual call of compile_assert_trypath. */
6539    compile_assert_hotpath(common, current->cc, &fallback, FALSE);    compile_assert_trypath(common, current->cc, &backtrack, FALSE);
6540    }    }
6541  SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
6542  }  }
6543    
6544  static void compile_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)
6545  {  {
6546  DEFINE_COMPILER;  DEFINE_COMPILER;
6547    
6548  while (current)  while (current)
6549    {    {
6550    if (current->nextfallbacks != NULL)    if (current->nextbacktracks != NULL)
6551      set_jumps(current->nextfallbacks, LABEL());      set_jumps(current->nextbacktracks, LABEL());
6552    switch(*current->cc)    switch(*current->cc)
6553      {      {
6554      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6198  while (current) Line 6627  while (current)
6627  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6628      case OP_XCLASS:      case OP_XCLASS:
6629  #endif  #endif
6630      compile_iterator_fallbackpath(common, current);      compile_iterator_backtrackpath(common, current);
6631      break;      break;
6632    
6633      case OP_REF:      case OP_REF:
6634      case OP_REFI:      case OP_REFI: