/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

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

revision 1275 by zherczeg, Sun Mar 10 05:32:10 2013 UTC revision 1290 by zherczeg, Sat Mar 16 18:45:51 2013 UTC
# Line 202  enum frame_types { Line 202  enum frame_types {
202  };  };
203    
204  enum control_types {  enum control_types {
205    type_commit = 0,    type_mark = 0,
206    type_prune = 1,    type_then_trap = 1
   type_skip = 2  
207  };  };
208    
209  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
# Line 227  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 248  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 283  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 291  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 {
# Line 302  typedef struct compiler_common { Line 316  typedef struct compiler_common {
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 cbra_ptr;    int cbra_ptr;
325    /* Output vector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
# Line 330  typedef struct compiler_common { Line 348  typedef struct compiler_common {
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 in the pattern. */    /* \K is found in the pattern. */
352    BOOL has_set_som;    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. */    /* Needs to know the start position anytime. */
358    BOOL needs_start_ptr;    BOOL needs_start_ptr;
359    /* Currently in recurse or assert. */    /* Currently in recurse or assert. */
# Line 513  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 597  switch(*cc) Line 619  switch(*cc)
619    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
620    case OP_PRUNE:    case OP_PRUNE:
621    case OP_SKIP:    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 696  switch(*cc) Line 719  switch(*cc)
719    
720    case OP_MARK:    case OP_MARK:
721    case OP_PRUNE_ARG:    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 947  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:      case OP_PRUNE_ARG:
983      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
     common->control_head_ptr = 1;  
984      /* Fall through. */      /* Fall through. */
985    
986      case OP_MARK:      case OP_MARK:
# Line 961  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:      case OP_PRUNE:
1001      case OP_SKIP:      case OP_SKIP:
1002      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
1003      /* Fall through. */      cc += 1;
1004        break;
1005    
1006      case OP_COMMIT:      case OP_SKIP_ARG:
1007      common->control_head_ptr = 1;      common->control_head_ptr = 1;
1008      cc += 1;      common->has_skip_arg = TRUE;
1009        cc += 1 + 2 + cc[1];
1010      break;      break;
1011    
1012      default:      default:
# Line 1148  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 1159  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 1184  while (cc < ccend) Line 1232  while (cc < ccend)
1232    
1233      case OP_MARK:      case OP_MARK:
1234      case OP_PRUNE_ARG:      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 1191  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 1310  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 1325  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 1347  while (cc < ccend) Line 1402  while (cc < ccend)
1402    
1403      case OP_MARK:      case OP_MARK:
1404      case OP_PRUNE_ARG:      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 1427  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 = common->control_head_ptr ? 3 : 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 1542  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 1563  stacktop = STACK(stacktop - 1); Line 1619  stacktop = STACK(stacktop - 1);
1619    
1620  if (!save)  if (!save)
1621    {    {
1622    stackptr += (common->control_head_ptr ? 2 : 1) * 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 1588  do Line 1644  do
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 (common->control_head_ptr != 0)      if (needs_control_head)
1648        {        {
1649          SLJIT_ASSERT(common->control_head_ptr != 0);
1650        count = 2;        count = 2;
1651        srcw[1] = common->control_head_ptr;        srcw[1] = common->control_head_ptr;
1652        }        }
# Line 1851  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 1998  else Line 2088  else
2088  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2089  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2090    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2091  SLJIT_ASSERT(common->control_head_ptr != 0);  if (common->control_head_ptr != 0)
2092  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);    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));  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);  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));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2096  }  }
2097    
2098  static sljit_sw do_check_control_chain(sljit_sw *current)  static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2099  {  {
2100  sljit_sw return_value = 0;  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  SLJIT_ASSERT(current != NULL);      default:
2113        SLJIT_ASSERT_STOP();
2114        break;
2115        }
2116      current = (sljit_sw*)current[-1];
2117      }
2118    return -1;
2119    }
2120    
2121    static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)
2122    {
2123  do  do
2124    {    {
2125      SLJIT_ASSERT(current != NULL);
2126    switch (current[-2])    switch (current[-2])
2127      {      {
2128      case type_commit:      case type_then_trap:
2129      /* Commit overwrites all. */      if (current[-3] == start)
2130      return -1;        return (sljit_sw)current;
   
     case type_prune:  
2131      break;      break;
2132    
2133      case type_skip:      case type_mark:
     /* Overwrites prune, but not other skips. */  
     if (return_value == 0)  
       return_value = current[-3];  
2134      break;      break;
2135    
2136      default:      default:
# Line 2033  do Line 2139  do
2139      }      }
2140    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
2141    }    }
2142  while (current != NULL);  while (TRUE);
 return return_value;  
2143  }  }
2144    
2145  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
# Line 2106  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 2211  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2211  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));
2212    
2213  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);
2214  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + 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);
2215  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2216  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);
2217  #endif  #endif
# Line 5242  DEFINE_COMPILER; Line 5347  DEFINE_COMPILER;
5347  backtrack_common *backtrack;  backtrack_common *backtrack;
5348  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5349  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5350  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5351  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5352    BOOL needs_control_head;
5353    
5354  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5355    
5356  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5357  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5358    {    {
5359    start_cc = common->start + start;    start_cc = common->start + start;
5360    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 5408  static pcre_uchar *compile_assert_matchi Line 5514  static pcre_uchar *compile_assert_matchi
5514  DEFINE_COMPILER;  DEFINE_COMPILER;
5515  int framesize;  int framesize;
5516  int extrasize;  int extrasize;
5517  BOOL needs_control_head = common->control_head_ptr != 0;  BOOL needs_control_head;
5518  int private_data_ptr;  int private_data_ptr;
5519  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5520  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5418  jump_list *tmp = NULL; Line 5524  jump_list *tmp = NULL;
5524  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5525  jump_list **found;  jump_list **found;
5526  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5527    BOOL save_local_exit = common->local_exit;
5528    then_trap_backtrack *save_then_trap = common->then_trap;
5529  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5530  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5531  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5532  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
 BOOL save_local_exit = common->local_exit;  
5533  struct sljit_jump *jump;  struct sljit_jump *jump;
5534  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5535    
5536    /* Assert captures then. */
5537    common->then_trap = NULL;
5538    
5539  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5540    {    {
5541    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5434  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5544  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5544    }    }
5545  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5546  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5547  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5548  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5549  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5550  opcode = *cc;  opcode = *cc;
# Line 5454  if (bra == OP_BRAMINZERO) Line 5564  if (bra == OP_BRAMINZERO)
5564  if (framesize < 0)  if (framesize < 0)
5565    {    {
5566    extrasize = needs_control_head ? 2 : 1;    extrasize = needs_control_head ? 2 : 1;
5567    if (framesize != no_stack)    if (framesize == no_frame)
5568      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);
5569    allocate_stack(common, extrasize);    allocate_stack(common, extrasize);
5570    if (needs_control_head)    if (needs_control_head)
# Line 5484  else Line 5594  else
5594      }      }
5595    else    else
5596      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5597    init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5598    }    }
5599    
5600  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
# Line 5506  while (1) Line 5616  while (1)
5616    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5617      {      {
5618      common->local_exit = save_local_exit;      common->local_exit = save_local_exit;
5619        common->then_trap = save_then_trap;
5620      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5621      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5622      common->quit = save_quit;      common->quit = save_quit;
# Line 5519  while (1) Line 5630  while (1)
5630    /* Reset stack. */    /* Reset stack. */
5631    if (framesize < 0)    if (framesize < 0)
5632      {      {
5633      if (framesize != no_stack)      if (framesize == no_frame)
5634        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);
5635      else      else
5636        free_stack(common, extrasize);        free_stack(common, extrasize);
# Line 5574  while (1) Line 5685  while (1)
5685    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5686      {      {
5687      common->local_exit = save_local_exit;      common->local_exit = save_local_exit;
5688        common->then_trap = save_then_trap;
5689      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5690      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5691      common->quit = save_quit;      common->quit = save_quit;
# Line 5754  else Line 5866  else
5866    }    }
5867    
5868  common->local_exit = save_local_exit;  common->local_exit = save_local_exit;
5869    common->then_trap = save_then_trap;
5870  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5871  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5872  common->quit = save_quit;  common->quit = save_quit;
# Line 5871  if (i < name_count) Line 5984  if (i < name_count)
5984  return condition;  return condition;
5985  }  }
5986    
5987    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)
5988    {
5989    DEFINE_COMPILER;
5990    int stacksize;
5991    
5992    if (framesize < 0)
5993      {
5994      if (framesize == no_frame)
5995        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5996      else
5997        {
5998        stacksize = needs_control_head ? 1 : 0;
5999        if (ket != OP_KET || has_alternatives)
6000          stacksize++;
6001        free_stack(common, stacksize);
6002        }
6003    
6004      if (needs_control_head)
6005        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6006    
6007      /* TMP2 which is set here used by OP_KETRMAX below. */
6008      if (ket == OP_KETRMAX)
6009        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6010      else if (ket == OP_KETRMIN)
6011        {
6012        /* Move the STR_PTR to the private_data_ptr. */
6013        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6014        }
6015      }
6016    else
6017      {
6018      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6019      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6020      if (needs_control_head)
6021        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6022    
6023      if (ket == OP_KETRMAX)
6024        {
6025        /* TMP2 which is set here used by OP_KETRMAX below. */
6026        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6027        }
6028      }
6029    if (needs_control_head)
6030      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6031    }
6032    
6033    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6034    {
6035    DEFINE_COMPILER;
6036    
6037    if (common->capture_last_ptr != 0)
6038      {
6039      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6040      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6041      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6042      stacksize++;
6043      }
6044    if (common->optimized_cbracket[offset >> 1] == 0)
6045      {
6046      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6047      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6048      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6049      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6050      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6051      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6052      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6053      stacksize += 2;
6054      }
6055    return stacksize;
6056    }
6057    
6058  /*  /*
6059    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6060    
# Line 5939  pcre_uchar bra = OP_BRA; Line 6123  pcre_uchar bra = OP_BRA;
6123  pcre_uchar ket;  pcre_uchar ket;
6124  assert_backtrack *assert;  assert_backtrack *assert;
6125  BOOL has_alternatives;  BOOL has_alternatives;
6126    BOOL needs_control_head = FALSE;
6127  struct sljit_jump *jump;  struct sljit_jump *jump;
6128  struct sljit_jump *skip;  struct sljit_jump *skip;
6129  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 6014  else if (opcode == OP_ONCE || opcode == Line 6199  else if (opcode == OP_ONCE || opcode ==
6199    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6200    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6201    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6202      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);
6203    }    }
6204    
6205  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6206  stacksize = 0;  stacksize = 0;
6207  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6208    stacksize++;    stacksize++;
6209  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6210    stacksize++;    stacksize++;
# Line 6028  if (stacksize > 0) Line 6213  if (stacksize > 0)
6213    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6214    
6215  stacksize = 0;  stacksize = 0;
6216  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6217    {    {
6218    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6219    stacksize++;    stacksize++;
# Line 6091  if (ket == OP_KETRMAX) Line 6276  if (ket == OP_KETRMAX)
6276  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6277  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6278    {    {
6279      stacksize = 0;
6280      if (needs_control_head)
6281        {
6282        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6283        stacksize++;
6284        }
6285    
6286    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6287      {      {
6288      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6289      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6290        {        {
6291        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6292        allocate_stack(common, 2);        if (!needs_control_head)
6293        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));  
6294        }        }
6295      else if (ket == OP_KETRMAX || has_alternatives)      else
6296        {        {
6297        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6298        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6299        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6300            stacksize++;
6301        }        }
6302      else  
6303        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6304          allocate_stack(common, stacksize);
6305    
6306        stacksize = 0;
6307        if (needs_control_head)
6308          {
6309          stacksize++;
6310          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6311          }
6312    
6313        if (ket == OP_KETRMIN)
6314          {
6315          if (needs_control_head)
6316            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6317          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6318          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6319            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));
6320          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6321          }
6322        else if (ket == OP_KETRMAX || has_alternatives)
6323          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6324      }      }
6325    else    else
6326      {      {
6327      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6328          stacksize++;
6329    
6330        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6331        allocate_stack(common, stacksize);
6332    
6333        if (needs_control_head)
6334          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6335    
6336        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6337        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6338    
6339        stacksize = needs_control_head ? 1 : 0;
6340        if (ket != OP_KET || has_alternatives)
6341        {        {
6342        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);  
6343        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);
6344        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6345        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6346        }        }
6347      else      else
6348        {        {
       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));  
6349        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);
6350        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);  
6351        }        }
6352        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6353      }      }
6354    }    }
6355  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6267  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6485  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6485    return NULL;    return NULL;
6486    
6487  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6488    {    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));  
       }  
     }  
   }  
6489    
6490  stacksize = 0;  stacksize = 0;
6491  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6319  if (ket != OP_KET || bra != OP_BRA) Line 6514  if (ket != OP_KET || bra != OP_BRA)
6514    }    }
6515    
6516  if (offset != 0)  if (offset != 0)
6517    {    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;  
     }  
   }  
6518    
6519  if (has_alternatives)  if (has_alternatives)
6520    {    {
# Line 6409  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6585  if ((ket != OP_KET && bra != OP_BRAMINZE
6585  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6586    cc += GET(cc, 1);    cc += GET(cc, 1);
6587  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6588    
6589    /* Temporarily encoding the needs_control_head in framesize. */
6590    if (opcode == OP_ONCE)
6591      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6592  return cc;  return cc;
6593  }  }
6594    
# Line 6419  backtrack_common *backtrack; Line 6599  backtrack_common *backtrack;
6599  pcre_uchar opcode;  pcre_uchar opcode;
6600  int private_data_ptr;  int private_data_ptr;
6601  int cbraprivptr = 0;  int cbraprivptr = 0;
6602    BOOL needs_control_head;
6603  int framesize;  int framesize;
6604  int stacksize;  int stacksize;
6605  int offset = 0;  int offset = 0;
6606  BOOL zero = FALSE;  BOOL zero = FALSE;
6607  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6608  int stack;  int stack; /* Also contains the offset of control head. */
6609  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6610  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6611    
# Line 6462  switch(opcode) Line 6643  switch(opcode)
6643    break;    break;
6644    }    }
6645    
6646  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6647  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6648  if (framesize < 0)  if (framesize < 0)
6649    {    {
# Line 6475  if (framesize < 0) Line 6656  if (framesize < 0)
6656    else    else
6657      stacksize = 1;      stacksize = 1;
6658    
6659      if (needs_control_head)
6660        stacksize++;
6661    if (!zero)    if (!zero)
6662      stacksize++;      stacksize++;
6663    
# Line 6483  if (framesize < 0) Line 6666  if (framesize < 0)
6666    if (framesize == no_frame)    if (framesize == no_frame)
6667      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);
6668    
6669      stack = 0;
6670    if (offset != 0)    if (offset != 0)
6671      {      {
6672        stack = 2;
6673      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6674      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));
6675      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6676      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6677        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);
6678      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6679        if (needs_control_head)
6680          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6681      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6682          {
6683        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6684          stack = 3;
6685          }
6686      }      }
6687    else    else
6688        {
6689        if (needs_control_head)
6690          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6691      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6692        stack = 1;
6693        }
6694    
6695      if (needs_control_head)
6696        stack++;
6697    if (!zero)    if (!zero)
6698      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);
6699      if (needs_control_head)
6700        {
6701        stack--;
6702        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6703        }
6704    }    }
6705  else  else
6706    {    {
6707    stacksize = framesize + 1;    stacksize = framesize + 1;
6708    if (!zero)    if (!zero)
6709      stacksize++;      stacksize++;
6710    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6711        stacksize++;
6712      if (offset == 0)
6713      stacksize++;      stacksize++;
6714    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6715    
6716    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6717    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);
6718    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6719    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);
6720      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6721    
6722    stack = 0;    stack = 0;
6723    if (!zero)    if (!zero)
6724      {      {
6725      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6726        stack = 1;
6727        }
6728      if (needs_control_head)
6729        {
6730        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6731      stack++;      stack++;
6732      }      }
6733    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6734      {      {
6735      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6736      stack++;      stack++;
6737      }      }
6738    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6739    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6740      stack -= 1 + (offset == 0);
6741    }    }
6742    
6743  if (offset != 0)  if (offset != 0)
# Line 6602  while (*cc != OP_KETRPOS) Line 6813  while (*cc != OP_KETRPOS)
6813          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6814        }        }
6815      }      }
6816    
6817      if (needs_control_head)
6818        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6819    
6820    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6821    flush_stubs(common);    flush_stubs(common);
6822    
# Line 6638  while (*cc != OP_KETRPOS) Line 6853  while (*cc != OP_KETRPOS)
6853    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6854    }    }
6855    
6856    /* We don't have to restore the control head in case of a failed match. */
6857    
6858  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6859  if (!zero)  if (!zero)
6860    {    {
# Line 7026  if (!optimized_cbracket) Line 7243  if (!optimized_cbracket)
7243  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7244  }  }
7245    
7246    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7247    {
7248    DEFINE_COMPILER;
7249    backtrack_common *backtrack;
7250    pcre_uchar opcode = *cc;
7251    pcre_uchar *ccend = cc + 1;
7252    
7253    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7254      ccend += 2 + cc[1];
7255    
7256    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7257    
7258    if (opcode == OP_SKIP)
7259      {
7260      allocate_stack(common, 1);
7261      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7262      return ccend;
7263      }
7264    
7265    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7266      {
7267      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7268      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7269      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7270      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7271      }
7272    
7273    return ccend;
7274    }
7275    
7276    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7277    
7278    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7279    {
7280    DEFINE_COMPILER;
7281    backtrack_common *backtrack;
7282    BOOL needs_control_head;
7283    int size;
7284    
7285    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7286    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7287    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7288    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7289    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7290    
7291    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7292    size = 3 + (size < 0 ? 0 : size);
7293    
7294    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7295    allocate_stack(common, size);
7296    if (size > 3)
7297      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7298    else
7299      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7300    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7301    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7302    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7303    
7304    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7305    if (size >= 0)
7306      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7307    }
7308    
7309  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)
7310  {  {
7311  DEFINE_COMPILER;  DEFINE_COMPILER;
7312  backtrack_common *backtrack;  backtrack_common *backtrack;
7313    BOOL has_then_trap = FALSE;
7314    then_trap_backtrack *save_then_trap = NULL;
7315    
7316    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7317    
7318    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7319      {
7320      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7321      has_then_trap = TRUE;
7322      save_then_trap = common->then_trap;
7323      /* Tail item on backtrack. */
7324      compile_then_trap_matchingpath(common, cc, ccend, parent);
7325      }
7326    
7327  while (cc < ccend)  while (cc < ccend)
7328    {    {
# Line 7246  while (cc < ccend) Line 7539  while (cc < ccend)
7539      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7540      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7541      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);
7542      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7543      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7544      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);
7545      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7546      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);
7547      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);
7548        if (common->has_skip_arg)
7549          {
7550          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7551          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7552          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7553          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7554          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7555          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7556          }
7557      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7558      break;      break;
7559    
     case OP_PRUNE_ARG:  
     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);  
     /* Fall through. */  
   
7560      case OP_PRUNE:      case OP_PRUNE:
7561      case OP_COMMIT:      case OP_PRUNE_ARG:
     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);  
     SLJIT_ASSERT(common->control_head_ptr != 0);  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);  
     allocate_stack(common, 2);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
     cc += (*cc == OP_PRUNE_ARG) ? (1 + 2 + cc[1]) : 1;  
     break;  
   
7562      case OP_SKIP:      case OP_SKIP:
7563      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      case OP_SKIP_ARG:
7564      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);      case OP_THEN:
7565      allocate_stack(common, 3);      case OP_THEN_ARG:
7566      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);      case OP_COMMIT:
7567      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_skip);      cc = compile_control_verb_matchingpath(common, cc, parent);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
     cc += 1;  
7568      break;      break;
7569    
7570      case OP_FAIL:      case OP_FAIL:
# Line 7306  while (cc < ccend) Line 7588  while (cc < ccend)
7588    if (cc == NULL)    if (cc == NULL)
7589      return;      return;
7590    }    }
7591    
7592    if (has_then_trap)
7593      {
7594      /* Head item on backtrack. */
7595      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7596      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7597      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7598      common->then_trap = save_then_trap;
7599      }
7600  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7601  }  }
7602    
# Line 7467  switch(opcode) Line 7758  switch(opcode)
7758    }    }
7759  }  }
7760    
7761  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)
7762  {  {
7763  DEFINE_COMPILER;  DEFINE_COMPILER;
7764  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7489  set_jumps(current->topbacktracks, LABEL( Line 7780  set_jumps(current->topbacktracks, LABEL(
7780  free_stack(common, 2);  free_stack(common, 2);
7781  }  }
7782    
7783  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)
7784  {  {
7785  DEFINE_COMPILER;  DEFINE_COMPILER;
7786    
# Line 7599  pcre_uchar bra = OP_BRA; Line 7890  pcre_uchar bra = OP_BRA;
7890  pcre_uchar ket;  pcre_uchar ket;
7891  assert_backtrack *assert;  assert_backtrack *assert;
7892  BOOL has_alternatives;  BOOL has_alternatives;
7893    BOOL needs_control_head = FALSE;
7894  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7895  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7896  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7624  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7916  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7916  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7917    opcode = OP_ONCE;    opcode = OP_ONCE;
7918    
7919    /* Decoding the needs_control_head in framesize. */
7920    if (opcode == OP_ONCE)
7921      {
7922      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7923      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7924      }
7925    
7926  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7927    {    {
7928    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7781  if (has_alternatives) Line 8080  if (has_alternatives)
8080      current->top = NULL;      current->top = NULL;
8081      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8082      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8083        /* Conditional blocks always have an additional alternative, even if it is empty. */
8084      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8085        {        {
8086        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8087        cc += GET(cc, 1);        cc += GET(cc, 1);
8088        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8089          {          {
8090          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8091            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8092              if (private_data_ptr != 0)
8093                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8094              else
8095                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8096              }
8097          else          else
8098            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));
8099          }          }
8100        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8101        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7800  if (has_alternatives) Line 8105  if (has_alternatives)
8105      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8106      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8107      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8108        {        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));  
           }  
         }  
       }  
8109    
8110      stacksize = 0;      stacksize = 0;
8111      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7837  if (has_alternatives) Line 8120  if (has_alternatives)
8120      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8121        stacksize++;        stacksize++;
8122    
8123      if (stacksize > 0) {      if (stacksize > 0)
8124          {
8125        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8126          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
8127        else        else
# Line 7846  if (has_alternatives) Line 8130  if (has_alternatives)
8130          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
8131          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));
8132          }          }
8133      }        }
8134    
8135      stacksize = 0;      stacksize = 0;
8136      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7859  if (has_alternatives) Line 8143  if (has_alternatives)
8143        }        }
8144    
8145      if (offset != 0)      if (offset != 0)
8146        {        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;  
         }  
       }  
8147    
8148      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8149        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 7951  else if (opcode == OP_SBRA || opcode == Line 8216  else if (opcode == OP_SBRA || opcode ==
8216  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8217    {    {
8218    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8219      stacksize = needs_control_head ? 1 : 0;
8220    
8221    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8222      {      {
8223      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8224      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);  
8225      }      }
8226    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8227      {      {
8228      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8229      free_stack(common, 1);      stacksize++;
8230      }      }
8231      free_stack(common, stacksize);
8232    
8233    JUMPHERE(once);    JUMPHERE(once);
8234    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 8013  else if (bra == OP_BRAZERO) Line 8280  else if (bra == OP_BRAZERO)
8280    }    }
8281  }  }
8282    
8283  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)
8284  {  {
8285  DEFINE_COMPILER;  DEFINE_COMPILER;
8286  int offset;  int offset;
# Line 8052  if (current->topbacktracks) Line 8319  if (current->topbacktracks)
8319  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));
8320  }  }
8321    
8322  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)
8323  {  {
8324  assert_backtrack backtrack;  assert_backtrack backtrack;
8325    
# Line 8076  else Line 8343  else
8343  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8344  }  }
8345    
8346    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8347    {
8348    DEFINE_COMPILER;
8349    pcre_uchar opcode = *current->cc;
8350    
8351    if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8352      {
8353      SLJIT_ASSERT(common->control_head_ptr != 0);
8354      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8355      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8356      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, common->then_trap->start);
8357      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_then_trap));
8358      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8359    
8360      OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);
8361      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8362      if (common->quit_label == NULL)
8363        add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
8364      else
8365        CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->quit_label);
8366    
8367      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
8368      add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8369      return;
8370      }
8371    
8372    if (common->local_exit)
8373      {
8374      if (common->quit_label == NULL)
8375        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8376      else
8377        JUMPTO(SLJIT_JUMP, common->quit_label);
8378      return;
8379      }
8380    
8381    if (opcode == OP_SKIP_ARG)
8382      {
8383      SLJIT_ASSERT(common->control_head_ptr != 0);
8384      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8385      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8386      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8387      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8388      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8389    
8390      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8391      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8392      return;
8393      }
8394    
8395    if (opcode == OP_SKIP)
8396      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8397    else
8398      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8399    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8400    }
8401    
8402    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8403    {
8404    DEFINE_COMPILER;
8405    struct sljit_jump *jump;
8406    int size;
8407    
8408    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8409      {
8410      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8411      return;
8412      }
8413    
8414    size = CURRENT_AS(then_trap_backtrack)->framesize;
8415    size = 3 + (size < 0 ? 0 : size);
8416    
8417    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8418    free_stack(common, size);
8419    jump = JUMP(SLJIT_JUMP);
8420    
8421    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8422    /* STACK_TOP is set by THEN. */
8423    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8424      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8425    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8426    free_stack(common, 3);
8427    
8428    JUMPHERE(jump);
8429    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8430    }
8431    
8432  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8433  {  {
8434  DEFINE_COMPILER;  DEFINE_COMPILER;
8435    then_trap_backtrack *save_then_trap = common->then_trap;
8436    
8437  while (current)  while (current)
8438    {    {
# Line 8212  while (current) Line 8566  while (current)
8566      break;      break;
8567    
8568      case OP_MARK:      case OP_MARK:
8569      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));
8570      free_stack(common, 1);      if (common->has_skip_arg)
8571          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8572        free_stack(common, common->has_skip_arg ? 5 : 1);
8573      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);
8574        if (common->has_skip_arg)
8575          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8576      break;      break;
8577    
8578        case OP_THEN:
8579        case OP_THEN_ARG:
8580      case OP_PRUNE:      case OP_PRUNE:
8581      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8582      case OP_SKIP:      case OP_SKIP:
8583      if (!common->local_exit)      case OP_SKIP_ARG:
8584        {      compile_control_verb_backtrackingpath(common, current);
       SLJIT_ASSERT(common->control_head_ptr != 0);  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);  
       sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));  
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
   
       OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);  
       add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));  
   
       OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  
       }  
   
     /* Commit or in recurse or accept. */  
     if (common->quit_label == NULL)  
       add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));  
     else  
       JUMPTO(SLJIT_JUMP, common->quit_label);  
8585      break;      break;
8586    
8587      case OP_COMMIT:      case OP_COMMIT:
# Line 8257  while (current) Line 8600  while (current)
8600      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8601      break;      break;
8602    
8603        case OP_THEN_TRAP:
8604        /* A virtual opcode for then traps. */
8605        compile_then_trap_backtrackingpath(common, current);
8606        break;
8607    
8608      default:      default:
8609      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8610      break;      break;
8611      }      }
8612    current = current->prev;    current = current->prev;
8613    }    }
8614    common->then_trap = save_then_trap;
8615  }  }
8616    
8617  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8271  DEFINE_COMPILER; Line 8620  DEFINE_COMPILER;
8620  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8621  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);
8622  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8623  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8624  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8625    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8626  int alternativesize;  int alternativesize;
8627  BOOL needs_frame;  BOOL needs_frame;
8628  backtrack_common altbacktrack;  backtrack_common altbacktrack;
8629  struct sljit_jump *jump;  struct sljit_jump *jump;
8630    
8631    /* Recurse captures then. */
8632    common->then_trap = NULL;
8633    
8634  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);
8635  needs_frame = framesize >= 0;  needs_frame = framesize >= 0;
8636  if (!needs_frame)  if (!needs_frame)
# Line 8291  set_jumps(common->currententry->calls, c Line 8644  set_jumps(common->currententry->calls, c
8644  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8645  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8646  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);
8647  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);
8648  if (common->control_head_ptr != 0)  if (needs_control_head)
8649    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8650  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);
8651  if (needs_frame)  if (needs_frame)
8652    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8653    
8654  if (alternativesize > 0)  if (alternativesize > 0)
8655    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 8366  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); Line 8719  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8719  JUMPHERE(jump);  JUMPHERE(jump);
8720  if (common->quit != NULL)  if (common->quit != NULL)
8721    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
8722  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8723  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8724  if (common->control_head_ptr != 0)  if (needs_control_head)
8725    {    {
8726    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8727    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
# Line 8560  if (private_data_size > SLJIT_MAX_LOCAL_ Line 8913  if (private_data_size > SLJIT_MAX_LOCAL_
8913    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8914    return;    return;
8915    }    }
8916    
8917  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
8918  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
8919    {    {
# Line 8569  if (!common->private_data_ptrs) Line 8923  if (!common->private_data_ptrs)
8923  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8924  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);
8925    
8926    if (common->has_then)
8927      {
8928      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
8929      if (!common->then_offsets)
8930        {
8931        SLJIT_FREE(common->optimized_cbracket);
8932        SLJIT_FREE(common->private_data_ptrs);
8933        return;
8934        }
8935      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
8936      set_then_offsets(common, rootbacktrack.cc, NULL);
8937      }
8938    
8939  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
8940  if (!compiler)  if (!compiler)
8941    {    {
8942    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8943    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
8944      if (common->has_then)
8945        SLJIT_FREE(common->then_offsets);
8946    return;    return;
8947    }    }
8948  common->compiler = compiler;  common->compiler = compiler;
# Line 8665  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9034  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9034    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9035    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9036    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9037      if (common->has_then)
9038        SLJIT_FREE(common->then_offsets);
9039    return;    return;
9040    }    }
9041    
# Line 8700  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9071  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9071    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9072    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9073    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9074      if (common->has_then)
9075        SLJIT_FREE(common->then_offsets);
9076    return;    return;
9077    }    }
9078    
# Line 8767  while (common->currententry != NULL) Line 9140  while (common->currententry != NULL)
9140      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9141      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9142      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9143        if (common->has_then)
9144          SLJIT_FREE(common->then_offsets);
9145      return;      return;
9146      }      }
9147    flush_stubs(common);    flush_stubs(common);
# Line 8875  if (common->getucd != NULL) Line 9250  if (common->getucd != NULL)
9250    
9251  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9252  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9253    if (common->has_then)
9254      SLJIT_FREE(common->then_offsets);
9255    
9256  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9257  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9258  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

Legend:
Removed from v.1275  
changed lines
  Added in v.1290

  ViewVC Help
Powered by ViewVC 1.1.5