/[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 1269 by zherczeg, Mon Mar 4 10:47:12 2013 UTC revision 1279 by zherczeg, Tue Mar 12 17:27:34 2013 UTC
# Line 71  system files. */ Line 71  system files. */
71     2 - Enable capture_last_ptr (includes option 1). */     2 - Enable capture_last_ptr (includes option 1). */
72  /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */  /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
78  Fast, but limited size. */  Fast, but limited size. */
79  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 193  typedef struct stub_list { Line 196  typedef struct stub_list {
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199  enum frame_types { no_frame = -1, no_stack = -2 };  enum bytecode_flag_types {
200      flag_optimized_cbracket = 1,
201      flag_then_start = 2,
202    };
203    
204    enum frame_types {
205      no_frame = -1,
206      no_stack = -2
207    };
208    
209    enum control_types {
210      type_commit = 0,
211      type_prune = 1,
212      type_skip = 2,
213      type_skip_arg = 3,
214      type_mark = 4,
215      type_then_trap = 5
216    };
217    
218  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
219    
# Line 215  typedef struct backtrack_common { Line 235  typedef struct backtrack_common {
235  typedef struct assert_backtrack {  typedef struct assert_backtrack {
236    backtrack_common common;    backtrack_common common;
237    jump_list *condfailed;    jump_list *condfailed;
238    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
239    int framesize;    int framesize;
240    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
241    int private_data_ptr;    int private_data_ptr;
# Line 236  typedef struct bracket_backtrack { Line 256  typedef struct bracket_backtrack {
256      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
257      jump_list *condfailed;      jump_list *condfailed;
258      assert_backtrack *assert;      assert_backtrack *assert;
259      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
260      int framesize;      int framesize;
261    } u;    } u;
262    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 279  typedef struct recurse_backtrack { Line 299  typedef struct recurse_backtrack {
299    BOOL inlined_pattern;    BOOL inlined_pattern;
300  } recurse_backtrack;  } recurse_backtrack;
301    
302    typedef struct then_trap_backtrack {
303      backtrack_common common;
304      struct then_trap_backtrack *then_trap;
305      jump_list *quit;
306      int framesize;
307    } then_trap_backtrack;
308    
309  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
310    
311  typedef struct compiler_common {  typedef struct compiler_common {
312      /* The sljit ceneric compiler. */
313    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
314      /* First byte code. */
315    pcre_uchar *start;    pcre_uchar *start;
   
316    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
317    int *private_data_ptrs;    int *private_data_ptrs;
318    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
319    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
320      /* Tells whether the starting offset is a target of then. */
321      pcre_uint8 *then_offsets;
322      /* Current position where a THEN must jump. */
323      then_trap_backtrack *then_trap;
324    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
325    int cbraptr;    int cbra_ptr;
326    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
327    int ovector_start;    int ovector_start;
328    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
329    int req_char_ptr;    int req_char_ptr;
# Line 305  typedef struct compiler_common { Line 337  typedef struct compiler_common {
337    int first_line_end;    int first_line_end;
338    /* Points to the marked string. */    /* Points to the marked string. */
339    int mark_ptr;    int mark_ptr;
340      /* Recursive control verb management chain. */
341      int control_head_ptr;
342    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
343    int capture_last_ptr;    int capture_last_ptr;
344      /* Points to the starting position of the current match. */
345      int start_ptr;
346    
347    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
348    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
349    sljit_sw lcc;    sljit_sw lcc;
350    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
351    int mode;    int mode;
352      /* \K is found in the pattern. */
353      BOOL has_set_som;
354      /* (*SKIP:arg) is found in the pattern. */
355      BOOL has_skip_arg;
356      /* (*THEN) is found in the pattern. */
357      BOOL has_then;
358      /* Needs to know the start position anytime. */
359      BOOL needs_start_ptr;
360      /* Currently in recurse or assert. */
361      BOOL local_exit;
362    /* Newline control. */    /* Newline control. */
363    int nltype;    int nltype;
364    int newline;    int newline;
365    int bsr_nltype;    int bsr_nltype;
366    /* Dollar endonly. */    /* Dollar endonly. */
367    int endonly;    int endonly;
   BOOL has_set_som;  
368    /* Tables. */    /* Tables. */
369    sljit_sw ctypes;    sljit_sw ctypes;
370    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 349  typedef struct compiler_common { Line 394  typedef struct compiler_common {
394    jump_list *vspace;    jump_list *vspace;
395    jump_list *casefulcmp;    jump_list *casefulcmp;
396    jump_list *caselesscmp;    jump_list *caselesscmp;
397      jump_list *reset_match;
398    BOOL jscript_compat;    BOOL jscript_compat;
399  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
400    BOOL utf;    BOOL utf;
# Line 433  group contains the start / end character Line 479  group contains the start / end character
479  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
480  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
481  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
482  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
483  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
484    
485  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 490  return cc; Line 536  return cc;
536   set_private_data_ptrs   set_private_data_ptrs
537   get_framesize   get_framesize
538   init_frame   init_frame
539   get_private_data_length_for_copy   get_private_data_copy_length
540   copy_private_data   copy_private_data
541   compile_matchingpath   compile_matchingpath
542   compile_backtrackingpath   compile_backtrackingpath
# Line 572  switch(*cc) Line 618  switch(*cc)
618    case OP_BRAZERO:    case OP_BRAZERO:
619    case OP_BRAMINZERO:    case OP_BRAMINZERO:
620    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
621      case OP_PRUNE:
622      case OP_SKIP:
623      case OP_THEN:
624    case OP_COMMIT:    case OP_COMMIT:
625    case OP_FAIL:    case OP_FAIL:
626    case OP_ACCEPT:    case OP_ACCEPT:
# Line 670  switch(*cc) Line 719  switch(*cc)
719  #endif  #endif
720    
721    case OP_MARK:    case OP_MARK:
722      case OP_PRUNE_ARG:
723      case OP_SKIP_ARG:
724      case OP_THEN_ARG:
725    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
726    
727    default:    default:
# Line 921  while (cc < ccend) Line 973  while (cc < ccend)
973      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
974      break;      break;
975    
976        case OP_THEN_ARG:
977        common->has_then = TRUE;
978        /* Fall through. */
979    
980        case OP_PRUNE_ARG:
981        common->needs_start_ptr = TRUE;
982        common->control_head_ptr = 1;
983        /* Fall through. */
984    
985      case OP_MARK:      case OP_MARK:
986      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
987        {        {
# Line 930  while (cc < ccend) Line 991  while (cc < ccend)
991      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
992      break;      break;
993    
994        case OP_THEN:
995        common->has_then = TRUE;
996        /* Fall through. */
997    
998        case OP_PRUNE:
999        case OP_SKIP:
1000        common->needs_start_ptr = TRUE;
1001        common->control_head_ptr = 1;
1002        cc += 1;
1003        break;
1004    
1005        case OP_SKIP_ARG:
1006        common->control_head_ptr = 1;
1007        common->has_skip_arg = TRUE;
1008        cc += 1 + 2 + cc[1];
1009        break;
1010    
1011      default:      default:
1012      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1013      if (cc == NULL)      if (cc == NULL)
# Line 1107  while (cc < ccend) Line 1185  while (cc < ccend)
1185  }  }
1186    
1187  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1188  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
1189  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1190  int length = 0;  int length = 0;
1191  int possessive = 0;  int possessive = 0;
1192  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1118  BOOL setmark_found = recursive; Line 1195  BOOL setmark_found = recursive;
1195  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1196  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1197    
1198  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1199    SLJIT_ASSERT(common->control_head_ptr != 0);
1200    *needs_control_head = TRUE;
1201    #else
1202    *needs_control_head = FALSE;
1203    #endif
1204    
1205    if (ccend == NULL)
1206    {    {
1207    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1208    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1209    capture_last_found = TRUE;      {
1210        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1211        /* This is correct regardless of common->capture_last_ptr. */
1212        capture_last_found = TRUE;
1213        }
1214      cc = next_opcode(common, cc);
1215    }    }
1216    
 cc = next_opcode(common, cc);  
1217  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1218  while (cc < ccend)  while (cc < ccend)
1219    switch(*cc)    switch(*cc)
# Line 1142  while (cc < ccend) Line 1230  while (cc < ccend)
1230      break;      break;
1231    
1232      case OP_MARK:      case OP_MARK:
1233        case OP_PRUNE_ARG:
1234        case OP_THEN_ARG:
1235      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1236      stack_restore = TRUE;      stack_restore = TRUE;
1237      if (!setmark_found)      if (!setmark_found)
# Line 1149  while (cc < ccend) Line 1239  while (cc < ccend)
1239        length += 2;        length += 2;
1240        setmark_found = TRUE;        setmark_found = TRUE;
1241        }        }
1242        if (common->control_head_ptr != 0)
1243          *needs_control_head = TRUE;
1244      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1245      break;      break;
1246    
# Line 1186  while (cc < ccend) Line 1278  while (cc < ccend)
1278      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1279      break;      break;
1280    
1281        case OP_PRUNE:
1282        case OP_SKIP:
1283        case OP_SKIP_ARG:
1284        case OP_COMMIT:
1285        if (common->control_head_ptr != 0)
1286          *needs_control_head = TRUE;
1287        /* Fall through. */
1288    
1289      default:      default:
1290      stack_restore = TRUE;      stack_restore = TRUE;
1291      /* Fall through. */      /* Fall through. */
# Line 1268  if (length > 0) Line 1368  if (length > 0)
1368  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1369  }  }
1370    
1371  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1372  {  {
1373  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1374  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1375  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1376  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
# Line 1283  SLJIT_UNUSED_ARG(stacktop); Line 1382  SLJIT_UNUSED_ARG(stacktop);
1382  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1383    
1384  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1385  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1386    cc = next_opcode(common, cc);    {
1387      ccend = bracketend(cc) - (1 + LINK_SIZE);
1388      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1389        cc = next_opcode(common, cc);
1390      }
1391    
1392  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1393  while (cc < ccend)  while (cc < ccend)
1394    switch(*cc)    switch(*cc)
# Line 1304  while (cc < ccend) Line 1408  while (cc < ccend)
1408      break;      break;
1409    
1410      case OP_MARK:      case OP_MARK:
1411        case OP_PRUNE_ARG:
1412        case OP_THEN_ARG:
1413      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1414      if (!setmark_found)      if (!setmark_found)
1415        {        {
# Line 1384  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1490  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1490  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1491  }  }
1492    
1493  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1494  {  {
1495  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1496  int size;  int size;
1497  pcre_uchar *alternative;  pcre_uchar *alternative;
1498  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1499  return private_data_length; Line 1605  return private_data_length;
1605  }  }
1606    
1607  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1608    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1609  {  {
1610  DEFINE_COMPILER;  DEFINE_COMPILER;
1611  int srcw[2];  int srcw[2];
# Line 1520  stacktop = STACK(stacktop - 1); Line 1626  stacktop = STACK(stacktop - 1);
1626    
1627  if (!save)  if (!save)
1628    {    {
1629    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1630    if (stackptr < stacktop)    if (stackptr < stacktop)
1631      {      {
1632      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1536  if (!save) Line 1642  if (!save)
1642    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1643    }    }
1644    
1645  while (status != end)  do
1646    {    {
1647    count = 0;    count = 0;
1648    switch(status)    switch(status)
# Line 1545  while (status != end) Line 1651  while (status != end)
1651      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1652      count = 1;      count = 1;
1653      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1654        if (needs_control_head)
1655          {
1656          SLJIT_ASSERT(common->control_head_ptr != 0);
1657          count = 2;
1658          srcw[1] = common->control_head_ptr;
1659          }
1660      status = loop;      status = loop;
1661      break;      break;
1662    
# Line 1769  while (status != end) Line 1881  while (status != end)
1881        }        }
1882      }      }
1883    }    }
1884    while (status != end);
1885    
1886  if (save)  if (save)
1887    {    {
# Line 1802  if (save) Line 1915  if (save)
1915  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1916  }  }
1917    
1918    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1919    {
1920    pcre_uchar *end = bracketend(cc);
1921    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1922    
1923    /* Assert captures then. */
1924    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1925      current_offset = NULL;
1926    /* Conditional block does not. */
1927    if (*cc == OP_COND || *cc == OP_SCOND)
1928      has_alternatives = FALSE;
1929    
1930    cc = next_opcode(common, cc);
1931    if (has_alternatives)
1932      current_offset = common->then_offsets + (cc - common->start);
1933    
1934    while (cc < end)
1935      {
1936      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1937        cc = set_then_offsets(common, cc, current_offset);
1938      else
1939        {
1940        if (*cc == OP_ALT && has_alternatives)
1941          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1942        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1943          *current_offset = 1;
1944        cc = next_opcode(common, cc);
1945        }
1946      }
1947    
1948    return end;
1949    }
1950    
1951  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1952  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1953  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1900  static SLJIT_INLINE void reset_ovector(c Line 2046  static SLJIT_INLINE void reset_ovector(c
2046  DEFINE_COMPILER;  DEFINE_COMPILER;
2047  struct sljit_label *loop;  struct sljit_label *loop;
2048  int i;  int i;
2049    
2050  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2051    SLJIT_ASSERT(length > 1);
2052  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2053  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2054  if (length < 8)  if (length < 8)
2055    {    {
2056    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2057      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2058    }    }
2059  else  else
2060    {    {
2061    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2062    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2063    loop = LABEL();    loop = LABEL();
2064    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2065    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
# Line 1919  else Line 2067  else
2067    }    }
2068  }  }
2069    
2070    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2071    {
2072    DEFINE_COMPILER;
2073    struct sljit_label *loop;
2074    int i;
2075    
2076    SLJIT_ASSERT(length > 1);
2077    /* OVECTOR(1) contains the "string begin - 1" constant. */
2078    if (length > 2)
2079      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2080    if (length < 8)
2081      {
2082      for (i = 2; i < length; i++)
2083        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2084      }
2085    else
2086      {
2087      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2088      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2089      loop = LABEL();
2090      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2091      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2092      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2093      }
2094    
2095    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2096    if (common->mark_ptr != 0)
2097      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2098    SLJIT_ASSERT(common->control_head_ptr != 0);
2099    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2100    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2101    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2102    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2103    }
2104    
2105    static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2106    {
2107    sljit_sw return_value = 0;
2108    const pcre_uchar *skip_arg = NULL;
2109    
2110    SLJIT_ASSERT(current != NULL);
2111    do
2112      {
2113      switch (current[-2])
2114        {
2115        case type_commit:
2116        /* Commit overwrites all. */
2117        return -1;
2118    
2119        case type_prune:
2120        case type_then_trap:
2121        break;
2122    
2123        case type_skip:
2124        /* Overwrites prune, but not other skips. */
2125        if (return_value == 0 && skip_arg == NULL)
2126          return_value = current[-3];
2127        break;
2128    
2129        case type_skip_arg:
2130        if (return_value == 0 && skip_arg == NULL)
2131          skip_arg = (pcre_uchar *)current[-3];
2132        break;
2133    
2134        case type_mark:
2135        if (return_value == 0 && skip_arg != NULL)
2136          if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2137            return_value = current[-4];
2138        break;
2139    
2140        default:
2141        SLJIT_ASSERT_STOP();
2142        break;
2143        }
2144      current = (sljit_sw*)current[-1];
2145      }
2146    while (current != NULL);
2147    return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2148    }
2149    
2150    static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current)
2151    {
2152    do
2153      {
2154      switch (current[-2])
2155        {
2156        case type_commit:
2157        /* Commit overwrites all. */
2158        return 0;
2159    
2160        case type_then_trap:
2161        return (sljit_sw)current;
2162    
2163        case type_prune:
2164        case type_skip:
2165        case type_skip_arg:
2166        case type_mark:
2167        break;
2168    
2169        default:
2170        SLJIT_ASSERT_STOP();
2171        break;
2172        }
2173      current = (sljit_sw*)current[-1];
2174      SLJIT_ASSERT(current != NULL);
2175      }
2176    while (TRUE);
2177    }
2178    
2179  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2180  {  {
2181  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1975  DEFINE_COMPILER; Line 2232  DEFINE_COMPILER;
2232  struct sljit_jump *jump;  struct sljit_jump *jump;
2233    
2234  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
2235  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));  SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2236      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2237    
2238  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2239  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
# Line 1987  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 2245  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2245  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2246    
2247  jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);  jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2248  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr + sizeof(sljit_sw), SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);
2249  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2250  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2251  #endif  #endif
# Line 5125  recurse_entry *entry = common->entries; Line 5383  recurse_entry *entry = common->entries;
5383  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5384  int start = GET(cc, 1);  int start = GET(cc, 1);
5385  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5386    BOOL needs_control_head;
5387    
5388  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5389    
5390  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5391  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5392    {    {
5393    start_cc = common->start + start;    start_cc = common->start + start;
5394    compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);    compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
# Line 5248  allocate_stack(common, CALLOUT_ARG_SIZE Line 5507  allocate_stack(common, CALLOUT_ARG_SIZE
5507  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5508  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5509  SLJIT_ASSERT(common->capture_last_ptr != 0);  SLJIT_ASSERT(common->capture_last_ptr != 0);
5510  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5511  OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5512    
5513  /* These pointer sized fields temporarly stores internal variables. */  /* These pointer sized fields temporarly stores internal variables. */
5514  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 5258  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA Line 5517  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA
5517    
5518  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
5519    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5520  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5521  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5522  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5523    
5524  /* Needed to save important temporary registers. */  /* Needed to save important temporary registers. */
# Line 5288  static pcre_uchar *compile_assert_matchi Line 5547  static pcre_uchar *compile_assert_matchi
5547  {  {
5548  DEFINE_COMPILER;  DEFINE_COMPILER;
5549  int framesize;  int framesize;
5550    int extrasize;
5551    BOOL needs_control_head;
5552  int private_data_ptr;  int private_data_ptr;
5553  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5554  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5297  jump_list *tmp = NULL; Line 5558  jump_list *tmp = NULL;
5558  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5559  jump_list **found;  jump_list **found;
5560  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5561    BOOL save_local_exit = common->local_exit;
5562    then_trap_backtrack *save_then_trap = common->then_trap;
5563  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5564  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5565  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
# Line 5304  jump_list *save_accept = common->accept; Line 5567  jump_list *save_accept = common->accept;
5567  struct sljit_jump *jump;  struct sljit_jump *jump;
5568  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5569    
5570    /* Assert captures then. */
5571    common->then_trap = NULL;
5572    
5573  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5574    {    {
5575    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5312  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5578  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5578    }    }
5579  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5580  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5581  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5582  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5583  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5584  opcode = *cc;  opcode = *cc;
# Line 5331  if (bra == OP_BRAMINZERO) Line 5597  if (bra == OP_BRAMINZERO)
5597    
5598  if (framesize < 0)  if (framesize < 0)
5599    {    {
5600    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5601    allocate_stack(common, 1);    if (framesize == no_frame)
5602        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5603      allocate_stack(common, extrasize);
5604      if (needs_control_head)
5605        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5606    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5607      if (needs_control_head)
5608        {
5609        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5610        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5611        }
5612    }    }
5613  else  else
5614    {    {
5615    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5616      allocate_stack(common, framesize + extrasize);
5617    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5618    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5619    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5620      if (needs_control_head)
5621        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5622    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5623    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5624    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5625        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5626        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5627        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5628        }
5629      else
5630        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5631      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5632    }    }
5633    
5634  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5635    common->local_exit = TRUE;
5636  common->quit_label = NULL;  common->quit_label = NULL;
5637  common->quit = NULL;  common->quit = NULL;
5638  while (1)  while (1)
# Line 5363  while (1) Line 5649  while (1)
5649    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5650    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5651      {      {
5652        common->local_exit = save_local_exit;
5653        common->then_trap = save_then_trap;
5654      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5655      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5656      common->quit = save_quit;      common->quit = save_quit;
# Line 5375  while (1) Line 5663  while (1)
5663    
5664    /* Reset stack. */    /* Reset stack. */
5665    if (framesize < 0)    if (framesize < 0)
5666      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5667    else {      if (framesize == no_frame)
5668          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5669        else
5670          free_stack(common, extrasize);
5671        if (needs_control_head)
5672          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5673        }
5674      else
5675        {
5676      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5677        {        {
5678        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5679        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5680          if (needs_control_head)
5681            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5682        }        }
5683      else      else
5684        {        {
5685        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5686          if (needs_control_head)
5687            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5688        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5689        }        }
5690    }      }
5691    
5692    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5693      {      {
5694      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5695      if (conditional)      if (conditional)
5696        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
5697      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5698        {        {
5699        if (framesize < 0)        if (framesize < 0)
5700          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5701        else        else
5702          {          {
5703          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5704          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
5705          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5706          }          }
5707        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5418  while (1) Line 5718  while (1)
5718    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5719    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5720      {      {
5721        common->local_exit = save_local_exit;
5722        common->then_trap = save_then_trap;
5723      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5724      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5725      common->quit = save_quit;      common->quit = save_quit;
# Line 5432  while (1) Line 5734  while (1)
5734    ccbegin = cc;    ccbegin = cc;
5735    cc += GET(cc, 1);    cc += GET(cc, 1);
5736    }    }
5737    
5738  /* None of them matched. */  /* None of them matched. */
5739  if (common->quit != NULL)  if (common->quit != NULL)
5740      {
5741      jump = JUMP(SLJIT_JUMP);
5742    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5743      SLJIT_ASSERT(framesize != no_stack);
5744      if (framesize < 0)
5745        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5746      else
5747        {
5748        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5749        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5750        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5751        }
5752      JUMPHERE(jump);
5753      }
5754    
5755    if (needs_control_head)
5756      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5757    
5758  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5759    {    {
# Line 5446  if (opcode == OP_ASSERT || opcode == OP_ Line 5765  if (opcode == OP_ASSERT || opcode == OP_
5765      {      {
5766      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5767      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5768          {
5769          if (extrasize == 2)
5770            free_stack(common, 1);
5771        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5772          }
5773      else      else
5774        free_stack(common, 1);        free_stack(common, extrasize);
5775      }      }
5776    else    else
5777      {      {
5778      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5779      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5780      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5781        {        {
5782        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5783        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5784        }        }
5785      else      else
5786        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5787      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5788      }      }
5789    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5472  if (opcode == OP_ASSERT || opcode == OP_ Line 5795  if (opcode == OP_ASSERT || opcode == OP_
5795    if (framesize < 0)    if (framesize < 0)
5796      {      {
5797      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5798      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5799      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5800      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5801          {
5802        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5803          if (extrasize == 2)
5804            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5805          }
5806      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5807        {        {
5808        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5488  if (opcode == OP_ASSERT || opcode == OP_ Line 5815  if (opcode == OP_ASSERT || opcode == OP_
5815        {        {
5816        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5817        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5818        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
5819        }        }
5820      else      else
5821        {        {
5822        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5823        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
5824        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5825        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5826            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5827            if (bra == OP_BRAMINZERO)
5828              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5829            }
5830          else
5831            {
5832            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5833            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5834            }
5835        }        }
5836      }      }
5837    
# Line 5524  else Line 5860  else
5860      {      {
5861      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5862      if (bra != OP_BRA)      if (bra != OP_BRA)
5863          {
5864          if (extrasize == 2)
5865            free_stack(common, 1);
5866        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5867          }
5868      else      else
5869        free_stack(common, 1);        free_stack(common, extrasize);
5870      }      }
5871    else    else
5872      {      {
5873      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5874      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5875      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5876      if (bra != OP_BRA)      if (bra != OP_BRA)
5877        {        {
5878        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5879        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5880        }        }
5881      else      else
5882        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5883      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5884      }      }
5885    
# Line 5559  else Line 5899  else
5899      }      }
5900    }    }
5901    
5902    common->local_exit = save_local_exit;
5903    common->then_trap = save_then_trap;
5904  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5905  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5906  common->quit = save_quit;  common->quit = save_quit;
# Line 5676  if (i < name_count) Line 6018  if (i < name_count)
6018  return condition;  return condition;
6019  }  }
6020    
6021    static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
6022    {
6023    DEFINE_COMPILER;
6024    int stacksize;
6025    
6026    if (framesize < 0)
6027      {
6028      if (framesize == no_frame)
6029        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6030      else
6031        {
6032        stacksize = needs_control_head ? 1 : 0;
6033        if (ket != OP_KET || has_alternatives)
6034          stacksize++;
6035        free_stack(common, stacksize);
6036        }
6037    
6038      if (needs_control_head)
6039        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6040    
6041      /* TMP2 which is set here used by OP_KETRMAX below. */
6042      if (ket == OP_KETRMAX)
6043        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6044      else if (ket == OP_KETRMIN)
6045        {
6046        /* Move the STR_PTR to the private_data_ptr. */
6047        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6048        }
6049      }
6050    else
6051      {
6052      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6053      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6054      if (needs_control_head)
6055        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6056    
6057      if (ket == OP_KETRMAX)
6058        {
6059        /* TMP2 which is set here used by OP_KETRMAX below. */
6060        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6061        }
6062      }
6063    if (needs_control_head)
6064      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6065    }
6066    
6067    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6068    {
6069    DEFINE_COMPILER;
6070    
6071    if (common->capture_last_ptr != 0)
6072      {
6073      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6074      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6075      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6076      stacksize++;
6077      }
6078    if (common->optimized_cbracket[offset >> 1] == 0)
6079      {
6080      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6081      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6082      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6083      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6084      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6085      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6086      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6087      stacksize += 2;
6088      }
6089    return stacksize;
6090    }
6091    
6092  /*  /*
6093    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6094    
# Line 5744  pcre_uchar bra = OP_BRA; Line 6157  pcre_uchar bra = OP_BRA;
6157  pcre_uchar ket;  pcre_uchar ket;
6158  assert_backtrack *assert;  assert_backtrack *assert;
6159  BOOL has_alternatives;  BOOL has_alternatives;
6160    BOOL needs_control_head = FALSE;
6161  struct sljit_jump *jump;  struct sljit_jump *jump;
6162  struct sljit_jump *skip;  struct sljit_jump *skip;
6163  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 5819  else if (opcode == OP_ONCE || opcode == Line 6233  else if (opcode == OP_ONCE || opcode ==
6233    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6234    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6235    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6236      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
6237    }    }
6238    
6239  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6240  stacksize = 0;  stacksize = 0;
6241  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6242    stacksize++;    stacksize++;
6243  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6244    stacksize++;    stacksize++;
# Line 5833  if (stacksize > 0) Line 6247  if (stacksize > 0)
6247    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6248    
6249  stacksize = 0;  stacksize = 0;
6250  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6251    {    {
6252    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6253    stacksize++;    stacksize++;
# Line 5896  if (ket == OP_KETRMAX) Line 6310  if (ket == OP_KETRMAX)
6310  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6311  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6312    {    {
6313      stacksize = 0;
6314      if (needs_control_head)
6315        {
6316        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6317        stacksize++;
6318        }
6319    
6320    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6321      {      {
6322      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6323      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6324        {        {
6325        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6326        allocate_stack(common, 2);        if (!needs_control_head)
6327        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);  
       OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));  
6328        }        }
6329      else if (ket == OP_KETRMAX || has_alternatives)      else
6330        {        {
6331        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6332        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6333        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6334            stacksize++;
6335        }        }
6336      else  
6337        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6338          allocate_stack(common, stacksize);
6339    
6340        stacksize = 0;
6341        if (needs_control_head)
6342          {
6343          stacksize++;
6344          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6345          }
6346    
6347        if (ket == OP_KETRMIN)
6348          {
6349          if (needs_control_head)
6350            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6351          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6352          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6353            OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
6354          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6355          }
6356        else if (ket == OP_KETRMAX || has_alternatives)
6357          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6358      }      }
6359    else    else
6360      {      {
6361      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6362          stacksize++;
6363    
6364        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6365        allocate_stack(common, stacksize);
6366    
6367        if (needs_control_head)
6368          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6369    
6370        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6371        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6372    
6373        stacksize = needs_control_head ? 1 : 0;
6374        if (ket != OP_KET || has_alternatives)
6375        {        {
6376        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
       OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6377        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6378        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6379        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6380        }        }
6381      else      else
6382        {        {
       allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
       OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));  
6383        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6384        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
       init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);  
6385        }        }
6386        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6387      }      }
6388    }    }
6389  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6072  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6519  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6519    return NULL;    return NULL;
6520    
6521  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6522    {    match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
   if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)  
     {  
     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     /* TMP2 which is set here used by OP_KETRMAX below. */  
     if (ket == OP_KETRMAX)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);  
     else if (ket == OP_KETRMIN)  
       {  
       /* Move the STR_PTR to the private_data_ptr. */  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);  
       }  
     }  
   else  
     {  
     stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;  
     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw));  
     if (ket == OP_KETRMAX)  
       {  
       /* TMP2 which is set here used by OP_KETRMAX below. */  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
       }  
     }  
   }  
6523    
6524  stacksize = 0;  stacksize = 0;
6525  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6124  if (ket != OP_KET || bra != OP_BRA) Line 6548  if (ket != OP_KET || bra != OP_BRA)
6548    }    }
6549    
6550  if (offset != 0)  if (offset != 0)
6551    {    stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
   if (common->capture_last_ptr != 0)  
     {  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);  
     stacksize++;  
     }  
   if (common->optimized_cbracket[offset >> 1] == 0)  
     {  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     stacksize += 2;  
     }  
   }  
6552    
6553  if (has_alternatives)  if (has_alternatives)
6554    {    {
# Line 6214  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6619  if ((ket != OP_KET && bra != OP_BRAMINZE
6619  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6620    cc += GET(cc, 1);    cc += GET(cc, 1);
6621  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6622    
6623    /* Temporarily encoding the needs_control_head in framesize. */
6624    if (opcode == OP_ONCE)
6625      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6626  return cc;  return cc;
6627  }  }
6628    
# Line 6224  backtrack_common *backtrack; Line 6633  backtrack_common *backtrack;
6633  pcre_uchar opcode;  pcre_uchar opcode;
6634  int private_data_ptr;  int private_data_ptr;
6635  int cbraprivptr = 0;  int cbraprivptr = 0;
6636    BOOL needs_control_head;
6637  int framesize;  int framesize;
6638  int stacksize;  int stacksize;
6639  int offset = 0;  int offset = 0;
6640  BOOL zero = FALSE;  BOOL zero = FALSE;
6641  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6642  int stack;  int stack; /* Also contains the offset of control head. */
6643  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6644  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6645    
# Line 6267  switch(opcode) Line 6677  switch(opcode)
6677    break;    break;
6678    }    }
6679    
6680  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6681  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6682  if (framesize < 0)  if (framesize < 0)
6683    {    {
# Line 6280  if (framesize < 0) Line 6690  if (framesize < 0)
6690    else    else
6691      stacksize = 1;      stacksize = 1;
6692    
6693      if (needs_control_head)
6694        stacksize++;
6695    if (!zero)    if (!zero)
6696      stacksize++;      stacksize++;
6697    
# Line 6288  if (framesize < 0) Line 6700  if (framesize < 0)
6700    if (framesize == no_frame)    if (framesize == no_frame)
6701      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6702    
6703      stack = 0;
6704    if (offset != 0)    if (offset != 0)
6705      {      {
6706        stack = 2;
6707      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6708      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6709      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6710      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6711        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6712      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6713        if (needs_control_head)
6714          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6715      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6716          {
6717        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6718          stack = 3;
6719          }
6720      }      }
6721    else    else
6722        {
6723        if (needs_control_head)
6724          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6725      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6726        stack = 1;
6727        }
6728    
6729      if (needs_control_head)
6730        stack++;
6731    if (!zero)    if (!zero)
6732      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
6733      if (needs_control_head)
6734        {
6735        stack--;
6736        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6737        }
6738    }    }
6739  else  else
6740    {    {
6741    stacksize = framesize + 1;    stacksize = framesize + 1;
6742    if (!zero)    if (!zero)
6743      stacksize++;      stacksize++;
6744    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6745        stacksize++;
6746      if (offset == 0)
6747      stacksize++;      stacksize++;
6748    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6749    
6750    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6751    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6752    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6753    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6754      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6755    
6756    stack = 0;    stack = 0;
6757    if (!zero)    if (!zero)
6758      {      {
6759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6760        stack = 1;
6761        }
6762      if (needs_control_head)
6763        {
6764        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6765      stack++;      stack++;
6766      }      }
6767    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6768      {      {
6769      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6770      stack++;      stack++;
6771      }      }
6772    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6773    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6774      stack -= 1 + (offset == 0);
6775    }    }
6776    
6777  if (offset != 0)  if (offset != 0)
# Line 6407  while (*cc != OP_KETRPOS) Line 6847  while (*cc != OP_KETRPOS)
6847          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6848        }        }
6849      }      }
6850    
6851      if (needs_control_head)
6852        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6853    
6854    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6855    flush_stubs(common);    flush_stubs(common);
6856    
# Line 6443  while (*cc != OP_KETRPOS) Line 6887  while (*cc != OP_KETRPOS)
6887    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6888    }    }
6889    
6890    /* We don't have to restore the control head in case of a failed match. */
6891    
6892  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6893  if (!zero)  if (!zero)
6894    {    {
# Line 6831  if (!optimized_cbracket) Line 7277  if (!optimized_cbracket)
7277  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7278  }  }
7279    
7280    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7281    {
7282    DEFINE_COMPILER;
7283    backtrack_common *backtrack;
7284    pcre_uchar opcode = *cc;
7285    pcre_uchar *ccend = cc + 1;
7286    
7287    SLJIT_ASSERT(common->control_head_ptr != 0 || *cc == OP_COMMIT);
7288    
7289    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7290      ccend += 2 + cc[1];
7291    
7292    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7293    
7294    if (opcode == OP_SKIP || opcode == OP_SKIP_ARG)
7295      {
7296      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7297      allocate_stack(common, 3);
7298      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7299      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg);
7300      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), (opcode == OP_SKIP) ? STR_PTR : SLJIT_IMM, (opcode == OP_SKIP) ? 0 : (sljit_sw)(cc + 2));
7301      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7302      return ccend;
7303      }
7304    
7305    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7306      {
7307      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7308      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7309      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7310      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7311      }
7312    
7313    if (common->control_head_ptr != 0 && ((opcode != OP_THEN && opcode != OP_THEN_ARG) || common->then_trap == NULL))
7314      {
7315      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7316      allocate_stack(common, 2);
7317      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7318      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);
7319      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7320      }
7321    
7322    return ccend;
7323    }
7324    
7325    static pcre_uchar then_trap_opcode[1] = { OP_TABLE_LENGTH };
7326    
7327    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7328    {
7329    DEFINE_COMPILER;
7330    backtrack_common *backtrack;
7331    BOOL needs_control_head;
7332    int size;
7333    
7334    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7335    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7336    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7337    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7338    
7339    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7340    size = 2 + (size < 0 ? 0 : size);
7341    
7342    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7343    allocate_stack(common, size);
7344    if (size > 2)
7345      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 2) * sizeof(sljit_sw));
7346    else
7347      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7348    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, type_then_trap);
7349    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), TMP2, 0);
7350    
7351    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7352    if (size >= 0)
7353      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7354    }
7355    
7356  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7357  {  {
7358  DEFINE_COMPILER;  DEFINE_COMPILER;
7359  backtrack_common *backtrack;  backtrack_common *backtrack;
7360    BOOL has_then_trap = FALSE;
7361    then_trap_backtrack *save_then_trap = NULL;
7362    
7363    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7364    
7365    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7366      {
7367      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7368      has_then_trap = TRUE;
7369      save_then_trap = common->then_trap;
7370      /* Tail item on backtrack. */
7371      compile_then_trap_matchingpath(common, cc, ccend, parent);
7372      }
7373    
7374  while (cc < ccend)  while (cc < ccend)
7375    {    {
# Line 7051  while (cc < ccend) Line 7586  while (cc < ccend)
7586      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7587      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7588      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);
7589      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7590      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7591      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
7592      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7593      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7594      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7595        if (common->has_skip_arg)
7596          {
7597          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7598          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7599          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7600          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7601          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7602          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7603          }
7604      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7605      break;      break;
7606    
7607        case OP_PRUNE:
7608        case OP_PRUNE_ARG:
7609        case OP_SKIP:
7610        case OP_SKIP_ARG:
7611        case OP_THEN:
7612        case OP_THEN_ARG:
7613      case OP_COMMIT:      case OP_COMMIT:
7614      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7615      break;      break;
7616    
7617      case OP_FAIL:      case OP_FAIL:
# Line 7086  while (cc < ccend) Line 7635  while (cc < ccend)
7635    if (cc == NULL)    if (cc == NULL)
7636      return;      return;
7637    }    }
7638    
7639    if (has_then_trap)
7640      {
7641      /* Head item on backtrack. */
7642      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7643      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7644      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7645      common->then_trap = save_then_trap;
7646      }
7647  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7648  }  }
7649    
# Line 7247  switch(opcode) Line 7805  switch(opcode)
7805    }    }
7806  }  }
7807    
7808  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7809  {  {
7810  DEFINE_COMPILER;  DEFINE_COMPILER;
7811  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7269  set_jumps(current->topbacktracks, LABEL( Line 7827  set_jumps(current->topbacktracks, LABEL(
7827  free_stack(common, 2);  free_stack(common, 2);
7828  }  }
7829    
7830  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7831  {  {
7832  DEFINE_COMPILER;  DEFINE_COMPILER;
7833    
# Line 7379  pcre_uchar bra = OP_BRA; Line 7937  pcre_uchar bra = OP_BRA;
7937  pcre_uchar ket;  pcre_uchar ket;
7938  assert_backtrack *assert;  assert_backtrack *assert;
7939  BOOL has_alternatives;  BOOL has_alternatives;
7940    BOOL needs_control_head = FALSE;
7941  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7942  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7943  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7404  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7963  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7963  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7964    opcode = OP_ONCE;    opcode = OP_ONCE;
7965    
7966    /* Decoding the needs_control_head in framesize. */
7967    if (opcode == OP_ONCE)
7968      {
7969      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7970      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7971      }
7972    
7973  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7974    {    {
7975    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7561  if (has_alternatives) Line 8127  if (has_alternatives)
8127      current->top = NULL;      current->top = NULL;
8128      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8129      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8130        /* Conditional blocks always have an additional alternative, even if it is empty. */
8131      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8132        {        {
8133        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8134        cc += GET(cc, 1);        cc += GET(cc, 1);
8135        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8136          {          {
8137          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8138            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8139              if (private_data_ptr != 0)
8140                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8141              else
8142                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8143              }
8144          else          else
8145            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
8146          }          }
8147        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8148        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7580  if (has_alternatives) Line 8152  if (has_alternatives)
8152      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8153      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8154      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8155        {        match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
       if (CURRENT_AS(bracket_backtrack)->u.framesize < 0)  
         {  
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
         /* TMP2 which is set here used by OP_KETRMAX below. */  
         if (ket == OP_KETRMAX)  
           OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);  
         else if (ket == OP_KETRMIN)  
           {  
           /* Move the STR_PTR to the private_data_ptr. */  
           OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);  
           }  
         }  
       else  
         {  
         OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw));  
         if (ket == OP_KETRMAX)  
           {  
           /* TMP2 which is set here used by OP_KETRMAX below. */  
           OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
           }  
         }  
       }  
8156    
8157      stacksize = 0;      stacksize = 0;
8158      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7617  if (has_alternatives) Line 8167  if (has_alternatives)
8167      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8168        stacksize++;        stacksize++;
8169    
8170      if (stacksize > 0) {      if (stacksize > 0)
8171          {
8172        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8173          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
8174        else        else
# Line 7626  if (has_alternatives) Line 8177  if (has_alternatives)
8177          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
8178          OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));          OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
8179          }          }
8180      }        }
8181    
8182      stacksize = 0;      stacksize = 0;
8183      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7639  if (has_alternatives) Line 8190  if (has_alternatives)
8190        }        }
8191    
8192      if (offset != 0)      if (offset != 0)
8193        {        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
       if (common->capture_last_ptr != 0)  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
         stacksize++;  
         }  
       if (common->optimized_cbracket[offset >> 1] == 0)  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
         stacksize += 2;  
         }  
       }  
8194    
8195      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8196        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
# Line 7692  if (has_alternatives) Line 8224  if (has_alternatives)
8224      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8225      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8226      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)
   
8227        {        {
8228        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
8229        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7732  else if (opcode == OP_SBRA || opcode == Line 8263  else if (opcode == OP_SBRA || opcode ==
8263  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8264    {    {
8265    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8266      stacksize = needs_control_head ? 1 : 0;
8267    
8268    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8269      {      {
8270      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8271      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
     free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize);  
8272      }      }
8273    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8274      {      {
8275      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8276      free_stack(common, 1);      stacksize++;
8277      }      }
8278      free_stack(common, stacksize);
8279    
8280    JUMPHERE(once);    JUMPHERE(once);
8281    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7794  else if (bra == OP_BRAZERO) Line 8327  else if (bra == OP_BRAZERO)
8327    }    }
8328  }  }
8329    
8330  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8331  {  {
8332  DEFINE_COMPILER;  DEFINE_COMPILER;
8333  int offset;  int offset;
# Line 7833  if (current->topbacktracks) Line 8366  if (current->topbacktracks)
8366  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
8367  }  }
8368    
8369  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8370  {  {
8371  assert_backtrack backtrack;  assert_backtrack backtrack;
8372    
# Line 7857  else Line 8390  else
8390  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8391  }  }
8392    
8393    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8394    {
8395    DEFINE_COMPILER;
8396    pcre_uchar opcode = *current->cc;
8397    
8398    SLJIT_ASSERT(common->control_head_ptr != 0);
8399    
8400    if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8401      {
8402      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8403      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8404      sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_then_trap));
8405      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8406    
8407      if (common->quit_label == NULL)
8408        add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
8409      else
8410        CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0, common->quit_label);
8411    
8412      OP1(SLJIT_MOV, STACK_TOP, 0, TMP1, 0);
8413      add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8414      return;
8415      }
8416    
8417    if (!common->local_exit)
8418      {
8419      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8420      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8421      sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8422      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8423    
8424      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8425      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8426    
8427      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8428      }
8429    
8430    /* Commit or in recurse or accept. */
8431    if (common->quit_label == NULL)
8432      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8433    else
8434      JUMPTO(SLJIT_JUMP, common->quit_label);
8435    }
8436    
8437    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8438    {
8439    DEFINE_COMPILER;
8440    struct sljit_jump *jump;
8441    int size;
8442    
8443    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8444      {
8445      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8446      return;
8447      }
8448    
8449    size = CURRENT_AS(then_trap_backtrack)->framesize;
8450    size = 2 + (size < 0 ? 0 : size);
8451    
8452    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 2));
8453    free_stack(common, size);
8454    jump = JUMP(SLJIT_JUMP);
8455    
8456    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8457    /* STACK_TOP is set by THEN. */
8458    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8459      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8460    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8461    free_stack(common, 2);
8462    
8463    JUMPHERE(jump);
8464    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8465    }
8466    
8467  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8468  {  {
8469  DEFINE_COMPILER;  DEFINE_COMPILER;
8470    then_trap_backtrack *save_then_trap = common->then_trap;
8471    
8472  while (current)  while (current)
8473    {    {
# Line 7993  while (current) Line 8601  while (current)
8601      break;      break;
8602    
8603      case OP_MARK:      case OP_MARK:
8604      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
8605      free_stack(common, 1);      if (common->has_skip_arg)
8606          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8607        free_stack(common, common->has_skip_arg ? 5 : 1);
8608      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
8609        if (common->has_skip_arg)
8610          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8611        break;
8612    
8613        case OP_THEN:
8614        case OP_THEN_ARG:
8615        case OP_PRUNE:
8616        case OP_PRUNE_ARG:
8617        case OP_SKIP:
8618        compile_control_verb_backtrackingpath(common, current);
8619        break;
8620    
8621        case OP_SKIP_ARG:
8622        if (!common->local_exit)
8623          {
8624          SLJIT_ASSERT(common->control_head_ptr != 0);
8625          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8626          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8627          sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8628          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8629    
8630          OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8631          add_jump(compiler, &common->reset_match, CMP(SLJIT_C_LESS, STR_PTR, 0, SLJIT_IMM, -2));
8632    
8633          /* May not find suitable mark. */
8634          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8635          if (common->quit_label == NULL)
8636            add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8637          else
8638            CMPTO(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1, common->quit_label);
8639    
8640          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8641          free_stack(common, 3);
8642          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8643          }
8644        else
8645          {
8646          /* In recurse or accept. */
8647          if (common->quit_label == NULL)
8648            add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8649          else
8650            JUMPTO(SLJIT_JUMP, common->quit_label);
8651          }
8652      break;      break;
8653    
8654      case OP_COMMIT:      case OP_COMMIT:
8655      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8656          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8657      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8658        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8659      else      else
# Line 8013  while (current) Line 8667  while (current)
8667      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8668      break;      break;
8669    
8670        case OP_TABLE_LENGTH:
8671        /* A virtual opcode for then traps. */
8672        compile_then_trap_backtrackingpath(common, current);
8673        break;
8674    
8675      default:      default:
8676      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8677      break;      break;
8678      }      }
8679    current = current->prev;    current = current->prev;
8680    }    }
8681    common->then_trap = save_then_trap;
8682  }  }
8683    
8684  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8027  DEFINE_COMPILER; Line 8687  DEFINE_COMPILER;
8687  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8688  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
8689  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8690  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8691  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8692    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8693  int alternativesize;  int alternativesize;
8694  BOOL needsframe;  BOOL needs_frame;
8695  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quit_label = common->quit_label;  
 jump_list *save_quit = common->quit;  
8696  struct sljit_jump *jump;  struct sljit_jump *jump;
8697    
8698    /* Recurse captures then. */
8699    common->then_trap = NULL;
8700    
8701  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
8702  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8703  if (!needsframe)  if (!needs_frame)
8704    framesize = 0;    framesize = 0;
8705  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8706    
# Line 8049  set_jumps(common->currententry->calls, c Line 8711  set_jumps(common->currententry->calls, c
8711  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8712  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8713  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
8714  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8715    if (needs_control_head)
8716      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8717  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8718  if (needsframe)  if (needs_frame)
8719    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8720    
8721  if (alternativesize > 0)  if (alternativesize > 0)
8722    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 8074  while (1) Line 8738  while (1)
8738    
8739    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8740    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quit_label = save_quit_label;  
     common->quit = save_quit;  
8741      return;      return;
     }  
8742    
8743    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8744    
8745    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8746    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quit_label = save_quit_label;  
     common->quit = save_quit;  
8747      return;      return;
     }  
8748    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8749    
8750    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 8097  while (1) Line 8753  while (1)
8753    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8754    cc += GET(cc, 1);    cc += GET(cc, 1);
8755    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8756    
8757    /* None of them matched. */
8758  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8759  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8760    
8761    if (common->quit != NULL)
8762      {
8763      set_jumps(common->quit, LABEL());
8764      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8765      if (needs_frame)
8766        {
8767        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8768        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8769        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8770        }
8771      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8772      common->quit = NULL;
8773      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8774      }
8775    
8776  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8777  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8778  if (needsframe)  if (needs_frame)
8779    {    {
8780    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8781    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 8115  if (needsframe) Line 8784  if (needsframe)
8784  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8785    
8786  JUMPHERE(jump);  JUMPHERE(jump);
8787  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8788      set_jumps(common->quit, LABEL());
8789    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8790  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8791  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8792  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8793  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8794      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8795      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8796      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8797      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8798      }
8799    else
8800      {
8801      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8802      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8803      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8804      }
8805  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
   
 common->quit_label = save_quit_label;  
 common->quit = save_quit;  
8806  }  }
8807    
8808  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 8143  pcre_uchar *ccend; Line 8822  pcre_uchar *ccend;
8822  executable_functions *functions;  executable_functions *functions;
8823  void *executable_func;  void *executable_func;
8824  sljit_uw executable_size;  sljit_uw executable_size;
8825  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8826  struct sljit_label *empty_match_found;  struct sljit_label *continue_match_label;
8827  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_found_label;
8828    struct sljit_label *empty_match_backtrack_label;
8829    struct sljit_label *reset_match_label;
8830  struct sljit_jump *jump;  struct sljit_jump *jump;
8831  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
8832  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8833  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8834    struct sljit_label *quit_label;
8835    
8836  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8837  study = extra->study_data;  study = extra->study_data;
# Line 8245  if (mode == JIT_COMPILE && (re->flags & Line 8927  if (mode == JIT_COMPILE && (re->flags &
8927  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8928    {    {
8929    common->start_used_ptr = common->ovector_start;    common->start_used_ptr = common->ovector_start;
8930    common->ovector_start += 2 * sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8931    if (mode == JIT_PARTIAL_SOFT_COMPILE)    if (mode == JIT_PARTIAL_SOFT_COMPILE)
8932      {      {
8933      common->hit_start = common->ovector_start;      common->hit_start = common->ovector_start;
8934      common->ovector_start += sizeof(sljit_sw);      common->ovector_start += 2 * sizeof(sljit_sw);
8935        }
8936      else
8937        {
8938        SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
8939        common->needs_start_ptr = TRUE;
8940      }      }
8941    }    }
8942  if ((re->options & PCRE_FIRSTLINE) != 0)  if ((re->options & PCRE_FIRSTLINE) != 0)
# Line 8257  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8944  if ((re->options & PCRE_FIRSTLINE) != 0)
8944    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
8945    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8946    }    }
8947    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
8948    common->control_head_ptr = 1;
8949    #endif
8950    if (common->control_head_ptr != 0)
8951      {
8952      common->control_head_ptr = common->ovector_start;
8953      common->ovector_start += sizeof(sljit_sw);
8954      }
8955    if (common->needs_start_ptr && common->has_set_som)
8956      {
8957      /* Saving the real start pointer is necessary. */
8958      common->start_ptr = common->ovector_start;
8959      common->ovector_start += sizeof(sljit_sw);
8960      }
8961    else
8962      common->needs_start_ptr = FALSE;
8963    
8964  /* Aligning ovector to even number of sljit words. */  /* Aligning ovector to even number of sljit words. */
8965  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8966    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8967    
8968    if (common->start_ptr == 0)
8969      common->start_ptr = OVECTOR(0);
8970    
8971  /* Capturing brackets cannot be optimized if callouts are allowed. */  /* Capturing brackets cannot be optimized if callouts are allowed. */
8972  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8973    memset(common->optimized_cbracket, 0, re->top_bracket + 1);    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8974    
8975  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8976  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
8977  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);  private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
8978  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
8979    {    {
8980    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8981    return;    return;
8982    }    }
8983    
8984  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
8985  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
8986    {    {
# Line 8281  if (!common->private_data_ptrs) Line 8988  if (!common->private_data_ptrs)
8988    return;    return;
8989    }    }
8990  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8991  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);
8992    
8993    if (common->has_then)
8994      {
8995      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
8996      if (!common->then_offsets)
8997        {
8998        SLJIT_FREE(common->optimized_cbracket);
8999        SLJIT_FREE(common->private_data_ptrs);
9000        return;
9001        }
9002      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
9003      set_then_offsets(common, rootbacktrack.cc, NULL);
9004      }
9005    
9006  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
9007  if (!compiler)  if (!compiler)
9008    {    {
9009    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9010    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9011      if (common->has_then)
9012        SLJIT_FREE(common->then_offsets);
9013    return;    return;
9014    }    }
9015  common->compiler = compiler;  common->compiler = compiler;
# Line 8312  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 9034  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
9034    
9035  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9036    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);
9037    if (common->mark_ptr != 0)
9038      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
9039    if (common->control_head_ptr != 0)
9040      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
9041    
9042  /* Main part of the matching */  /* Main part of the matching */
9043  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9044    {    {
9045    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
9046      continue_match_label = LABEL();
9047    /* Forward search if possible. */    /* Forward search if possible. */
9048    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
9049      {      {
# Line 8330  if ((re->options & PCRE_ANCHORED) == 0) Line 9057  if ((re->options & PCRE_ANCHORED) == 0)
9057        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
9058      }      }
9059    }    }
9060    else
9061      continue_match_label = LABEL();
9062    
9063  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
9064    {    {
9065    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
# Line 8343  if (common->req_char_ptr != 0) Line 9073  if (common->req_char_ptr != 0)
9073  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);
9074  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9075  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
 if (common->mark_ptr != 0)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);  
9076  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9077    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
9078    
9079    if (common->needs_start_ptr)
9080      {
9081      SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
9082      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
9083      }
9084    else
9085      SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
9086    
9087  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
9088  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9089    {    {
9090    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
9091    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);
9092    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr + sizeof(sljit_sw), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
9093    JUMPHERE(jump);    JUMPHERE(jump);
9094    }    }
9095  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
   {  
9096    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);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr + sizeof(sljit_sw), STR_PTR, 0);  
   }  
9097    
9098  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
9099  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 8367  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9101  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9101    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9102    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9103    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9104      if (common->has_then)
9105        SLJIT_FREE(common->then_offsets);
9106    return;    return;
9107    }    }
9108    
9109  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
9110  empty_match_found = LABEL();  empty_match_found_label = LABEL();
9111    
9112  common->accept_label = LABEL();  common->accept_label = LABEL();
9113  if (common->accept != NULL)  if (common->accept != NULL)
# Line 8395  if (mode != JIT_COMPILE) Line 9131  if (mode != JIT_COMPILE)
9131    return_with_partial_match(common, common->quit_label);    return_with_partial_match(common, common->quit_label);
9132    }    }
9133    
9134  empty_match_backtrack = LABEL();  empty_match_backtrack_label = LABEL();
9135  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
9136  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9137    {    {
9138    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9139    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9140    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9141      if (common->has_then)
9142        SLJIT_FREE(common->then_offsets);
9143    return;    return;
9144    }    }
9145    
9146  SLJIT_ASSERT(rootbacktrack.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
9147    reset_match_label = LABEL();
9148    
9149  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9150    {    {
# Line 8423  if ((re->options & PCRE_ANCHORED) == 0 & Line 9162  if ((re->options & PCRE_ANCHORED) == 0 &
9162    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
9163    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
9164    }    }
9165  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
9166    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
9167    
9168  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9169    {    {
9170    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
9171      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
9172    else    else
9173      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
9174    }    }
9175    
9176  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8448  flush_stubs(common); Line 9188  flush_stubs(common);
9188  JUMPHERE(empty_match);  JUMPHERE(empty_match);
9189  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9190  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));
9191  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
9192  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));
9193  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
9194  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));
9195  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_label);
9196  JUMPTO(SLJIT_JUMP, empty_match_backtrack);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9197    
9198  common->currententry = common->entries;  common->currententry = common->entries;
9199    common->local_exit = TRUE;
9200    quit_label = common->quit_label;
9201  while (common->currententry != NULL)  while (common->currententry != NULL)
9202    {    {
9203    /* Might add new entries. */    /* Might add new entries. */
# Line 8465  while (common->currententry != NULL) Line 9207  while (common->currententry != NULL)
9207      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9208      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9209      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9210        if (common->has_then)
9211          SLJIT_FREE(common->then_offsets);
9212      return;      return;
9213      }      }
9214    flush_stubs(common);    flush_stubs(common);
9215    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
9216    }    }
9217    common->local_exit = FALSE;
9218    common->quit_label = quit_label;
9219    
9220  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
9221  /* This is a (really) rare case. */  /* This is a (really) rare case. */
# Line 8537  if (common->caselesscmp != NULL) Line 9283  if (common->caselesscmp != NULL)
9283    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
9284    do_caselesscmp(common);    do_caselesscmp(common);
9285    }    }
9286    if (common->reset_match != NULL)
9287      {
9288      set_jumps(common->reset_match, LABEL());
9289      do_reset_match(common, (re->top_bracket + 1) * 2);
9290      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
9291      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
9292      JUMPTO(SLJIT_JUMP, reset_match_label);
9293      }
9294  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9295  #ifndef COMPILE_PCRE32  #ifndef COMPILE_PCRE32
9296  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
# Line 8563  if (common->getucd != NULL) Line 9317  if (common->getucd != NULL)
9317    
9318  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9319  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9320    if (common->has_then)
9321      SLJIT_FREE(common->then_offsets);
9322    
9323  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9324  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9325  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

Legend:
Removed from v.1269  
changed lines
  Added in v.1279

  ViewVC Help
Powered by ViewVC 1.1.5