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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 941 by zherczeg, Tue Feb 28 11:33:34 2012 UTC revision 977 by zherczeg, Sun Jun 17 06:20:52 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 188  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 264  typedef struct recurse_entry { Line 264  typedef struct recurse_entry {
264    int start;    int start;
265  } recurse_entry;  } recurse_entry;
266    
267  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
268    fallback_common common;    backtrack_common common;
269  } recurse_fallback;  } recurse_backtrack;
270    
271  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    
275    /* Local stack area size and variable pointers. */    /* Opcode local area direct map. */
   int localsize;  
276    int *localptrs;    int *localptrs;
277    int cbraptr;    int cbraptr;
278    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
# Line 448  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 466  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 1325  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 1352  if (common->mark_ptr != 0) Line 1353  if (common->mark_ptr != 0)
1353    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
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_SAVED_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();
# Line 1370  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_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
# Line 1621  JUMPHERE(jump); Line 1622  JUMPHERE(jump);
1622  return return_value;  return return_value;
1623  }  }
1624    
1625  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
1626  {  {
1627  DEFINE_COMPILER;  DEFINE_COMPILER;
1628  struct sljit_jump *jump;  struct sljit_jump *jump;
1629    
1630  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
1631    {    {
1632    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1633    return;    return;
1634    }    }
1635    
1636  /* Partial matching mode. */  /* Partial matching mode. */
1637  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1638  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1639  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1640    {    {
1641    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1642    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
1643    }    }
1644  else  else
1645    {    {
# Line 1788  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 1796  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 1804  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 1823  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 1882  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 1919  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 1956  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 2384  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 2437  struct sljit_jump *jump; Line 2439  struct sljit_jump *jump;
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));
# Line 2540  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 2567  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 2606  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 2638  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 2667  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 2731  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 2832  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 2871  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 2910  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 2929  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  fallback_at_str_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 3080  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 3162  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 3235  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 3247  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 3266  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    fallback_at_str_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    fallback_at_str_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    fallback_at_str_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    fallback_at_str_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      {      {
# Line 3317  switch(type) Line 3319  switch(type)
3319        jump[1] = check_str_end(common);        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      if (jump[1] != NULL)      if (jump[1] != NULL)
3324        JUMPHERE(jump[1]);        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    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
3333  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3334    if (common->utf)    if (common->utf)
3335      {      {
# Line 3355  switch(type) Line 3357  switch(type)
3357    return cc;    return cc;
3358    
3359    case OP_ANYBYTE:    case OP_ANYBYTE:
3360    fallback_at_str_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 3368  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    fallback_at_str_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    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
# Line 3387  switch(type) Line 3389  switch(type)
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 3395  switch(type) Line 3397  switch(type)
3397    
3398    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3399    case OP_HSPACE:    case OP_HSPACE:
3400    fallback_at_str_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    fallback_at_str_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    fallback_at_str_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 3445  switch(type) Line 3447  switch(type)
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      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
3450        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));
3451      else      else
3452        {        {
3453        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
# Line 3453  switch(type) Line 3455  switch(type)
3455        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        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);        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);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3458        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
3459        check_partial(common, TRUE);        check_partial(common, TRUE);
3460        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3461        JUMPHERE(jump[1]);        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 3476  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]);
# Line 3506  switch(type) Line 3508  switch(type)
3508    return cc;    return cc;
3509    
3510    case OP_EOD:    case OP_EOD:
3511    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3512    check_partial(common, FALSE);    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 3523  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_GREATER_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 3549  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      {      {
3560      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3561      check_partial(common, FALSE);      check_partial(common, FALSE);
3562      }      }
3563    return cc;    return cc;
# Line 3564  switch(type) Line 3566  switch(type)
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);    check_partial(common, FALSE);
3571    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3572    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3574  switch(type) Line 3576  switch(type)
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));
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)      if (common->mode == JIT_COMPILE)
3579        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3580      else      else
3581        {        {
3582        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3583        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
3584        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));
3585        check_partial(common, TRUE);        check_partial(common, TRUE);
3586        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3587        JUMPHERE(jump[1]);        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 3606  switch(type) Line 3608  switch(type)
3608    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
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    fallback_at_str_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 3627  switch(type) Line 3629  switch(type)
3629      c = *cc;      c = *cc;
3630    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
3631      {      {
3632      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3633      return cc + length;      return cc + length;
3634      }      }
3635    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 3635  switch(type) Line 3637  switch(type)
3637    if (ispowerof2(bit))    if (ispowerof2(bit))
3638      {      {
3639      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3640      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3641      return cc + length;      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    fallback_at_str_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 3658  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 3688  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 3696  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 + length;    return cc + length;
3710    
3711    case OP_CLASS:    case OP_CLASS:
3712    case OP_NCLASS:    case OP_NCLASS:
3713    fallback_at_str_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 3721  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 3731  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 3740  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 3754  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);
# Line 3764  switch(type) Line 3767  switch(type)
3767      {      {
3768      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));
3769      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3770      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3771      }      }
3772    check_start_used_ptr(common);    check_start_used_ptr(common);
3773    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3773  SLJIT_ASSERT_STOP(); Line 3776  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 3825  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 3847  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. */      /* 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));
# Line 3856  if (!common->jscript_compat) Line 3859  if (!common->jscript_compat)
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;
# Line 3904  struct sljit_jump *nopartial; Line 3907  struct sljit_jump *nopartial;
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. */  /* 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 3921  if (common->utf && *cc == OP_REFI) Line 3924  if (common->utf && *cc == OP_REFI)
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    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
3927      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3928    else    else
3929      {      {
3930      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3931      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3932      check_partial(common, FALSE);      check_partial(common, FALSE);
3933      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3934      JUMPHERE(nopartial);      JUMPHERE(nopartial);
3935      }      }
3936    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3942  else Line 3945  else
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);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3947    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
3948      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
3949    
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)    if (common->mode != JIT_COMPILE)
3954      {      {
# Line 3957  else Line 3960  else
3960      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3961      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3962      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));
3963      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));
3964      JUMPHERE(partial);      JUMPHERE(partial);
3965      check_partial(common, FALSE);      check_partial(common, FALSE);
3966      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3967      JUMPHERE(nopartial);      JUMPHERE(nopartial);
3968      }      }
3969    }    }
# Line 3968  else Line 3971  else
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 3987  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 4039  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 4074  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 4092  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 4106  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 4119  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 4172  if (entry->entry == NULL) Line 4175  if (entry->entry == NULL)
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;  struct sljit_label *save_leavelabel = common->leavelabel;
# Line 4205  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 4215  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 4238  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;  common->leavelabel = NULL;
4246  common->leave = NULL;  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;      common->leavelabel = save_leavelabel;
# Line 4307  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;      common->leavelabel = save_leavelabel;
# Line 4316  while (1) Line 4319  while (1)
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 4393  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 4406  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 4436  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    
# Line 4622  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 4652  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 4669  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 4693  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 4728  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 4745  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 4754  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 4768  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 4804  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 4853  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 << 8) | (common->ovector_start / sizeof(sljit_w)));      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 4894  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 4963  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 4998  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 5014  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          {
5024        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);
5025          /* Drop STR_PTR for greedy plus quantifier. */
5026          if (bra != OP_BRAZERO)
5027            free_stack(common, 1);
5028          }
5029      else      else
5030        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5031        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5032      }      }
5033    else    else
5034      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5035    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5036    }    }
5037    
5038  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5039    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
5040    
5041  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5042    {    {
5043    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5044    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
5045    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5046      {      {
5047      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5048      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5049      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5050      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5051      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5052        {        {
5053        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5054        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5048  if (bra == OP_BRAMINZERO) Line 5056  if (bra == OP_BRAMINZERO)
5056      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5057        free_stack(common, 1);        free_stack(common, 1);
5058      }      }
5059    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5060    }    }
5061    
5062  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
# Line 5061  cc += 1 + LINK_SIZE; Line 5069  cc += 1 + LINK_SIZE;
5069  return cc;  return cc;
5070  }  }
5071    
5072  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)
5073  {  {
5074  DEFINE_COMPILER;  DEFINE_COMPILER;
5075  fallback_common *fallback;  backtrack_common *backtrack;
5076  pcre_uchar opcode;  pcre_uchar opcode;
5077  int localptr;  int localptr;
5078  int cbraprivptr = 0;  int cbraprivptr = 0;
# Line 5077  int stack; Line 5085  int stack;
5085  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5086  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5087    
5088  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5089  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5090    {    {
5091    zero = TRUE;    zero = TRUE;
# Line 5087  if (*cc == OP_BRAPOSZERO) Line 5095  if (*cc == OP_BRAPOSZERO)
5095  opcode = *cc;  opcode = *cc;
5096  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
5097  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
5098  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
5099  switch(opcode)  switch(opcode)
5100    {    {
5101    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5109  switch(opcode) Line 5117  switch(opcode)
5117    }    }
5118    
5119  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5120  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5121  if (framesize < 0)  if (framesize < 0)
5122    {    {
5123    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5124    if (!zero)    if (!zero)
5125      stacksize++;      stacksize++;
5126    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5127    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5128    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
5129    
# Line 5139  else Line 5147  else
5147      stacksize++;      stacksize++;
5148    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5149      stacksize++;      stacksize++;
5150    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5151    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5152    
5153    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 5166  if (opcode == OP_CBRAPOS || opcode == OP Line 5174  if (opcode == OP_CBRAPOS || opcode == OP
5174  loop = LABEL();  loop = LABEL();
5175  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
5176    {    {
5177    fallback->top = NULL;    backtrack->top = NULL;
5178    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
5179    cc += GET(cc, 1);    cc += GET(cc, 1);
5180    
5181    compile_hotpath(common, ccbegin, cc, fallback);    compile_trypath(common, ccbegin, cc, backtrack);
5182    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5183      return NULL;      return NULL;
5184    
# Line 5231  while (*cc != OP_KETRPOS) Line 5239  while (*cc != OP_KETRPOS)
5239    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5240    flush_stubs(common);    flush_stubs(common);
5241    
5242    compile_fallbackpath(common, fallback->top);    compile_backtrackpath(common, backtrack->top);
5243    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5244      return NULL;      return NULL;
5245    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
5246    
5247    if (framesize < 0)    if (framesize < 0)
5248      {      {
# Line 5264  while (*cc != OP_KETRPOS) Line 5272  while (*cc != OP_KETRPOS)
5272    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
5273    }    }
5274    
5275  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
5276  if (!zero)  if (!zero)
5277    {    {
5278    if (framesize < 0)    if (framesize < 0)
5279      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));
5280    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [localptr] above. */
5281      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));
5282    }    }
5283    
5284  /* None of them matched. */  /* None of them matched. */
# Line 5371  if (end != NULL) Line 5379  if (end != NULL)
5379  return cc;  return cc;
5380  }  }
5381    
5382  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)
5383  {  {
5384  DEFINE_COMPILER;  DEFINE_COMPILER;
5385  fallback_common *fallback;  backtrack_common *backtrack;
5386  pcre_uchar opcode;  pcre_uchar opcode;
5387  pcre_uchar type;  pcre_uchar type;
5388  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 5383  jump_list *nomatch = NULL; Line 5391  jump_list *nomatch = NULL;
5391  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5392  struct sljit_label *label;  struct sljit_label *label;
5393    
5394  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5395    
5396  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
5397    
# Line 5410  switch(opcode) Line 5418  switch(opcode)
5418        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5419    
5420      label = LABEL();      label = LABEL();
5421      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5422      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
5423        {        {
5424        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5430  switch(opcode) Line 5438  switch(opcode)
5438      }      }
5439    else    else
5440      {      {
5441        if (opcode == OP_PLUS)
5442          compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5443      allocate_stack(common, 2);      allocate_stack(common, 2);
5444      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5445      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5446      label = LABEL();      label = LABEL();
5447      compile_char1_hotpath(common, type, cc, &nomatch);      compile_char1_trypath(common, type, cc, &nomatch);
5448      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5449      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))
5450        {        {
# Line 5449  switch(opcode) Line 5459  switch(opcode)
5459        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
5460        }        }
5461      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
5462      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
5463        add_jump(compiler, &fallback->topfallbacks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1));
         CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));  
5464      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5465      }      }
5466    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5467    break;    break;
5468    
5469    case OP_MINSTAR:    case OP_MINSTAR:
5470    case OP_MINPLUS:    case OP_MINPLUS:
5471      if (opcode == OP_MINPLUS)
5472        compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5473    allocate_stack(common, 1);    allocate_stack(common, 1);
5474    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5475    if (opcode == OP_MINPLUS)    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
     add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));  
   FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  
5476    break;    break;
5477    
5478    case OP_MINUPTO:    case OP_MINUPTO:
# Line 5472  switch(opcode) Line 5481  switch(opcode)
5481    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5482    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
5483    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
5484      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5485    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5486    break;    break;
5487    
5488    case OP_QUERY:    case OP_QUERY:
# Line 5481  switch(opcode) Line 5490  switch(opcode)
5490    allocate_stack(common, 1);    allocate_stack(common, 1);
5491    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5492    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
5493      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5494    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
5495    break;    break;
5496    
5497    case OP_EXACT:    case OP_EXACT:
5498    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5499    label = LABEL();    label = LABEL();
5500    compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);    compile_char1_trypath(common, type, cc, &backtrack->topbacktracks);
5501    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
5502    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
5503    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
# Line 5502  switch(opcode) Line 5511  switch(opcode)
5511      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);
5512    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5513    label = LABEL();    label = LABEL();
5514    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
5515    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5516    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
5517      {      {
# Line 5519  switch(opcode) Line 5528  switch(opcode)
5528      }      }
5529    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
5530    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
5531      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));
5532    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5533    break;    break;
5534    
5535    case OP_POSQUERY:    case OP_POSQUERY:
5536    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5537    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_trypath(common, type, cc, &nomatch);
5538    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);
5539    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
5540    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 5540  decrease_call_count(common); Line 5549  decrease_call_count(common);
5549  return end;  return end;
5550  }  }
5551    
5552  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)
5553  {  {
5554  DEFINE_COMPILER;  DEFINE_COMPILER;
5555  fallback_common *fallback;  backtrack_common *backtrack;
5556    
5557  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5558    
5559  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
5560    {    {
5561    add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5562    return cc + 1;    return cc + 1;
5563    }    }
5564    
# Line 5569  else Line 5578  else
5578    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);
5579  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5580  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));
5581  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));
5582  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));
5583  if (common->acceptlabel == NULL)  if (common->acceptlabel == NULL)
5584    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
# Line 5580  if (common->acceptlabel == NULL) Line 5589  if (common->acceptlabel == NULL)
5589    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));
5590  else  else
5591    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);
5592  add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
5593  return cc + 1;  return cc + 1;
5594  }  }
5595    
5596  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)
5597  {  {
5598  DEFINE_COMPILER;  DEFINE_COMPILER;
5599  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
# Line 5600  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5609  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5609  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
5610  }  }
5611    
5612  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)
5613  {  {
5614  DEFINE_COMPILER;  DEFINE_COMPILER;
5615  fallback_common *fallback;  backtrack_common *backtrack;
5616    
5617  while (cc < ccend)  while (cc < ccend)
5618    {    {
# Line 5639  while (cc < ccend) Line 5648  while (cc < ccend)
5648      case OP_NOT:      case OP_NOT:
5649      case OP_NOTI:      case OP_NOTI:
5650      case OP_REVERSE:      case OP_REVERSE:
5651      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);
5652      break;      break;
5653    
5654      case OP_SET_SOM:      case OP_SET_SOM:
5655      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5656      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5657      allocate_stack(common, 1);      allocate_stack(common, 1);
5658      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
# Line 5654  while (cc < ccend) Line 5663  while (cc < ccend)
5663      case OP_CHAR:      case OP_CHAR:
5664      case OP_CHARI:      case OP_CHARI:
5665      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
5666        cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_charn_trypath(common, cc, ccend, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
5667      else      else
5668        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);
5669      break;      break;
5670    
5671      case OP_STAR:      case OP_STAR:
# Line 5724  while (cc < ccend) Line 5733  while (cc < ccend)
5733      case OP_TYPEPOSPLUS:      case OP_TYPEPOSPLUS:
5734      case OP_TYPEPOSQUERY:      case OP_TYPEPOSQUERY:
5735      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
5736      cc = compile_iterator_hotpath(common, cc, parent);      cc = compile_iterator_trypath(common, cc, parent);
5737      break;      break;
5738    
5739      case OP_CLASS:      case OP_CLASS:
5740      case OP_NCLASS:      case OP_NCLASS:
5741      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)
5742        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_trypath(common, cc, parent);
5743      else      else
5744        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);
5745      break;      break;
5746    
5747  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5748      case OP_XCLASS:      case OP_XCLASS:
5749      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)
5750        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_trypath(common, cc, parent);
5751      else      else
5752        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);
5753      break;      break;
5754  #endif  #endif
5755    
5756      case OP_REF:      case OP_REF:
5757      case OP_REFI:      case OP_REFI:
5758      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)
5759        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_trypath(common, cc, parent);
5760      else      else
5761        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);
5762      break;      break;
5763    
5764      case OP_RECURSE:      case OP_RECURSE:
5765      cc = compile_recurse_hotpath(common, cc, parent);      cc = compile_recurse_trypath(common, cc, parent);
5766      break;      break;
5767    
5768      case OP_ASSERT:      case OP_ASSERT:
5769      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
5770      case OP_ASSERTBACK:      case OP_ASSERTBACK:
5771      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
5772      PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
5773      cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);      cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
5774      break;      break;
5775    
5776      case OP_BRAMINZERO:      case OP_BRAMINZERO:
5777      PUSH_FALLBACK_NOVALUE(sizeof(braminzero_fallback), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(braminzero_backtrack), cc);
5778      cc = bracketend(cc + 1);      cc = bracketend(cc + 1);
5779      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)      if (*(cc - 1 - LINK_SIZE) != OP_KETRMIN)
5780        {        {
# Line 5778  while (cc < ccend) Line 5787  while (cc < ccend)
5787        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5788        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
5789        }        }
5790      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->trypath = LABEL();
5791      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
5792        decrease_call_count(common);        decrease_call_count(common);
5793      break;      break;
# Line 5791  while (cc < ccend) Line 5800  while (cc < ccend)
5800      case OP_SBRA:      case OP_SBRA:
5801      case OP_SCBRA:      case OP_SCBRA:
5802      case OP_SCOND:      case OP_SCOND:
5803      cc = compile_bracket_hotpath(common, cc, parent);      cc = compile_bracket_trypath(common, cc, parent);
5804      break;      break;
5805    
5806      case OP_BRAZERO:      case OP_BRAZERO:
5807      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
5808        cc = compile_bracket_hotpath(common, cc, parent);        cc = compile_bracket_trypath(common, cc, parent);
5809      else      else
5810        {        {
5811        PUSH_FALLBACK_NOVALUE(sizeof(assert_fallback), cc);        PUSH_BACKTRACK_NOVALUE(sizeof(assert_backtrack), cc);
5812        cc = compile_assert_hotpath(common, cc, FALLBACK_AS(assert_fallback), FALSE);        cc = compile_assert_trypath(common, cc, BACKTRACK_AS(assert_backtrack), FALSE);
5813        }        }
5814      break;      break;
5815    
# Line 5809  while (cc < ccend) Line 5818  while (cc < ccend)
5818      case OP_SBRAPOS:      case OP_SBRAPOS:
5819      case OP_SCBRAPOS:      case OP_SCBRAPOS:
5820      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
5821      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_trypath(common, cc, parent);
5822      break;      break;
5823    
5824      case OP_MARK:      case OP_MARK:
5825      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5826      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
5827      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5828      allocate_stack(common, 1);      allocate_stack(common, 1);
# Line 5826  while (cc < ccend) Line 5835  while (cc < ccend)
5835      break;      break;
5836    
5837      case OP_COMMIT:      case OP_COMMIT:
5838      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
5839      cc += 1;      cc += 1;
5840      break;      break;
5841    
5842      case OP_FAIL:      case OP_FAIL:
5843      case OP_ACCEPT:      case OP_ACCEPT:
5844      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
5845      cc = compile_fail_accept_hotpath(common, cc, parent);      cc = compile_fail_accept_trypath(common, cc, parent);
5846      break;      break;
5847    
5848      case OP_CLOSE:      case OP_CLOSE:
5849      cc = compile_close_hotpath(common, cc);      cc = compile_close_trypath(common, cc);
5850      break;      break;
5851    
5852      case OP_SKIPZERO:      case OP_SKIPZERO:
# Line 5854  while (cc < ccend) Line 5863  while (cc < ccend)
5863  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
5864  }  }
5865    
5866  #undef PUSH_FALLBACK  #undef PUSH_BACKTRACK
5867  #undef PUSH_FALLBACK_NOVALUE  #undef PUSH_BACKTRACK_NOVALUE
5868  #undef FALLBACK_AS  #undef BACKTRACK_AS
5869    
5870  #define COMPILE_FALLBACKPATH(current) \  #define COMPILE_BACKTRACKPATH(current) \
5871    do \    do \
5872      { \      { \
5873      compile_fallbackpath(common, (current)); \      compile_backtrackpath(common, (current)); \
5874      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
5875        return; \        return; \
5876      } \      } \
# Line 5869  SLJIT_ASSERT(cc == ccend); Line 5878  SLJIT_ASSERT(cc == ccend);
5878    
5879  #define CURRENT_AS(type) ((type *)current)  #define CURRENT_AS(type) ((type *)current)
5880    
5881  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_backtrackpath(compiler_common *common, struct backtrack_common *current)
5882  {  {
5883  DEFINE_COMPILER;  DEFINE_COMPILER;
5884  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 5878  pcre_uchar type; Line 5887  pcre_uchar type;
5887  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5888  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5889  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5890    jump_list *jumplist = NULL;
5891    
5892  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);
5893    
# Line 5889  switch(opcode) Line 5899  switch(opcode)
5899    case OP_CRRANGE:    case OP_CRRANGE:
5900    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
5901      {      {
5902      set_jumps(current->topfallbacks, LABEL());      set_jumps(current->topbacktracks, LABEL());
5903      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5904      free_stack(common, 1);      free_stack(common, 1);
5905      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);
5906      }      }
5907    else    else
5908      {      {
5909      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode <= OP_PLUS || opcode == OP_UPTO)
5910        arg2 = 0;        arg2 = 0;
5911      else if (opcode == OP_PLUS)      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5912        arg2 = 1;      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);
5913      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, arg2 + 1);      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0, SLJIT_IMM, 1);
     OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);  
5914      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5915      skip_char_back(common);      skip_char_back(common);
5916      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5917      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5918      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
5919        set_jumps(current->topfallbacks, LABEL());        set_jumps(current->topbacktracks, LABEL());
5920      JUMPHERE(jump);      JUMPHERE(jump);
5921      free_stack(common, 2);      free_stack(common, 2);
5922        if (opcode == OP_PLUS)
5923          set_jumps(current->topbacktracks, LABEL());
5924      }      }
5925    break;    break;
5926    
5927    case OP_MINSTAR:    case OP_MINSTAR:
5928    case OP_MINPLUS:    case OP_MINPLUS:
5929    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5930    if (opcode == OP_MINPLUS)    compile_char1_trypath(common, type, cc, &jumplist);
     {  
     set_jumps(current->topfallbacks, LABEL());  
     current->topfallbacks = NULL;  
     }  
   compile_char1_hotpath(common, type, cc, &current->topfallbacks);  
5931    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5932    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5933    set_jumps(current->topfallbacks, LABEL());    set_jumps(jumplist, LABEL());
5934    free_stack(common, 1);    free_stack(common, 1);
5935      if (opcode == OP_MINPLUS)
5936        set_jumps(current->topbacktracks, LABEL());
5937    break;    break;
5938    
5939    case OP_MINUPTO:    case OP_MINUPTO:
5940    case OP_CRMINRANGE:    case OP_CRMINRANGE:
5941    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
5942      {      {
     set_jumps(current->topfallbacks, LABEL());  
     current->topfallbacks = NULL;  
5943      label = LABEL();      label = LABEL();
5944        set_jumps(current->topbacktracks, label);
5945      }      }
5946    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5947    compile_char1_hotpath(common, type, cc, &current->topfallbacks);    compile_char1_trypath(common, type, cc, &jumplist);
5948    
5949    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5950    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 5948  switch(opcode) Line 5955  switch(opcode)
5955      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);
5956    
5957    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && arg1 == 0)
5958      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5959    else    else
5960      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);
5961    
5962    set_jumps(current->topfallbacks, LABEL());    set_jumps(jumplist, LABEL());
5963    free_stack(common, 2);    free_stack(common, 2);
5964    break;    break;
5965    
5966    case OP_QUERY:    case OP_QUERY:
5967    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5968    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5969    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);
5970    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5971    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5972    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5973    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5974    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5975    JUMPHERE(jump);    JUMPHERE(jump);
5976    free_stack(common, 1);    free_stack(common, 1);
5977    break;    break;
# Line 5973  switch(opcode) Line 5980  switch(opcode)
5980    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5981    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5982    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
5983    compile_char1_hotpath(common, type, cc, &current->topfallbacks);    compile_char1_trypath(common, type, cc, &jumplist);
5984    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->trypath);
5985    set_jumps(current->topfallbacks, LABEL());    set_jumps(jumplist, LABEL());
5986    JUMPHERE(jump);    JUMPHERE(jump);
5987    free_stack(common, 1);    free_stack(common, 1);
5988    break;    break;
5989    
5990    case OP_EXACT:    case OP_EXACT:
5991    case OP_POSPLUS:    case OP_POSPLUS:
5992    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
5993    break;    break;
5994    
5995    case OP_POSSTAR:    case OP_POSSTAR:
# Line 5996  switch(opcode) Line 6003  switch(opcode)
6003    }    }
6004  }  }
6005    
6006  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)
6007  {  {
6008  DEFINE_COMPILER;  DEFINE_COMPILER;
6009  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6005  pcre_uchar type; Line 6012  pcre_uchar type;
6012  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
6013  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
6014    {    {
6015    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6016    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6017    free_stack(common, 1);    free_stack(common, 1);
6018    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);
6019    return;    return;
6020    }    }
6021    
6022  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6023  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);
6024  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6025  free_stack(common, 2);  free_stack(common, 2);
6026  }  }
6027    
6028  static void compile_recurse_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_recurse_backtrackpath(compiler_common *common, struct backtrack_common *current)
6029  {  {
6030  DEFINE_COMPILER;  DEFINE_COMPILER;
6031    
6032  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topbacktracks, LABEL());
6033    
6034  if (common->has_set_som && common->mark_ptr != 0)  if (common->has_set_som && common->mark_ptr != 0)
6035    {    {
# Line 6040  else if (common->has_set_som || common-> Line 6047  else if (common->has_set_som || common->
6047    }    }
6048  }  }
6049    
6050  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_backtrackpath(compiler_common *common, struct backtrack_common *current)
6051  {  {
6052  DEFINE_COMPILER;  DEFINE_COMPILER;
6053  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6056  if (*cc == OP_BRAZERO) Line 6063  if (*cc == OP_BRAZERO)
6063    
6064  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6065    {    {
6066    SLJIT_ASSERT(current->topfallbacks == NULL);    SLJIT_ASSERT(current->topbacktracks == NULL);
6067    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6068    }    }
6069    
6070  if (CURRENT_AS(assert_fallback)->framesize < 0)  if (CURRENT_AS(assert_backtrack)->framesize < 0)
6071    {    {
6072    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6073    
6074    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6075      {      {
6076      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6077      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);
6078      free_stack(common, 1);      free_stack(common, 1);
6079      }      }
6080    return;    return;
# Line 6078  if (bra == OP_BRAZERO) Line 6085  if (bra == OP_BRAZERO)
6085    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)    if (*cc == OP_ASSERT_NOT || *cc == OP_ASSERTBACK_NOT)
6086      {      {
6087      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6088      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);
6089      free_stack(common, 1);      free_stack(common, 1);
6090      return;      return;
6091      }      }
# Line 6088  if (bra == OP_BRAZERO) Line 6095  if (bra == OP_BRAZERO)
6095    
6096  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)  if (*cc == OP_ASSERT || *cc == OP_ASSERTBACK)
6097    {    {
6098    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);
6099    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6100    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));
6101    
6102    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6103    }    }
6104  else  else
6105    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6106    
6107  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6108    {    {
6109    /* We know there is enough place on the stack. */    /* We know there is enough place on the stack. */
6110    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));
6111    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6112    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_fallback)->hotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(assert_backtrack)->trypath);
6113    JUMPHERE(brajump);    JUMPHERE(brajump);
6114    }    }
6115  }  }
6116    
6117  static void compile_bracket_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_bracket_backtrackpath(compiler_common *common, struct backtrack_common *current)
6118  {  {
6119  DEFINE_COMPILER;  DEFINE_COMPILER;
6120  int opcode;  int opcode;
6121  int offset = 0;  int offset = 0;
6122  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_backtrack)->localptr;
6123  int stacksize;  int stacksize;
6124  int count;  int count;
6125  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 6122  jump_list *jumplist = NULL; Line 6129  jump_list *jumplist = NULL;
6129  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
6130  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6131  pcre_uchar ket;  pcre_uchar ket;
6132  assert_fallback *assert;  assert_backtrack *assert;
6133  BOOL has_alternatives;  BOOL has_alternatives;
6134  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
6135  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
# Line 6141  ket = *(bracketend(ccbegin) - 1 - LINK_S Line 6148  ket = *(bracketend(ccbegin) - 1 - LINK_S
6148  cc += GET(cc, 1);  cc += GET(cc, 1);
6149  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6150  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6151    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;
6152  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
6153    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
6154  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 6151  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC) Line 6158  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC)
6158    
6159  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6160    {    {
6161    if (bra != OP_BRAZERO)    if (bra == OP_BRAZERO)
     free_stack(common, 1);  
   else  
6162      {      {
6163      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6164      free_stack(common, 1);      free_stack(common, 1);
# Line 6168  else if (ket == OP_KETRMIN) Line 6173  else if (ket == OP_KETRMIN)
6173      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (opcode >= OP_SBRA || opcode == OP_ONCE)
6174        {        {
6175        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
6176        if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
6177          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);
6178        else        else
6179          {          {
6180          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6181          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);
6182          }          }
6183        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
6184          free_stack(common, 1);          free_stack(common, 1);
6185        }        }
6186      else      else
6187        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->recursivehotpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6188      }      }
6189    rminlabel = LABEL();    rminlabel = LABEL();
6190    }    }
# Line 6192  else if (bra == OP_BRAZERO) Line 6197  else if (bra == OP_BRAZERO)
6197    
6198  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
6199    {    {
6200    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6201      {      {
6202      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6203      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 6247  else if (*cc == OP_ALT) Line 6252  else if (*cc == OP_ALT)
6252    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
6253    }    }
6254    
6255  COMPILE_FALLBACKPATH(current->top);  COMPILE_BACKTRACKPATH(current->top);
6256  if (current->topfallbacks)  if (current->topbacktracks)
6257    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6258    
6259  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
6260    {    {
# Line 6257  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 6262  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
6262    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)
6263      {      {
6264      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
6265      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
6266      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))
6267        {        {
6268        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 6265  if (SLJIT_UNLIKELY(opcode == OP_COND) || Line 6270  if (SLJIT_UNLIKELY(opcode == OP_COND) ||
6270        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));
6271        }        }
6272      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
6273      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.assert->condfailed, LABEL());
6274      }      }
6275    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)    else if (CURRENT_AS(bracket_backtrack)->u.condfailed != NULL)
6276      {      {
6277      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
6278      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
6279      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_backtrack)->u.condfailed, LABEL());
6280      }      }
6281    else    else
6282      SLJIT_ASSERT(!has_alternatives);      SLJIT_ASSERT(!has_alternatives);
# Line 6283  if (has_alternatives) Line 6288  if (has_alternatives)
6288    do    do
6289      {      {
6290      current->top = NULL;      current->top = NULL;
6291      current->topfallbacks = NULL;      current->topbacktracks = NULL;
6292      current->nextfallbacks = NULL;      current->nextbacktracks = NULL;
6293      if (*cc == OP_ALT)      if (*cc == OP_ALT)
6294        {        {
6295        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
# Line 6296  if (has_alternatives) Line 6301  if (has_alternatives)
6301          else          else
6302            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6303          }          }
6304        compile_hotpath(common, ccprev, cc, current);        compile_trypath(common, ccprev, cc, current);
6305        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6306          return;          return;
6307        }        }
6308    
6309      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
6310      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_trypath. */
6311      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
6312        {        {
6313        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)        if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)
6314          {          {
6315          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
6316          /* TMP2 which is set here used by OP_KETRMAX below. */          /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 6319  if (has_alternatives) Line 6324  if (has_alternatives)
6324          }          }
6325        else        else
6326          {          {
6327          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));
6328          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
6329            {            {
6330            /* TMP2 which is set here used by OP_KETRMAX below. */            /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 6335  if (has_alternatives) Line 6340  if (has_alternatives)
6340        stacksize++;        stacksize++;
6341    
6342      if (stacksize > 0) {      if (stacksize > 0) {
6343        if (opcode != OP_ONCE || CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6344          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
6345        else        else
6346          {          {
# Line 6365  if (has_alternatives) Line 6370  if (has_alternatives)
6370        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);
6371        }        }
6372    
6373      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->althotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alttrypath);
6374    
6375      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
6376        {        {
# Line 6374  if (has_alternatives) Line 6379  if (has_alternatives)
6379        jumplist = jumplist->next;        jumplist = jumplist->next;
6380        }        }
6381    
6382      COMPILE_FALLBACKPATH(current->top);      COMPILE_BACKTRACKPATH(current->top);
6383      if (current->topfallbacks)      if (current->topbacktracks)
6384        set_jumps(current->topfallbacks, LABEL());        set_jumps(current->topbacktracks, LABEL());
6385      SLJIT_ASSERT(!current->nextfallbacks);      SLJIT_ASSERT(!current->nextbacktracks);
6386      }      }
6387    while (*cc == OP_ALT);    while (*cc == OP_ALT);
6388    SLJIT_ASSERT(!jumplist);    SLJIT_ASSERT(!jumplist);
# Line 6385  if (has_alternatives) Line 6390  if (has_alternatives)
6390    if (cond != NULL)    if (cond != NULL)
6391      {      {
6392      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
6393      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
6394      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)
6395    
6396        {        {
# Line 6419  else if (opcode == OP_SBRA || opcode == Line 6424  else if (opcode == OP_SBRA || opcode ==
6424  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
6425    {    {
6426    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
6427    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6428      {      {
6429      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
6430      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
6431      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);      free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize);
6432      }      }
6433    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
6434      {      {
# Line 6433  else if (opcode == OP_ONCE) Line 6438  else if (opcode == OP_ONCE)
6438    
6439    JUMPHERE(once);    JUMPHERE(once);
6440    /* Restore previous localptr */    /* Restore previous localptr */
6441    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
6442      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));
6443    else if (ket == OP_KETRMIN)    else if (ket == OP_KETRMIN)
6444      {      {
6445      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
# Line 6447  else if (opcode == OP_ONCE) Line 6452  else if (opcode == OP_ONCE)
6452  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6453    {    {
6454    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6455    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_fallback)->recursivehotpath);    if (bra != OP_BRAZERO)
6456        free_stack(common, 1);
6457      CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursivetrypath);
6458    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
6459      {      {
6460      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6461      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
6462      JUMPHERE(brazero);      JUMPHERE(brazero);
6463        free_stack(common, 1);
6464      }      }
   free_stack(common, 1);  
6465    }    }
6466  else if (ket == OP_KETRMIN)  else if (ket == OP_KETRMIN)
6467    {    {
6468    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6469    
6470    /* 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
6471    need to explicitly release the STR_PTR. The extra release would    need to explicitly release the STR_PTR. The extra release would
6472    affect badly the free_stack(2) above. */    affect badly the free_stack(2) above. */
6473    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
# Line 6474  else if (ket == OP_KETRMIN) Line 6481  else if (ket == OP_KETRMIN)
6481  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
6482    {    {
6483    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6484    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_fallback)->zerohotpath);    JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->zerotrypath);
6485    JUMPHERE(brazero);    JUMPHERE(brazero);
6486    }    }
6487  }  }
6488    
6489  static void compile_bracketpos_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_bracketpos_backtrackpath(compiler_common *common, struct backtrack_common *current)
6490  {  {
6491  DEFINE_COMPILER;  DEFINE_COMPILER;
6492  int offset;  int offset;
6493  struct sljit_jump *jump;  struct sljit_jump *jump;
6494    
6495  if (CURRENT_AS(bracketpos_fallback)->framesize < 0)  if (CURRENT_AS(bracketpos_backtrack)->framesize < 0)
6496    {    {
6497    if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)    if (*current->cc == OP_CBRAPOS || *current->cc == OP_SCBRAPOS)
6498      {      {
# Line 6495  if (CURRENT_AS(bracketpos_fallback)->fra Line 6502  if (CURRENT_AS(bracketpos_fallback)->fra
6502      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6503      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);
6504      }      }
6505    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6506    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
6507    return;    return;
6508    }    }
6509    
6510  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);
6511  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6512    
6513  if (current->topfallbacks)  if (current->topbacktracks)
6514    {    {
6515    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6516    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topbacktracks, LABEL());
6517    /* Drop the stack frame. */    /* Drop the stack frame. */
6518    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
6519    JUMPHERE(jump);    JUMPHERE(jump);
6520    }    }
6521  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));
6522  }  }
6523    
6524  static void compile_braminzero_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_braminzero_backtrackpath(compiler_common *common, struct backtrack_common *current)
6525  {  {
6526  assert_fallback fallback;  assert_backtrack backtrack;
6527    
6528  current->top = NULL;  current->top = NULL;
6529  current->topfallbacks = NULL;  current->topbacktracks = NULL;
6530  current->nextfallbacks = NULL;  current->nextbacktracks = NULL;
6531  if (current->cc[1] > OP_ASSERTBACK_NOT)  if (current->cc[1] > OP_ASSERTBACK_NOT)
6532    {    {
6533    /* Manual call of compile_bracket_hotpath and compile_bracket_fallbackpath. */    /* Manual call of compile_bracket_trypath and compile_bracket_backtrackpath. */
6534    compile_bracket_hotpath(common, current->cc, current);    compile_bracket_trypath(common, current->cc, current);
6535    compile_bracket_fallbackpath(common, current->top);    compile_bracket_backtrackpath(common, current->top);
6536    }    }
6537  else  else
6538    {    {
6539    memset(&fallback, 0, sizeof(fallback));    memset(&backtrack, 0, sizeof(backtrack));
6540    fallback.common.cc = current->cc;    backtrack.common.cc = current->cc;
6541    fallback.hotpath = CURRENT_AS(braminzero_fallback)->hotpath;    backtrack.trypath = CURRENT_AS(braminzero_backtrack)->trypath;
6542    /* Manual call of compile_assert_hotpath. */    /* Manual call of compile_assert_trypath. */
6543    compile_assert_hotpath(common, current->cc, &fallback, FALSE);    compile_assert_trypath(common, current->cc, &backtrack, FALSE);
6544    }    }
6545  SLJIT_ASSERT(!current->nextfallbacks && !current->topfallbacks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
6546  }  }
6547    
6548  static void compile_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_backtrackpath(compiler_common *common, struct backtrack_common *current)
6549  {  {
6550  DEFINE_COMPILER;  DEFINE_COMPILER;
6551    
6552  while (current)  while (current)
6553    {    {
6554    if (current->nextfallbacks != NULL)    if (current->nextbacktracks != NULL)
6555      set_jumps(current->nextfallbacks, LABEL());      set_jumps(current->nextbacktracks, LABEL());
6556    switch(*current->cc)    switch(*current->cc)
6557      {      {
6558      case OP_SET_SOM:      case OP_SET_SOM:
# Line 6624  while (current) Line 6631  while (current)
6631  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6632      case OP_XCLASS:      case OP_XCLASS:
6633  #endif  #endif
6634      compile_iterator_fallbackpath(common, current);      compile_iterator_backtrackpath(common, current);
6635      break;      break;
6636    
6637      case OP_REF:      case OP_REF:
6638      case OP_REFI:      case OP_REFI:
6639      compile_ref_iterator_fallbackpath(common, current);      compile_ref_iterator_backtrackpath(common, current);
6640      break;      break;
6641    
6642      case OP_RECURSE:      case OP_RECURSE:
6643      compile_recurse_fallbackpath(common, current);      compile_recurse_backtrackpath(common, current);
6644      break;      break;
6645    
6646      case OP_ASSERT:      case OP_ASSERT:
6647      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
6648      case OP_ASSERTBACK:      case OP_ASSERTBACK:
6649      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
6650      compile_assert_fallbackpath(common, current);      compile_assert_backtrackpath(common, current);
6651      break;      break;
6652    
6653      case OP_ONCE:      case OP_ONCE:
# Line 6651  while (current) Line 6658  while (current)
6658      case OP_SBRA:      case OP_SBRA:
6659      case OP_SCBRA:      case OP_SCBRA:
6660      case OP_SCOND:      case OP_SCOND:
6661      compile_bracket_fallbackpath(common, current);      compile_bracket_backtrackpath(common, current);
6662      break;      break;
6663    
6664      case OP_BRAZERO:      case OP_BRAZERO:
6665      if (current->cc[1] > OP_ASSERTBACK_NOT)      if (current->cc[1] > OP_ASSERTBACK_NOT)
6666        compile_bracket_fallbackpath(common, current);        compile_bracket_backtrackpath(common, current);
6667      else      else
6668        compile_assert_fallbackpath(common, current);        compile_assert_backtrackpath(common, current);
6669      break;      break;
6670    
6671      case OP_BRAPOS:      case OP_BRAPOS:
# Line 6666  while (current) Line 6673  while (current)
6673      case OP_SBRAPOS:      case OP_SBRAPOS:
6674      case OP_SCBRAPOS:      case OP_SCBRAPOS:
6675      case OP_BRAPOSZERO:      case OP_BRAPOSZERO:
6676      compile_bracketpos_fallbackpath(common, current);      compile_bracketpos_backtrackpath(common, current);
6677      break;      break;
6678    
6679      case OP_BRAMINZERO:      case OP_BRAMINZERO:
6680      compile_braminzero_fallbackpath(common, current);      compile_braminzero_backtrackpath(common, current);
6681      break;      break;
6682    
6683      case OP_MARK:      case OP_MARK:
# Line 6690  while (current) Line 6697  while (current)
6697      case OP_FAIL:      case OP_FAIL:
6698      case OP_ACCEPT:      case OP_ACCEPT:
6699      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
6700      set_jumps(current->topfallbacks, LABEL());      set_jumps(current->topbacktracks, LABEL());
6701      break;      break;
6702    
6703      default:      default:
# Line 6711  int localsize = get_localsize(common, cc Line 6718  int localsize = get_localsize(common, cc
6718  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6719  int alternativesize;  int alternativesize;
6720  BOOL needsframe;  BOOL needsframe;
6721  fallback_common altfallback;  backtrack_common altbacktrack;
6722  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_leavelabel = common->leavelabel;
6723  jump_list *save_leave = common->leave;  jump_list *save_leave = common->leave;
6724  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 6726  SLJIT_ASSERT(common->currententry->entry Line 6733  SLJIT_ASSERT(common->currententry->entry
6733  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6734  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6735    
6736  sljit_emit_fast_enter(compiler, TMP2, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, TMP2, 0);
6737  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6738  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
6739  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
# Line 6737  if (needsframe) Line 6744  if (needsframe)
6744  if (alternativesize > 0)  if (alternativesize > 0)
6745    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6746    
6747  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
6748  common->leavelabel = NULL;  common->leavelabel = NULL;
6749  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6750  common->leave = NULL;  common->leave = NULL;
6751  common->accept = NULL;  common->accept = NULL;
6752  altfallback.cc = ccbegin;  altbacktrack.cc = ccbegin;
6753  cc += GET(cc, 1);  cc += GET(cc, 1);
6754  while (1)  while (1)
6755    {    {
6756    altfallback.top = NULL;    altbacktrack.top = NULL;
6757    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
6758    
6759    if (altfallback.cc != ccbegin)    if (altbacktrack.cc != ccbegin)
6760      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6761    
6762    compile_hotpath(common, altfallback.cc, cc, &altfallback);    compile_trypath(common, altbacktrack.cc, cc, &altbacktrack);
6763    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6764      {      {
6765      common->leavelabel = save_leavelabel;      common->leavelabel = save_leavelabel;
# Line 6762  while (1) Line 6769  while (1)
6769    
6770    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6771    
6772    compile_fallbackpath(common, altfallback.top);    compile_backtrackpath(common, altbacktrack.top);
6773    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6774      {      {
6775      common->leavelabel = save_leavelabel;      common->leavelabel = save_leavelabel;
6776      common->leave = save_leave;      common->leave = save_leave;
6777      return;      return;
6778      }      }
6779    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
6780    
6781    if (*cc != OP_ALT)    if (*cc != OP_ALT)
6782      break;      break;
6783    
6784    altfallback.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
6785    cc += GET(cc, 1);    cc += GET(cc, 1);
6786    }    }
6787  /* None of them matched. */  /* None of them matched. */
# Line 6806  common->leavelabel = save_leavelabel; Line 6813  common->leavelabel = save_leavelabel;
6813  common->leave = save_leave;  common->leave = save_leave;
6814  }  }
6815    
6816  #undef COMPILE_FALLBACKPATH  #undef COMPILE_BACKTRACKPATH
6817  #undef CURRENT_AS  #undef CURRENT_AS
6818    
6819  void  void
6820  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6821  {  {
6822  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6823  fallback_common rootfallback;  backtrack_common rootbacktrack;
6824  compiler_common common_data;  compiler_common common_data;
6825  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6826  const pcre_uint8 *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6827  pcre_study_data *study;  pcre_study_data *study;
6828    int localsize;
6829  pcre_uchar *ccend;  pcre_uchar *ccend;
6830  executable_functions *functions;  executable_functions *functions;
6831  void *executable_func;  void *executable_func;
6832  sljit_uw executable_size;  sljit_uw executable_size;
6833  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6834  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6835  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_backtrack;
6836  struct sljit_jump *jump;  struct sljit_jump *jump;
6837  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6838  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
# Line 6835  study = extra->study_data; Line 6843  study = extra->study_data;
6843  if (!tables)  if (!tables)
6844    tables = PRIV(default_tables);    tables = PRIV(default_tables);
6845    
6846  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootbacktrack, 0, sizeof(backtrack_common));
6847  memset(common, 0, sizeof(compiler_common));  memset(common, 0, sizeof(compiler_common));
6848  rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  rootbacktrack.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6849    
6850  common->start = rootfallback.cc;  common->start = rootbacktrack.cc;
6851  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6852  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6853  common->mode = mode;  common->mode = mode;
# Line 6888  common->utf = (re->options & PCRE_UTF8) Line 6896  common->utf = (re->options & PCRE_UTF8)
6896  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6897  #endif  #endif
6898  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
6899  ccend = bracketend(rootfallback.cc);  ccend = bracketend(rootbacktrack.cc);
6900    
6901  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
6902  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);  common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6903    
6904  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6905  common->localsize = get_localspace(common, rootfallback.cc, ccend);  localsize = get_localspace(common, rootbacktrack.cc, ccend);
6906  if (common->localsize < 0)  if (localsize < 0)
6907    return;    return;
6908    
6909  /* Checking flags and updating ovector_start. */  /* Checking flags and updating ovector_start. */
6910  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
6911    {    {
6912    common->req_char_ptr = common->ovector_start;    common->req_char_ptr = common->ovector_start;
6913    common->ovector_start += sizeof(sljit_w);    common->ovector_start += sizeof(sljit_w);
# Line 6926  if ((common->ovector_start & sizeof(slji Line 6934  if ((common->ovector_start & sizeof(slji
6934    
6935  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6936  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6937  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6938  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (localsize > SLJIT_MAX_LOCAL_SIZE)
6939    return;    return;
6940  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
6941  if (!common->localptrs)  if (!common->localptrs)
6942    return;    return;
6943  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));  memset(common->localptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
6944  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);  set_localptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w), ccend);
6945    
6946  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
# Line 6944  if (!compiler) Line 6952  if (!compiler)
6952  common->compiler = compiler;  common->compiler = compiler;
6953    
6954  /* Main pcre_jit_exec entry. */  /* Main pcre_jit_exec entry. */
6955  sljit_emit_enter(compiler, 1, 5, 5, common->localsize);  sljit_emit_enter(compiler, 1, 5, 5, localsize);
6956    
6957  /* Register init. */  /* Register init. */
6958  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6959  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)  if (common->req_char_ptr != 0)
6960    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);
6961    
6962  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
# Line 6969  if ((re->options & PCRE_ANCHORED) == 0) Line 6977  if ((re->options & PCRE_ANCHORED) == 0)
6977    {    {
6978    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6979    /* Forward search if possible. */    /* Forward search if possible. */
6980    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
6981      fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);      {
6982    else if ((re->flags & PCRE_STARTLINE) != 0)      if ((re->flags & PCRE_FIRSTSET) != 0)
6983      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6984    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
6985      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6986        else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6987          fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6988        }
6989    }    }
6990  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)  if (common->req_char_ptr != 0)
6991    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6992    
6993  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
# Line 6995  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 7006  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7006  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
7007    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
7008    
7009  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_trypath(common, rootbacktrack.cc, ccend, &rootbacktrack);
7010  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7011    {    {
7012    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
# Line 7024  if (mode != JIT_COMPILE) Line 7035  if (mode != JIT_COMPILE)
7035    return_with_partial_match(common, common->leavelabel);    return_with_partial_match(common, common->leavelabel);
7036    }    }
7037    
7038  empty_match_fallback = LABEL();  empty_match_backtrack = LABEL();
7039  compile_fallbackpath(common, rootfallback.top);  compile_backtrackpath(common, rootbacktrack.top);
7040  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
7041    {    {
7042    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
# Line 7033  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 7044  if (SLJIT_UNLIKELY(sljit_get_compiler_er
7044    return;    return;
7045    }    }
7046    
7047  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
7048    
7049  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
7050    {    {
# Line 7052  if ((re->options & PCRE_ANCHORED) == 0) Line 7063  if ((re->options & PCRE_ANCHORED) == 0)
7063    {    {
7064    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
7065      {      {
7066      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
7067        {        {
7068        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7069        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
# Line 7063  if ((re->options & PCRE_ANCHORED) == 0) Line 7074  if ((re->options & PCRE_ANCHORED) == 0)
7074    else    else
7075      {      {
7076      SLJIT_ASSERT(common->first_line_end != 0);      SLJIT_ASSERT(common->first_line_end != 0);
7077      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
7078        {        {
7079        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));
7080        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
# Line 7092  flush_stubs(common); Line 7103  flush_stubs(common);
7103  JUMPHERE(empty_match);  JUMPHERE(empty_match);
7104  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7105  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));
7106  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_fallback);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);
7107  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));
7108  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);
7109  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
7110  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);
7111  JUMPTO(SLJIT_JUMP, empty_match_fallback);  JUMPTO(SLJIT_JUMP, empty_match_backtrack);
7112    
7113  common->currententry = common->entries;  common->currententry = common->entries;
7114  while (common->currententry != NULL)  while (common->currententry != NULL)
# Line 7118  while (common->currententry != NULL) Line 7129  while (common->currententry != NULL)
7129  /* This is a (really) rare case. */  /* This is a (really) rare case. */
7130  set_jumps(common->stackalloc, LABEL());  set_jumps(common->stackalloc, LABEL());
7131  /* RETURN_ADDR is not a saved register. */  /* RETURN_ADDR is not a saved register. */
7132  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);
7133  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
7134  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7135  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));

Legend:
Removed from v.941  
changed lines
  Added in v.977

  ViewVC Help
Powered by ViewVC 1.1.5