/[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 1291 by zherczeg, Sun Mar 17 05:27:48 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 frame_types {
200      no_frame = -1,
201      no_stack = -2
202    };
203    
204    enum control_types {
205      type_mark = 0,
206      type_then_trap = 1
207    };
208    
209  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
210    
# Line 215  typedef struct backtrack_common { Line 226  typedef struct backtrack_common {
226  typedef struct assert_backtrack {  typedef struct assert_backtrack {
227    backtrack_common common;    backtrack_common common;
228    jump_list *condfailed;    jump_list *condfailed;
229    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
230    int framesize;    int framesize;
231    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
232    int private_data_ptr;    int private_data_ptr;
# Line 236  typedef struct bracket_backtrack { Line 247  typedef struct bracket_backtrack {
247      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
248      jump_list *condfailed;      jump_list *condfailed;
249      assert_backtrack *assert;      assert_backtrack *assert;
250      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
251      int framesize;      int framesize;
252    } u;    } u;
253    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 271  typedef struct recurse_entry { Line 282  typedef struct recurse_entry {
282    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
283    jump_list *calls;    jump_list *calls;
284    /* Points to the starting opcode. */    /* Points to the starting opcode. */
285    int start;    sljit_sw start;
286  } recurse_entry;  } recurse_entry;
287    
288  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
# Line 279  typedef struct recurse_backtrack { Line 290  typedef struct recurse_backtrack {
290    BOOL inlined_pattern;    BOOL inlined_pattern;
291  } recurse_backtrack;  } recurse_backtrack;
292    
293    #define OP_THEN_TRAP OP_TABLE_LENGTH
294    
295    typedef struct then_trap_backtrack {
296      backtrack_common common;
297      /* If then_trap is not NULL, this structure contains the real
298      then_trap for the backtracking path. */
299      struct then_trap_backtrack *then_trap;
300      /* Points to the starting opcode. */
301      sljit_sw start;
302      /* Exit point for the then opcodes of this alternative. */
303      jump_list *quit;
304      /* Frame size of the current alternative. */
305      int framesize;
306    } then_trap_backtrack;
307    
308  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
309    
310  typedef struct compiler_common {  typedef struct compiler_common {
311      /* The sljit ceneric compiler. */
312    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
313      /* First byte code. */
314    pcre_uchar *start;    pcre_uchar *start;
   
315    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
316    int *private_data_ptrs;    int *private_data_ptrs;
317    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
318    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
319      /* Tells whether the starting offset is a target of then. */
320      pcre_uint8 *then_offsets;
321      /* Current position where a THEN must jump. */
322      then_trap_backtrack *then_trap;
323    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
324    int cbraptr;    int cbra_ptr;
325    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
326    int ovector_start;    int ovector_start;
327    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
328    int req_char_ptr;    int req_char_ptr;
# Line 305  typedef struct compiler_common { Line 336  typedef struct compiler_common {
336    int first_line_end;    int first_line_end;
337    /* Points to the marked string. */    /* Points to the marked string. */
338    int mark_ptr;    int mark_ptr;
339      /* Recursive control verb management chain. */
340      int control_head_ptr;
341    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
342    int capture_last_ptr;    int capture_last_ptr;
343      /* Points to the starting position of the current match. */
344      int start_ptr;
345    
346    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
347    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
348    sljit_sw lcc;    sljit_sw lcc;
349    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
350    int mode;    int mode;
351      /* \K is found in the pattern. */
352      BOOL has_set_som;
353      /* (*SKIP:arg) is found in the pattern. */
354      BOOL has_skip_arg;
355      /* (*THEN) is found in the pattern. */
356      BOOL has_then;
357      /* Needs to know the start position anytime. */
358      BOOL needs_start_ptr;
359      /* Currently in recurse or assert. */
360      BOOL local_exit;
361    /* Newline control. */    /* Newline control. */
362    int nltype;    int nltype;
363    int newline;    int newline;
364    int bsr_nltype;    int bsr_nltype;
365    /* Dollar endonly. */    /* Dollar endonly. */
366    int endonly;    int endonly;
   BOOL has_set_som;  
367    /* Tables. */    /* Tables. */
368    sljit_sw ctypes;    sljit_sw ctypes;
369    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 349  typedef struct compiler_common { Line 393  typedef struct compiler_common {
393    jump_list *vspace;    jump_list *vspace;
394    jump_list *casefulcmp;    jump_list *casefulcmp;
395    jump_list *caselesscmp;    jump_list *caselesscmp;
396      jump_list *reset_match;
397    BOOL jscript_compat;    BOOL jscript_compat;
398  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
399    BOOL utf;    BOOL utf;
# Line 433  group contains the start / end character Line 478  group contains the start / end character
478  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. */
479  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
480  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
481  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
482  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
483    
484  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 490  return cc; Line 535  return cc;
535   set_private_data_ptrs   set_private_data_ptrs
536   get_framesize   get_framesize
537   init_frame   init_frame
538   get_private_data_length_for_copy   get_private_data_copy_length
539   copy_private_data   copy_private_data
540   compile_matchingpath   compile_matchingpath
541   compile_backtrackingpath   compile_backtrackingpath
# Line 572  switch(*cc) Line 617  switch(*cc)
617    case OP_BRAZERO:    case OP_BRAZERO:
618    case OP_BRAMINZERO:    case OP_BRAMINZERO:
619    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
620      case OP_PRUNE:
621      case OP_SKIP:
622      case OP_THEN:
623    case OP_COMMIT:    case OP_COMMIT:
624    case OP_FAIL:    case OP_FAIL:
625    case OP_ACCEPT:    case OP_ACCEPT:
# Line 670  switch(*cc) Line 718  switch(*cc)
718  #endif  #endif
719    
720    case OP_MARK:    case OP_MARK:
721      case OP_PRUNE_ARG:
722      case OP_SKIP_ARG:
723      case OP_THEN_ARG:
724    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
725    
726    default:    default:
727      /* All opcodes are supported now! */
728      SLJIT_ASSERT_STOP();
729    return NULL;    return NULL;
730    }    }
731  }  }
# Line 921  while (cc < ccend) Line 974  while (cc < ccend)
974      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
975      break;      break;
976    
977        case OP_THEN_ARG:
978        common->has_then = TRUE;
979        common->control_head_ptr = 1;
980        /* Fall through. */
981    
982        case OP_PRUNE_ARG:
983        common->needs_start_ptr = TRUE;
984        /* Fall through. */
985    
986      case OP_MARK:      case OP_MARK:
987      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
988        {        {
# Line 930  while (cc < ccend) Line 992  while (cc < ccend)
992      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
993      break;      break;
994    
995        case OP_THEN:
996        common->has_then = TRUE;
997        common->control_head_ptr = 1;
998        /* Fall through. */
999    
1000        case OP_PRUNE:
1001        case OP_SKIP:
1002        common->needs_start_ptr = TRUE;
1003        cc += 1;
1004        break;
1005    
1006        case OP_SKIP_ARG:
1007        common->control_head_ptr = 1;
1008        common->has_skip_arg = TRUE;
1009        cc += 1 + 2 + cc[1];
1010        break;
1011    
1012      default:      default:
1013      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1014      if (cc == NULL)      if (cc == NULL)
# Line 1107  while (cc < ccend) Line 1186  while (cc < ccend)
1186  }  }
1187    
1188  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1189  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)
1190  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1191  int length = 0;  int length = 0;
1192  int possessive = 0;  int possessive = 0;
1193  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1118  BOOL setmark_found = recursive; Line 1196  BOOL setmark_found = recursive;
1196  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1197  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1198    
1199  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1200    SLJIT_ASSERT(common->control_head_ptr != 0);
1201    *needs_control_head = TRUE;
1202    #else
1203    *needs_control_head = FALSE;
1204    #endif
1205    
1206    if (ccend == NULL)
1207    {    {
1208    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1209    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1210    capture_last_found = TRUE;      {
1211        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1212        /* This is correct regardless of common->capture_last_ptr. */
1213        capture_last_found = TRUE;
1214        }
1215      cc = next_opcode(common, cc);
1216    }    }
1217    
 cc = next_opcode(common, cc);  
1218  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1219  while (cc < ccend)  while (cc < ccend)
1220    switch(*cc)    switch(*cc)
# Line 1142  while (cc < ccend) Line 1231  while (cc < ccend)
1231      break;      break;
1232    
1233      case OP_MARK:      case OP_MARK:
1234        case OP_PRUNE_ARG:
1235        case OP_THEN_ARG:
1236      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1237      stack_restore = TRUE;      stack_restore = TRUE;
1238      if (!setmark_found)      if (!setmark_found)
# Line 1149  while (cc < ccend) Line 1240  while (cc < ccend)
1240        length += 2;        length += 2;
1241        setmark_found = TRUE;        setmark_found = TRUE;
1242        }        }
1243        if (common->control_head_ptr != 0)
1244          *needs_control_head = TRUE;
1245      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1246      break;      break;
1247    
# Line 1268  if (length > 0) Line 1361  if (length > 0)
1361  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1362  }  }
1363    
1364  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)
1365  {  {
1366  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1367  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1368  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1369  /* 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 1375  SLJIT_UNUSED_ARG(stacktop);
1375  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1376    
1377  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1378  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1379    cc = next_opcode(common, cc);    {
1380      ccend = bracketend(cc) - (1 + LINK_SIZE);
1381      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1382        cc = next_opcode(common, cc);
1383      }
1384    
1385  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1386  while (cc < ccend)  while (cc < ccend)
1387    switch(*cc)    switch(*cc)
# Line 1304  while (cc < ccend) Line 1401  while (cc < ccend)
1401      break;      break;
1402    
1403      case OP_MARK:      case OP_MARK:
1404        case OP_PRUNE_ARG:
1405        case OP_THEN_ARG:
1406      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1407      if (!setmark_found)      if (!setmark_found)
1408        {        {
# Line 1384  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1483  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1483  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1484  }  }
1485    
1486  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)
1487  {  {
1488  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1489  int size;  int size;
1490  pcre_uchar *alternative;  pcre_uchar *alternative;
1491  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1499  return private_data_length; Line 1598  return private_data_length;
1598  }  }
1599    
1600  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,
1601    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1602  {  {
1603  DEFINE_COMPILER;  DEFINE_COMPILER;
1604  int srcw[2];  int srcw[2];
# Line 1520  stacktop = STACK(stacktop - 1); Line 1619  stacktop = STACK(stacktop - 1);
1619    
1620  if (!save)  if (!save)
1621    {    {
1622    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1623    if (stackptr < stacktop)    if (stackptr < stacktop)
1624      {      {
1625      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 1635  if (!save)
1635    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1636    }    }
1637    
1638  while (status != end)  do
1639    {    {
1640    count = 0;    count = 0;
1641    switch(status)    switch(status)
# Line 1545  while (status != end) Line 1644  while (status != end)
1644      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1645      count = 1;      count = 1;
1646      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1647        if (needs_control_head)
1648          {
1649          SLJIT_ASSERT(common->control_head_ptr != 0);
1650          count = 2;
1651          srcw[1] = common->control_head_ptr;
1652          }
1653      status = loop;      status = loop;
1654      break;      break;
1655    
# Line 1769  while (status != end) Line 1874  while (status != end)
1874        }        }
1875      }      }
1876    }    }
1877    while (status != end);
1878    
1879  if (save)  if (save)
1880    {    {
# Line 1802  if (save) Line 1908  if (save)
1908  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1909  }  }
1910    
1911    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1912    {
1913    pcre_uchar *end = bracketend(cc);
1914    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1915    
1916    /* Assert captures then. */
1917    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1918      current_offset = NULL;
1919    /* Conditional block does not. */
1920    if (*cc == OP_COND || *cc == OP_SCOND)
1921      has_alternatives = FALSE;
1922    
1923    cc = next_opcode(common, cc);
1924    if (has_alternatives)
1925      current_offset = common->then_offsets + (cc - common->start);
1926    
1927    while (cc < end)
1928      {
1929      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1930        cc = set_then_offsets(common, cc, current_offset);
1931      else
1932        {
1933        if (*cc == OP_ALT && has_alternatives)
1934          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1935        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1936          *current_offset = 1;
1937        cc = next_opcode(common, cc);
1938        }
1939      }
1940    
1941    return end;
1942    }
1943    
1944  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1945  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1946  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1900  static SLJIT_INLINE void reset_ovector(c Line 2039  static SLJIT_INLINE void reset_ovector(c
2039  DEFINE_COMPILER;  DEFINE_COMPILER;
2040  struct sljit_label *loop;  struct sljit_label *loop;
2041  int i;  int i;
2042    
2043  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2044    SLJIT_ASSERT(length > 1);
2045  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2046  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));
2047  if (length < 8)  if (length < 8)
2048    {    {
2049    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2050      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);
2051    }    }
2052  else  else
2053    {    {
2054    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2055    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2056    loop = LABEL();    loop = LABEL();
2057    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);
2058    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 2060  else
2060    }    }
2061  }  }
2062    
2063    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2064    {
2065    DEFINE_COMPILER;
2066    struct sljit_label *loop;
2067    int i;
2068    
2069    SLJIT_ASSERT(length > 1);
2070    /* OVECTOR(1) contains the "string begin - 1" constant. */
2071    if (length > 2)
2072      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2073    if (length < 8)
2074      {
2075      for (i = 2; i < length; i++)
2076        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2077      }
2078    else
2079      {
2080      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2081      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2082      loop = LABEL();
2083      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2084      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2085      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2086      }
2087    
2088    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2089    if (common->mark_ptr != 0)
2090      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2091    if (common->control_head_ptr != 0)
2092      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2093    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2094    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2095    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2096    }
2097    
2098    static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2099    {
2100    while (current != NULL)
2101      {
2102      switch (current[-2])
2103        {
2104        case type_then_trap:
2105        break;
2106    
2107        case type_mark:
2108        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2109          return current[-4];
2110        break;
2111    
2112        default:
2113        SLJIT_ASSERT_STOP();
2114        break;
2115        }
2116      current = (sljit_sw*)current[-1];
2117      }
2118    return -1;
2119    }
2120    
2121  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2122  {  {
2123  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1975  DEFINE_COMPILER; Line 2174  DEFINE_COMPILER;
2174  struct sljit_jump *jump;  struct sljit_jump *jump;
2175    
2176  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);
2177  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
2178      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2179    
2180  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2181  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 2187  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2187  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));
2188    
2189  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);
2190  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);
2191  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2192  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);
2193  #endif  #endif
# Line 5123  DEFINE_COMPILER; Line 5323  DEFINE_COMPILER;
5323  backtrack_common *backtrack;  backtrack_common *backtrack;
5324  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5325  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5326  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5327  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5328    BOOL needs_control_head;
5329    
5330  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5331    
5332  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5333  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5334    {    {
5335    start_cc = common->start + start;    start_cc = common->start + start;
5336    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 5449  allocate_stack(common, CALLOUT_ARG_SIZE
5449  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);
5450  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5451  SLJIT_ASSERT(common->capture_last_ptr != 0);  SLJIT_ASSERT(common->capture_last_ptr != 0);
5452  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]);
5453  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);
5454    
5455  /* These pointer sized fields temporarly stores internal variables. */  /* These pointer sized fields temporarly stores internal variables. */
5456  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 5459  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA
5459    
5460  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
5461    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));
5462  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));
5463  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));
5464  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);
5465    
5466  /* Needed to save important temporary registers. */  /* Needed to save important temporary registers. */
# Line 5288  static pcre_uchar *compile_assert_matchi Line 5489  static pcre_uchar *compile_assert_matchi
5489  {  {
5490  DEFINE_COMPILER;  DEFINE_COMPILER;
5491  int framesize;  int framesize;
5492    int extrasize;
5493    BOOL needs_control_head;
5494  int private_data_ptr;  int private_data_ptr;
5495  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5496  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5297  jump_list *tmp = NULL; Line 5500  jump_list *tmp = NULL;
5500  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5501  jump_list **found;  jump_list **found;
5502  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5503    BOOL save_local_exit = common->local_exit;
5504    then_trap_backtrack *save_then_trap = common->then_trap;
5505  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5506  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5507  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
# Line 5304  jump_list *save_accept = common->accept; Line 5509  jump_list *save_accept = common->accept;
5509  struct sljit_jump *jump;  struct sljit_jump *jump;
5510  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5511    
5512    /* Assert captures then. */
5513    common->then_trap = NULL;
5514    
5515  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5516    {    {
5517    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5312  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5520  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5520    }    }
5521  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5522  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5523  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5524  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5525  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5526  opcode = *cc;  opcode = *cc;
# Line 5331  if (bra == OP_BRAMINZERO) Line 5539  if (bra == OP_BRAMINZERO)
5539    
5540  if (framesize < 0)  if (framesize < 0)
5541    {    {
5542    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5543    allocate_stack(common, 1);    if (framesize == no_frame)
5544        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5545      allocate_stack(common, extrasize);
5546      if (needs_control_head)
5547        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5548    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5549      if (needs_control_head)
5550        {
5551        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5552        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5553        }
5554    }    }
5555  else  else
5556    {    {
5557    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5558      allocate_stack(common, framesize + extrasize);
5559    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);
5560    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));
5561    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);
5562      if (needs_control_head)
5563        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5564    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5565    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5566    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5567        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5568        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5569        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5570        }
5571      else
5572        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5573      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5574    }    }
5575    
5576  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5577    common->local_exit = TRUE;
5578  common->quit_label = NULL;  common->quit_label = NULL;
5579  common->quit = NULL;  common->quit = NULL;
5580  while (1)  while (1)
# Line 5363  while (1) Line 5591  while (1)
5591    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5592    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5593      {      {
5594        common->local_exit = save_local_exit;
5595        common->then_trap = save_then_trap;
5596      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5597      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5598      common->quit = save_quit;      common->quit = save_quit;
# Line 5375  while (1) Line 5605  while (1)
5605    
5606    /* Reset stack. */    /* Reset stack. */
5607    if (framesize < 0)    if (framesize < 0)
5608      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5609    else {      if (framesize == no_frame)
5610          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5611        else
5612          free_stack(common, extrasize);
5613        if (needs_control_head)
5614          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5615        }
5616      else
5617        {
5618      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5619        {        {
5620        /* 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. */
5621        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));
5622          if (needs_control_head)
5623            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5624        }        }
5625      else      else
5626        {        {
5627        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);
5628          if (needs_control_head)
5629            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5630        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5631        }        }
5632    }      }
5633    
5634    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5635      {      {
5636      /* 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. */
5637      if (conditional)      if (conditional)
5638        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);
5639      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5640        {        {
5641        if (framesize < 0)        if (framesize < 0)
5642          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));
5643        else        else
5644          {          {
5645          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));
5646          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));
5647          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);
5648          }          }
5649        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 5660  while (1)
5660    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5661    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5662      {      {
5663        common->local_exit = save_local_exit;
5664        common->then_trap = save_then_trap;
5665      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5666      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5667      common->quit = save_quit;      common->quit = save_quit;
# Line 5432  while (1) Line 5676  while (1)
5676    ccbegin = cc;    ccbegin = cc;
5677    cc += GET(cc, 1);    cc += GET(cc, 1);
5678    }    }
5679    
5680  /* None of them matched. */  /* None of them matched. */
5681  if (common->quit != NULL)  if (common->quit != NULL)
5682      {
5683      jump = JUMP(SLJIT_JUMP);
5684    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5685      SLJIT_ASSERT(framesize != no_stack);
5686      if (framesize < 0)
5687        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5688      else
5689        {
5690        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5691        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5692        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5693        }
5694      JUMPHERE(jump);
5695      }
5696    
5697    if (needs_control_head)
5698      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5699    
5700  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5701    {    {
# Line 5446  if (opcode == OP_ASSERT || opcode == OP_ Line 5707  if (opcode == OP_ASSERT || opcode == OP_
5707      {      {
5708      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5709      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5710          {
5711          if (extrasize == 2)
5712            free_stack(common, 1);
5713        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5714          }
5715      else      else
5716        free_stack(common, 1);        free_stack(common, extrasize);
5717      }      }
5718    else    else
5719      {      {
5720      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5721      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5722      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5723        {        {
5724        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5725        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5726        }        }
5727      else      else
5728        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5729      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);
5730      }      }
5731    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5472  if (opcode == OP_ASSERT || opcode == OP_ Line 5737  if (opcode == OP_ASSERT || opcode == OP_
5737    if (framesize < 0)    if (framesize < 0)
5738      {      {
5739      /* 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. */
5740      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));
5741      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5742      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5743          {
5744        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));
5745          if (extrasize == 2)
5746            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5747          }
5748      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5749        {        {
5750        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 5757  if (opcode == OP_ASSERT || opcode == OP_
5757        {        {
5758        /* 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. */
5759        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));
5760        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));
5761        }        }
5762      else      else
5763        {        {
5764        /* 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. */
5765        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));
5766        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5767        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5768            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5769            if (bra == OP_BRAMINZERO)
5770              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5771            }
5772          else
5773            {
5774            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5775            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5776            }
5777        }        }
5778      }      }
5779    
# Line 5524  else Line 5802  else
5802      {      {
5803      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5804      if (bra != OP_BRA)      if (bra != OP_BRA)
5805          {
5806          if (extrasize == 2)
5807            free_stack(common, 1);
5808        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5809          }
5810      else      else
5811        free_stack(common, 1);        free_stack(common, extrasize);
5812      }      }
5813    else    else
5814      {      {
5815      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5816      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5817      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5818      if (bra != OP_BRA)      if (bra != OP_BRA)
5819        {        {
5820        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5821        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5822        }        }
5823      else      else
5824        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5825      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);
5826      }      }
5827    
# Line 5559  else Line 5841  else
5841      }      }
5842    }    }
5843    
5844    common->local_exit = save_local_exit;
5845    common->then_trap = save_then_trap;
5846  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5847  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5848  common->quit = save_quit;  common->quit = save_quit;
# Line 5676  if (i < name_count) Line 5960  if (i < name_count)
5960  return condition;  return condition;
5961  }  }
5962    
5963    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)
5964    {
5965    DEFINE_COMPILER;
5966    int stacksize;
5967    
5968    if (framesize < 0)
5969      {
5970      if (framesize == no_frame)
5971        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5972      else
5973        {
5974        stacksize = needs_control_head ? 1 : 0;
5975        if (ket != OP_KET || has_alternatives)
5976          stacksize++;
5977        free_stack(common, stacksize);
5978        }
5979    
5980      if (needs_control_head)
5981        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
5982    
5983      /* TMP2 which is set here used by OP_KETRMAX below. */
5984      if (ket == OP_KETRMAX)
5985        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5986      else if (ket == OP_KETRMIN)
5987        {
5988        /* Move the STR_PTR to the private_data_ptr. */
5989        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5990        }
5991      }
5992    else
5993      {
5994      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
5995      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
5996      if (needs_control_head)
5997        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
5998    
5999      if (ket == OP_KETRMAX)
6000        {
6001        /* TMP2 which is set here used by OP_KETRMAX below. */
6002        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6003        }
6004      }
6005    if (needs_control_head)
6006      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6007    }
6008    
6009    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6010    {
6011    DEFINE_COMPILER;
6012    
6013    if (common->capture_last_ptr != 0)
6014      {
6015      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6016      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6017      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6018      stacksize++;
6019      }
6020    if (common->optimized_cbracket[offset >> 1] == 0)
6021      {
6022      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6023      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6024      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6025      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6026      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6027      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6028      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6029      stacksize += 2;
6030      }
6031    return stacksize;
6032    }
6033    
6034  /*  /*
6035    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6036    
# Line 5744  pcre_uchar bra = OP_BRA; Line 6099  pcre_uchar bra = OP_BRA;
6099  pcre_uchar ket;  pcre_uchar ket;
6100  assert_backtrack *assert;  assert_backtrack *assert;
6101  BOOL has_alternatives;  BOOL has_alternatives;
6102    BOOL needs_control_head = FALSE;
6103  struct sljit_jump *jump;  struct sljit_jump *jump;
6104  struct sljit_jump *skip;  struct sljit_jump *skip;
6105  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 5819  else if (opcode == OP_ONCE || opcode == Line 6175  else if (opcode == OP_ONCE || opcode ==
6175    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6176    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6177    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6178      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);
6179    }    }
6180    
6181  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6182  stacksize = 0;  stacksize = 0;
6183  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6184    stacksize++;    stacksize++;
6185  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6186    stacksize++;    stacksize++;
# Line 5833  if (stacksize > 0) Line 6189  if (stacksize > 0)
6189    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6190    
6191  stacksize = 0;  stacksize = 0;
6192  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6193    {    {
6194    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6195    stacksize++;    stacksize++;
# Line 5896  if (ket == OP_KETRMAX) Line 6252  if (ket == OP_KETRMAX)
6252  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6253  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6254    {    {
6255      stacksize = 0;
6256      if (needs_control_head)
6257        {
6258        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6259        stacksize++;
6260        }
6261    
6262    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6263      {      {
6264      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6265      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6266        {        {
6267        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6268        allocate_stack(common, 2);        if (!needs_control_head)
6269        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));  
6270        }        }
6271      else if (ket == OP_KETRMAX || has_alternatives)      else
6272        {        {
6273        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6274        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6275        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6276            stacksize++;
6277        }        }
6278      else  
6279        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6280          allocate_stack(common, stacksize);
6281    
6282        stacksize = 0;
6283        if (needs_control_head)
6284          {
6285          stacksize++;
6286          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6287          }
6288    
6289        if (ket == OP_KETRMIN)
6290          {
6291          if (needs_control_head)
6292            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6293          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6294          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6295            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));
6296          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6297          }
6298        else if (ket == OP_KETRMAX || has_alternatives)
6299          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6300      }      }
6301    else    else
6302      {      {
6303      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6304          stacksize++;
6305    
6306        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6307        allocate_stack(common, stacksize);
6308    
6309        if (needs_control_head)
6310          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6311    
6312        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6313        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6314    
6315        stacksize = needs_control_head ? 1 : 0;
6316        if (ket != OP_KET || has_alternatives)
6317        {        {
6318        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);  
6319        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);
6320        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6321        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6322        }        }
6323      else      else
6324        {        {
       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));  
6325        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);
6326        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);  
6327        }        }
6328        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6329      }      }
6330    }    }
6331  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 6461  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6461    return NULL;    return NULL;
6462    
6463  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6464    {    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));  
       }  
     }  
   }  
6465    
6466  stacksize = 0;  stacksize = 0;
6467  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6124  if (ket != OP_KET || bra != OP_BRA) Line 6490  if (ket != OP_KET || bra != OP_BRA)
6490    }    }
6491    
6492  if (offset != 0)  if (offset != 0)
6493    {    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;  
     }  
   }  
6494    
6495  if (has_alternatives)  if (has_alternatives)
6496    {    {
# Line 6214  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6561  if ((ket != OP_KET && bra != OP_BRAMINZE
6561  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6562    cc += GET(cc, 1);    cc += GET(cc, 1);
6563  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6564    
6565    /* Temporarily encoding the needs_control_head in framesize. */
6566    if (opcode == OP_ONCE)
6567      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6568  return cc;  return cc;
6569  }  }
6570    
# Line 6224  backtrack_common *backtrack; Line 6575  backtrack_common *backtrack;
6575  pcre_uchar opcode;  pcre_uchar opcode;
6576  int private_data_ptr;  int private_data_ptr;
6577  int cbraprivptr = 0;  int cbraprivptr = 0;
6578    BOOL needs_control_head;
6579  int framesize;  int framesize;
6580  int stacksize;  int stacksize;
6581  int offset = 0;  int offset = 0;
6582  BOOL zero = FALSE;  BOOL zero = FALSE;
6583  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6584  int stack;  int stack; /* Also contains the offset of control head. */
6585  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6586  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6587    
# Line 6267  switch(opcode) Line 6619  switch(opcode)
6619    break;    break;
6620    }    }
6621    
6622  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6623  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6624  if (framesize < 0)  if (framesize < 0)
6625    {    {
# Line 6280  if (framesize < 0) Line 6632  if (framesize < 0)
6632    else    else
6633      stacksize = 1;      stacksize = 1;
6634    
6635      if (needs_control_head)
6636        stacksize++;
6637    if (!zero)    if (!zero)
6638      stacksize++;      stacksize++;
6639    
# Line 6288  if (framesize < 0) Line 6642  if (framesize < 0)
6642    if (framesize == no_frame)    if (framesize == no_frame)
6643      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);
6644    
6645      stack = 0;
6646    if (offset != 0)    if (offset != 0)
6647      {      {
6648        stack = 2;
6649      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6650      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));
6651      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6652      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6653        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);
6654      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6655        if (needs_control_head)
6656          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6657      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6658          {
6659        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6660          stack = 3;
6661          }
6662      }      }
6663    else    else
6664        {
6665        if (needs_control_head)
6666          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6667      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6668        stack = 1;
6669        }
6670    
6671      if (needs_control_head)
6672        stack++;
6673    if (!zero)    if (!zero)
6674      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);
6675      if (needs_control_head)
6676        {
6677        stack--;
6678        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6679        }
6680    }    }
6681  else  else
6682    {    {
6683    stacksize = framesize + 1;    stacksize = framesize + 1;
6684    if (!zero)    if (!zero)
6685      stacksize++;      stacksize++;
6686    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6687        stacksize++;
6688      if (offset == 0)
6689      stacksize++;      stacksize++;
6690    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6691    
6692    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6693    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);
6694    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6695    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);
6696      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6697    
6698    stack = 0;    stack = 0;
6699    if (!zero)    if (!zero)
6700      {      {
6701      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6702        stack = 1;
6703        }
6704      if (needs_control_head)
6705        {
6706        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6707      stack++;      stack++;
6708      }      }
6709    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6710      {      {
6711      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6712      stack++;      stack++;
6713      }      }
6714    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6715    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6716      stack -= 1 + (offset == 0);
6717    }    }
6718    
6719  if (offset != 0)  if (offset != 0)
# Line 6407  while (*cc != OP_KETRPOS) Line 6789  while (*cc != OP_KETRPOS)
6789          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6790        }        }
6791      }      }
6792    
6793      if (needs_control_head)
6794        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6795    
6796    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6797    flush_stubs(common);    flush_stubs(common);
6798    
# Line 6443  while (*cc != OP_KETRPOS) Line 6829  while (*cc != OP_KETRPOS)
6829    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6830    }    }
6831    
6832    /* We don't have to restore the control head in case of a failed match. */
6833    
6834  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6835  if (!zero)  if (!zero)
6836    {    {
# Line 6831  if (!optimized_cbracket) Line 7219  if (!optimized_cbracket)
7219  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7220  }  }
7221    
7222    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7223    {
7224    DEFINE_COMPILER;
7225    backtrack_common *backtrack;
7226    pcre_uchar opcode = *cc;
7227    pcre_uchar *ccend = cc + 1;
7228    
7229    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7230      ccend += 2 + cc[1];
7231    
7232    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7233    
7234    if (opcode == OP_SKIP)
7235      {
7236      allocate_stack(common, 1);
7237      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7238      return ccend;
7239      }
7240    
7241    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7242      {
7243      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7244      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7245      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7246      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7247      }
7248    
7249    return ccend;
7250    }
7251    
7252    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7253    
7254    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7255    {
7256    DEFINE_COMPILER;
7257    backtrack_common *backtrack;
7258    BOOL needs_control_head;
7259    int size;
7260    
7261    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7262    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7263    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7264    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7265    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7266    
7267    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7268    size = 3 + (size < 0 ? 0 : size);
7269    
7270    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7271    allocate_stack(common, size);
7272    if (size > 3)
7273      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7274    else
7275      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7276    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7277    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7278    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7279    
7280    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7281    if (size >= 0)
7282      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7283    }
7284    
7285  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)
7286  {  {
7287  DEFINE_COMPILER;  DEFINE_COMPILER;
7288  backtrack_common *backtrack;  backtrack_common *backtrack;
7289    BOOL has_then_trap = FALSE;
7290    then_trap_backtrack *save_then_trap = NULL;
7291    
7292    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7293    
7294    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7295      {
7296      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7297      has_then_trap = TRUE;
7298      save_then_trap = common->then_trap;
7299      /* Tail item on backtrack. */
7300      compile_then_trap_matchingpath(common, cc, ccend, parent);
7301      }
7302    
7303  while (cc < ccend)  while (cc < ccend)
7304    {    {
# Line 7051  while (cc < ccend) Line 7515  while (cc < ccend)
7515      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7516      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7517      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);
7518      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7519      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7520      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);
7521      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7522      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);
7523      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);
7524        if (common->has_skip_arg)
7525          {
7526          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7527          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7528          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7529          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7530          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7531          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7532          }
7533      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7534      break;      break;
7535    
7536        case OP_PRUNE:
7537        case OP_PRUNE_ARG:
7538        case OP_SKIP:
7539        case OP_SKIP_ARG:
7540        case OP_THEN:
7541        case OP_THEN_ARG:
7542      case OP_COMMIT:      case OP_COMMIT:
7543      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7544      break;      break;
7545    
7546      case OP_FAIL:      case OP_FAIL:
# Line 7086  while (cc < ccend) Line 7564  while (cc < ccend)
7564    if (cc == NULL)    if (cc == NULL)
7565      return;      return;
7566    }    }
7567    
7568    if (has_then_trap)
7569      {
7570      /* Head item on backtrack. */
7571      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7572      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7573      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7574      common->then_trap = save_then_trap;
7575      }
7576  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7577  }  }
7578    
# Line 7247  switch(opcode) Line 7734  switch(opcode)
7734    }    }
7735  }  }
7736    
7737  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)
7738  {  {
7739  DEFINE_COMPILER;  DEFINE_COMPILER;
7740  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7269  set_jumps(current->topbacktracks, LABEL( Line 7756  set_jumps(current->topbacktracks, LABEL(
7756  free_stack(common, 2);  free_stack(common, 2);
7757  }  }
7758    
7759  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)
7760  {  {
7761  DEFINE_COMPILER;  DEFINE_COMPILER;
7762    
# Line 7379  pcre_uchar bra = OP_BRA; Line 7866  pcre_uchar bra = OP_BRA;
7866  pcre_uchar ket;  pcre_uchar ket;
7867  assert_backtrack *assert;  assert_backtrack *assert;
7868  BOOL has_alternatives;  BOOL has_alternatives;
7869    BOOL needs_control_head = FALSE;
7870  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7871  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7872  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7404  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7892  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7892  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7893    opcode = OP_ONCE;    opcode = OP_ONCE;
7894    
7895    /* Decoding the needs_control_head in framesize. */
7896    if (opcode == OP_ONCE)
7897      {
7898      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7899      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7900      }
7901    
7902  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7903    {    {
7904    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7561  if (has_alternatives) Line 8056  if (has_alternatives)
8056      current->top = NULL;      current->top = NULL;
8057      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8058      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8059        /* Conditional blocks always have an additional alternative, even if it is empty. */
8060      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8061        {        {
8062        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8063        cc += GET(cc, 1);        cc += GET(cc, 1);
8064        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8065          {          {
8066          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8067            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8068              if (private_data_ptr != 0)
8069                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8070              else
8071                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8072              }
8073          else          else
8074            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));
8075          }          }
8076        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8077        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7580  if (has_alternatives) Line 8081  if (has_alternatives)
8081      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8082      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8083      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8084        {        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));  
           }  
         }  
       }  
8085    
8086      stacksize = 0;      stacksize = 0;
8087      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7617  if (has_alternatives) Line 8096  if (has_alternatives)
8096      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8097        stacksize++;        stacksize++;
8098    
8099      if (stacksize > 0) {      if (stacksize > 0)
8100          {
8101        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8102          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
8103        else        else
# Line 7626  if (has_alternatives) Line 8106  if (has_alternatives)
8106          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
8107          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));
8108          }          }
8109      }        }
8110    
8111      stacksize = 0;      stacksize = 0;
8112      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7639  if (has_alternatives) Line 8119  if (has_alternatives)
8119        }        }
8120    
8121      if (offset != 0)      if (offset != 0)
8122        {        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;  
         }  
       }  
8123    
8124      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8125        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 8153  if (has_alternatives)
8153      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8154      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8155      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)
   
8156        {        {
8157        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);
8158        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 8192  else if (opcode == OP_SBRA || opcode ==
8192  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8193    {    {
8194    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8195      stacksize = needs_control_head ? 1 : 0;
8196    
8197    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8198      {      {
8199      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8200      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);  
8201      }      }
8202    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8203      {      {
8204      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8205      free_stack(common, 1);      stacksize++;
8206      }      }
8207      free_stack(common, stacksize);
8208    
8209    JUMPHERE(once);    JUMPHERE(once);
8210    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7794  else if (bra == OP_BRAZERO) Line 8256  else if (bra == OP_BRAZERO)
8256    }    }
8257  }  }
8258    
8259  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)
8260  {  {
8261  DEFINE_COMPILER;  DEFINE_COMPILER;
8262  int offset;  int offset;
# Line 7833  if (current->topbacktracks) Line 8295  if (current->topbacktracks)
8295  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));
8296  }  }
8297    
8298  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)
8299  {  {
8300  assert_backtrack backtrack;  assert_backtrack backtrack;
8301    
# Line 7857  else Line 8319  else
8319  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8320  }  }
8321    
8322    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8323    {
8324    DEFINE_COMPILER;
8325    pcre_uchar opcode = *current->cc;
8326    struct sljit_label *loop;
8327    struct sljit_jump *jump;
8328    
8329    if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8330      {
8331      SLJIT_ASSERT(common->control_head_ptr != 0);
8332    
8333      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8334      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8335      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8336      jump = JUMP(SLJIT_JUMP);
8337    
8338      loop = LABEL();
8339      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8340      JUMPHERE(jump);
8341      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8342      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8343      add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8344      return;
8345      }
8346    
8347    if (common->local_exit)
8348      {
8349      if (common->quit_label == NULL)
8350        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8351      else
8352        JUMPTO(SLJIT_JUMP, common->quit_label);
8353      return;
8354      }
8355    
8356    if (opcode == OP_SKIP_ARG)
8357      {
8358      SLJIT_ASSERT(common->control_head_ptr != 0);
8359      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8360      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8361      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8362      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8363      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8364    
8365      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8366      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8367      return;
8368      }
8369    
8370    if (opcode == OP_SKIP)
8371      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8372    else
8373      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8374    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8375    }
8376    
8377    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8378    {
8379    DEFINE_COMPILER;
8380    struct sljit_jump *jump;
8381    int size;
8382    
8383    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8384      {
8385      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8386      return;
8387      }
8388    
8389    size = CURRENT_AS(then_trap_backtrack)->framesize;
8390    size = 3 + (size < 0 ? 0 : size);
8391    
8392    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8393    free_stack(common, size);
8394    jump = JUMP(SLJIT_JUMP);
8395    
8396    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8397    /* STACK_TOP is set by THEN. */
8398    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8399      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8400    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8401    free_stack(common, 3);
8402    
8403    JUMPHERE(jump);
8404    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8405    }
8406    
8407  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8408  {  {
8409  DEFINE_COMPILER;  DEFINE_COMPILER;
8410    then_trap_backtrack *save_then_trap = common->then_trap;
8411    
8412  while (current)  while (current)
8413    {    {
# Line 7993  while (current) Line 8541  while (current)
8541      break;      break;
8542    
8543      case OP_MARK:      case OP_MARK:
8544      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));
8545      free_stack(common, 1);      if (common->has_skip_arg)
8546          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8547        free_stack(common, common->has_skip_arg ? 5 : 1);
8548      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);
8549        if (common->has_skip_arg)
8550          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8551        break;
8552    
8553        case OP_THEN:
8554        case OP_THEN_ARG:
8555        case OP_PRUNE:
8556        case OP_PRUNE_ARG:
8557        case OP_SKIP:
8558        case OP_SKIP_ARG:
8559        compile_control_verb_backtrackingpath(common, current);
8560      break;      break;
8561    
8562      case OP_COMMIT:      case OP_COMMIT:
8563      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8564          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8565      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8566        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8567      else      else
# Line 8013  while (current) Line 8575  while (current)
8575      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8576      break;      break;
8577    
8578        case OP_THEN_TRAP:
8579        /* A virtual opcode for then traps. */
8580        compile_then_trap_backtrackingpath(common, current);
8581        break;
8582    
8583      default:      default:
8584      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8585      break;      break;
8586      }      }
8587    current = current->prev;    current = current->prev;
8588    }    }
8589    common->then_trap = save_then_trap;
8590  }  }
8591    
8592  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8027  DEFINE_COMPILER; Line 8595  DEFINE_COMPILER;
8595  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8596  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);
8597  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8598  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8599  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8600    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8601  int alternativesize;  int alternativesize;
8602  BOOL needsframe;  BOOL needs_frame;
8603  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quit_label = common->quit_label;  
 jump_list *save_quit = common->quit;  
8604  struct sljit_jump *jump;  struct sljit_jump *jump;
8605    
8606    /* Recurse captures then. */
8607    common->then_trap = NULL;
8608    
8609  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);
8610  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8611  if (!needsframe)  if (!needs_frame)
8612    framesize = 0;    framesize = 0;
8613  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8614    
# Line 8049  set_jumps(common->currententry->calls, c Line 8619  set_jumps(common->currententry->calls, c
8619  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8620  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8621  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);
8622  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);
8623    if (needs_control_head)
8624      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8625  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);
8626  if (needsframe)  if (needs_frame)
8627    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8628    
8629  if (alternativesize > 0)  if (alternativesize > 0)
8630    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 8646  while (1)
8646    
8647    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8648    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;  
8649      return;      return;
     }  
8650    
8651    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8652    
8653    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8654    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;  
8655      return;      return;
     }  
8656    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8657    
8658    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 8097  while (1) Line 8661  while (1)
8661    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8662    cc += GET(cc, 1);    cc += GET(cc, 1);
8663    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8664    
8665    /* None of them matched. */
8666  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8667  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8668    
8669    if (common->quit != NULL)
8670      {
8671      set_jumps(common->quit, LABEL());
8672      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8673      if (needs_frame)
8674        {
8675        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8676        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8677        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8678        }
8679      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8680      common->quit = NULL;
8681      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8682      }
8683    
8684  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8685  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);
8686  if (needsframe)  if (needs_frame)
8687    {    {
8688    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));
8689    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 8115  if (needsframe) Line 8692  if (needsframe)
8692  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8693    
8694  JUMPHERE(jump);  JUMPHERE(jump);
8695  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8696      set_jumps(common->quit, LABEL());
8697    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8698  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8699  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8700  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8701  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));
8702      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8703      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8704      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8705      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8706      }
8707    else
8708      {
8709      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8710      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8711      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8712      }
8713  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;  
8714  }  }
8715    
8716  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 8143  pcre_uchar *ccend; Line 8730  pcre_uchar *ccend;
8730  executable_functions *functions;  executable_functions *functions;
8731  void *executable_func;  void *executable_func;
8732  sljit_uw executable_size;  sljit_uw executable_size;
8733  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8734  struct sljit_label *empty_match_found;  struct sljit_label *continue_match_label;
8735  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_found_label;
8736    struct sljit_label *empty_match_backtrack_label;
8737    struct sljit_label *reset_match_label;
8738  struct sljit_jump *jump;  struct sljit_jump *jump;
8739  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
8740  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8741  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8742    struct sljit_label *quit_label;
8743    
8744  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8745  study = extra->study_data;  study = extra->study_data;
# Line 8245  if (mode == JIT_COMPILE && (re->flags & Line 8835  if (mode == JIT_COMPILE && (re->flags &
8835  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8836    {    {
8837    common->start_used_ptr = common->ovector_start;    common->start_used_ptr = common->ovector_start;
8838    common->ovector_start += 2 * sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8839    if (mode == JIT_PARTIAL_SOFT_COMPILE)    if (mode == JIT_PARTIAL_SOFT_COMPILE)
8840      {      {
8841      common->hit_start = common->ovector_start;      common->hit_start = common->ovector_start;
8842      common->ovector_start += sizeof(sljit_sw);      common->ovector_start += 2 * sizeof(sljit_sw);
8843        }
8844      else
8845        {
8846        SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
8847        common->needs_start_ptr = TRUE;
8848      }      }
8849    }    }
8850  if ((re->options & PCRE_FIRSTLINE) != 0)  if ((re->options & PCRE_FIRSTLINE) != 0)
# Line 8257  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8852  if ((re->options & PCRE_FIRSTLINE) != 0)
8852    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
8853    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8854    }    }
8855    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
8856    common->control_head_ptr = 1;
8857    #endif
8858    if (common->control_head_ptr != 0)
8859      {
8860      common->control_head_ptr = common->ovector_start;
8861      common->ovector_start += sizeof(sljit_sw);
8862      }
8863    if (common->needs_start_ptr && common->has_set_som)
8864      {
8865      /* Saving the real start pointer is necessary. */
8866      common->start_ptr = common->ovector_start;
8867      common->ovector_start += sizeof(sljit_sw);
8868      }
8869    else
8870      common->needs_start_ptr = FALSE;
8871    
8872  /* Aligning ovector to even number of sljit words. */  /* Aligning ovector to even number of sljit words. */
8873  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8874    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8875    
8876    if (common->start_ptr == 0)
8877      common->start_ptr = OVECTOR(0);
8878    
8879  /* Capturing brackets cannot be optimized if callouts are allowed. */  /* Capturing brackets cannot be optimized if callouts are allowed. */
8880  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8881    memset(common->optimized_cbracket, 0, re->top_bracket + 1);    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8882    
8883  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8884  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);
8885  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);
8886  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
8887    {    {
8888    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8889    return;    return;
8890    }    }
8891    
8892  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
8893  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
8894    {    {
# Line 8281  if (!common->private_data_ptrs) Line 8896  if (!common->private_data_ptrs)
8896    return;    return;
8897    }    }
8898  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8899  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);
8900    
8901    if (common->has_then)
8902      {
8903      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
8904      if (!common->then_offsets)
8905        {
8906        SLJIT_FREE(common->optimized_cbracket);
8907        SLJIT_FREE(common->private_data_ptrs);
8908        return;
8909        }
8910      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
8911      set_then_offsets(common, rootbacktrack.cc, NULL);
8912      }
8913    
8914  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
8915  if (!compiler)  if (!compiler)
8916    {    {
8917    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8918    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
8919      if (common->has_then)
8920        SLJIT_FREE(common->then_offsets);
8921    return;    return;
8922    }    }
8923  common->compiler = compiler;  common->compiler = compiler;
# Line 8312  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 8942  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
8942    
8943  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8944    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);
8945    if (common->mark_ptr != 0)
8946      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
8947    if (common->control_head_ptr != 0)
8948      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8949    
8950  /* Main part of the matching */  /* Main part of the matching */
8951  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
8952    {    {
8953    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);
8954      continue_match_label = LABEL();
8955    /* Forward search if possible. */    /* Forward search if possible. */
8956    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
8957      {      {
# Line 8330  if ((re->options & PCRE_ANCHORED) == 0) Line 8965  if ((re->options & PCRE_ANCHORED) == 0)
8965        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);
8966      }      }
8967    }    }
8968    else
8969      continue_match_label = LABEL();
8970    
8971  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)
8972    {    {
8973    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 8981  if (common->req_char_ptr != 0)
8981  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);
8982  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
8983  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);  
8984  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8985    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);
8986    
8987    if (common->needs_start_ptr)
8988      {
8989      SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
8990      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
8991      }
8992    else
8993      SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
8994    
8995  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
8996  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8997    {    {
8998    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);
8999    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);
9000    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);
9001    JUMPHERE(jump);    JUMPHERE(jump);
9002    }    }
9003  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
   {  
9004    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);  
   }  
9005    
9006  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
9007  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 9009  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9009    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9010    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9011    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9012      if (common->has_then)
9013        SLJIT_FREE(common->then_offsets);
9014    return;    return;
9015    }    }
9016    
9017  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));
9018  empty_match_found = LABEL();  empty_match_found_label = LABEL();
9019    
9020  common->accept_label = LABEL();  common->accept_label = LABEL();
9021  if (common->accept != NULL)  if (common->accept != NULL)
# Line 8395  if (mode != JIT_COMPILE) Line 9039  if (mode != JIT_COMPILE)
9039    return_with_partial_match(common, common->quit_label);    return_with_partial_match(common, common->quit_label);
9040    }    }
9041    
9042  empty_match_backtrack = LABEL();  empty_match_backtrack_label = LABEL();
9043  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
9044  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9045    {    {
9046    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9047    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9048    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9049      if (common->has_then)
9050        SLJIT_FREE(common->then_offsets);
9051    return;    return;
9052    }    }
9053    
9054  SLJIT_ASSERT(rootbacktrack.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
9055    reset_match_label = LABEL();
9056    
9057  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9058    {    {
# Line 8423  if ((re->options & PCRE_ANCHORED) == 0 & Line 9070  if ((re->options & PCRE_ANCHORED) == 0 &
9070    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
9071    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);
9072    }    }
9073  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
9074    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
9075    
9076  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9077    {    {
9078    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
9079      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
9080    else    else
9081      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
9082    }    }
9083    
9084  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8448  flush_stubs(common); Line 9096  flush_stubs(common);
9096  JUMPHERE(empty_match);  JUMPHERE(empty_match);
9097  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9098  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));
9099  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);
9100  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));
9101  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);
9102  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));
9103  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);
9104  JUMPTO(SLJIT_JUMP, empty_match_backtrack);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9105    
9106  common->currententry = common->entries;  common->currententry = common->entries;
9107    common->local_exit = TRUE;
9108    quit_label = common->quit_label;
9109  while (common->currententry != NULL)  while (common->currententry != NULL)
9110    {    {
9111    /* Might add new entries. */    /* Might add new entries. */
# Line 8465  while (common->currententry != NULL) Line 9115  while (common->currententry != NULL)
9115      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9116      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9117      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9118        if (common->has_then)
9119          SLJIT_FREE(common->then_offsets);
9120      return;      return;
9121      }      }
9122    flush_stubs(common);    flush_stubs(common);
9123    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
9124    }    }
9125    common->local_exit = FALSE;
9126    common->quit_label = quit_label;
9127    
9128  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
9129  /* This is a (really) rare case. */  /* This is a (really) rare case. */
# Line 8537  if (common->caselesscmp != NULL) Line 9191  if (common->caselesscmp != NULL)
9191    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
9192    do_caselesscmp(common);    do_caselesscmp(common);
9193    }    }
9194    if (common->reset_match != NULL)
9195      {
9196      set_jumps(common->reset_match, LABEL());
9197      do_reset_match(common, (re->top_bracket + 1) * 2);
9198      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
9199      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
9200      JUMPTO(SLJIT_JUMP, reset_match_label);
9201      }
9202  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9203  #ifndef COMPILE_PCRE32  #ifndef COMPILE_PCRE32
9204  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
# Line 8563  if (common->getucd != NULL) Line 9225  if (common->getucd != NULL)
9225    
9226  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9227  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9228    if (common->has_then)
9229      SLJIT_FREE(common->then_offsets);
9230    
9231  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9232  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9233  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

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

  ViewVC Help
Powered by ViewVC 1.1.5