/[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 1303 by zherczeg, Fri Mar 29 09:01:20 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 negative assert. */
360    BOOL local_exit;    BOOL local_exit;
361      /* Currently in a positive assert. */
362      BOOL positive_assert;
363    /* Newline control. */    /* Newline control. */
364    int nltype;    int nltype;
365    int newline;    int newline;
# Line 360  typedef struct compiler_common { Line 384  typedef struct compiler_common {
384    recurse_entry *currententry;    recurse_entry *currententry;
385    jump_list *partialmatch;    jump_list *partialmatch;
386    jump_list *quit;    jump_list *quit;
387      jump_list *positive_assert_quit;
388    jump_list *forced_quit;    jump_list *forced_quit;
389    jump_list *accept;    jump_list *accept;
390    jump_list *calllimit;    jump_list *calllimit;
# Line 513  return cc; Line 538  return cc;
538   set_private_data_ptrs   set_private_data_ptrs
539   get_framesize   get_framesize
540   init_frame   init_frame
541   get_private_data_length_for_copy   get_private_data_copy_length
542   copy_private_data   copy_private_data
543   compile_matchingpath   compile_matchingpath
544   compile_backtrackingpath   compile_backtrackingpath
# Line 597  switch(*cc) Line 622  switch(*cc)
622    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
623    case OP_PRUNE:    case OP_PRUNE:
624    case OP_SKIP:    case OP_SKIP:
625      case OP_THEN:
626    case OP_COMMIT:    case OP_COMMIT:
627    case OP_FAIL:    case OP_FAIL:
628    case OP_ACCEPT:    case OP_ACCEPT:
# Line 696  switch(*cc) Line 722  switch(*cc)
722    
723    case OP_MARK:    case OP_MARK:
724    case OP_PRUNE_ARG:    case OP_PRUNE_ARG:
725      case OP_SKIP_ARG:
726      case OP_THEN_ARG:
727    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
728    
729    default:    default:
730      /* All opcodes are supported now! */
731      SLJIT_ASSERT_STOP();
732    return NULL;    return NULL;
733    }    }
734  }  }
# Line 947  while (cc < ccend) Line 977  while (cc < ccend)
977      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
978      break;      break;
979    
980        case OP_THEN_ARG:
981        common->has_then = TRUE;
982        common->control_head_ptr = 1;
983        /* Fall through. */
984    
985      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
986      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
     common->control_head_ptr = 1;  
987      /* Fall through. */      /* Fall through. */
988    
989      case OP_MARK:      case OP_MARK:
# Line 961  while (cc < ccend) Line 995  while (cc < ccend)
995      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
996      break;      break;
997    
998        case OP_THEN:
999        common->has_then = TRUE;
1000        common->control_head_ptr = 1;
1001        /* Fall through. */
1002    
1003      case OP_PRUNE:      case OP_PRUNE:
1004      case OP_SKIP:      case OP_SKIP:
1005      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
1006      /* Fall through. */      cc += 1;
1007        break;
1008    
1009      case OP_COMMIT:      case OP_SKIP_ARG:
1010      common->control_head_ptr = 1;      common->control_head_ptr = 1;
1011      cc += 1;      common->has_skip_arg = TRUE;
1012        cc += 1 + 2 + cc[1];
1013      break;      break;
1014    
1015      default:      default:
# Line 1148  while (cc < ccend) Line 1189  while (cc < ccend)
1189  }  }
1190    
1191  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1192  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)
1193  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1194  int length = 0;  int length = 0;
1195  int possessive = 0;  int possessive = 0;
1196  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1159  BOOL setmark_found = recursive; Line 1199  BOOL setmark_found = recursive;
1199  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1200  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1201    
1202  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1203    SLJIT_ASSERT(common->control_head_ptr != 0);
1204    *needs_control_head = TRUE;
1205    #else
1206    *needs_control_head = FALSE;
1207    #endif
1208    
1209    if (ccend == NULL)
1210    {    {
1211    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1212    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1213    capture_last_found = TRUE;      {
1214        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1215        /* This is correct regardless of common->capture_last_ptr. */
1216        capture_last_found = TRUE;
1217        }
1218      cc = next_opcode(common, cc);
1219    }    }
1220    
 cc = next_opcode(common, cc);  
1221  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1222  while (cc < ccend)  while (cc < ccend)
1223    switch(*cc)    switch(*cc)
# Line 1184  while (cc < ccend) Line 1235  while (cc < ccend)
1235    
1236      case OP_MARK:      case OP_MARK:
1237      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1238        case OP_THEN_ARG:
1239      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1240      stack_restore = TRUE;      stack_restore = TRUE;
1241      if (!setmark_found)      if (!setmark_found)
# Line 1191  while (cc < ccend) Line 1243  while (cc < ccend)
1243        length += 2;        length += 2;
1244        setmark_found = TRUE;        setmark_found = TRUE;
1245        }        }
1246        if (common->control_head_ptr != 0)
1247          *needs_control_head = TRUE;
1248      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1249      break;      break;
1250    
# Line 1310  if (length > 0) Line 1364  if (length > 0)
1364  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1365  }  }
1366    
1367  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)
1368  {  {
1369  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1370  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1371  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1372  /* 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 1378  SLJIT_UNUSED_ARG(stacktop);
1378  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1379    
1380  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1381  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1382    cc = next_opcode(common, cc);    {
1383      ccend = bracketend(cc) - (1 + LINK_SIZE);
1384      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1385        cc = next_opcode(common, cc);
1386      }
1387    
1388  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1389  while (cc < ccend)  while (cc < ccend)
1390    switch(*cc)    switch(*cc)
# Line 1347  while (cc < ccend) Line 1405  while (cc < ccend)
1405    
1406      case OP_MARK:      case OP_MARK:
1407      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1408        case OP_THEN_ARG:
1409      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1410      if (!setmark_found)      if (!setmark_found)
1411        {        {
# Line 1427  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1486  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1486  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1487  }  }
1488    
1489  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)
1490  {  {
1491  int private_data_length = common->control_head_ptr ? 3 : 2;  int private_data_length = needs_control_head ? 3 : 2;
1492  int size;  int size;
1493  pcre_uchar *alternative;  pcre_uchar *alternative;
1494  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1542  return private_data_length; Line 1601  return private_data_length;
1601  }  }
1602    
1603  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,
1604    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1605  {  {
1606  DEFINE_COMPILER;  DEFINE_COMPILER;
1607  int srcw[2];  int srcw[2];
# Line 1563  stacktop = STACK(stacktop - 1); Line 1622  stacktop = STACK(stacktop - 1);
1622    
1623  if (!save)  if (!save)
1624    {    {
1625    stackptr += (common->control_head_ptr ? 2 : 1) * sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1626    if (stackptr < stacktop)    if (stackptr < stacktop)
1627      {      {
1628      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1588  do Line 1647  do
1647      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1648      count = 1;      count = 1;
1649      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1650      if (common->control_head_ptr != 0)      if (needs_control_head)
1651        {        {
1652          SLJIT_ASSERT(common->control_head_ptr != 0);
1653        count = 2;        count = 2;
1654        srcw[1] = common->control_head_ptr;        srcw[1] = common->control_head_ptr;
1655        }        }
# Line 1851  if (save) Line 1911  if (save)
1911  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1912  }  }
1913    
1914    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1915    {
1916    pcre_uchar *end = bracketend(cc);
1917    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1918    
1919    /* Assert captures then. */
1920    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1921      current_offset = NULL;
1922    /* Conditional block does not. */
1923    if (*cc == OP_COND || *cc == OP_SCOND)
1924      has_alternatives = FALSE;
1925    
1926    cc = next_opcode(common, cc);
1927    if (has_alternatives)
1928      current_offset = common->then_offsets + (cc - common->start);
1929    
1930    while (cc < end)
1931      {
1932      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1933        cc = set_then_offsets(common, cc, current_offset);
1934      else
1935        {
1936        if (*cc == OP_ALT && has_alternatives)
1937          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1938        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1939          *current_offset = 1;
1940        cc = next_opcode(common, cc);
1941        }
1942      }
1943    
1944    return end;
1945    }
1946    
1947  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1948  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1949  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1998  else Line 2091  else
2091  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2092  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2093    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);
2094  SLJIT_ASSERT(common->control_head_ptr != 0);  if (common->control_head_ptr != 0)
2095  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);
2096  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));
2097  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);
2098  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));
2099  }  }
2100    
2101  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)
2102  {  {
2103  sljit_sw return_value = 0;  while (current != NULL)
   
 SLJIT_ASSERT(current != NULL);  
 do  
2104    {    {
2105    switch (current[-2])    switch (current[-2])
2106      {      {
2107      case type_commit:      case type_then_trap:
     /* Commit overwrites all. */  
     return -1;  
   
     case type_prune:  
2108      break;      break;
2109    
2110      case type_skip:      case type_mark:
2111      /* Overwrites prune, but not other skips. */      if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2112      if (return_value == 0)        return current[-4];
       return_value = current[-3];  
2113      break;      break;
2114    
2115      default:      default:
# Line 2033  do Line 2118  do
2118      }      }
2119    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
2120    }    }
2121  while (current != NULL);  return -1;
 return return_value;  
2122  }  }
2123    
2124  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 2190  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2190  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));
2191    
2192  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);
2193  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);
2194  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2195  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);
2196  #endif  #endif
# Line 5242  DEFINE_COMPILER; Line 5326  DEFINE_COMPILER;
5326  backtrack_common *backtrack;  backtrack_common *backtrack;
5327  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5328  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5329  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5330  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5331    BOOL needs_control_head;
5332    
5333  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5334    
5335  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5336  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5337    {    {
5338    start_cc = common->start + start;    start_cc = common->start + start;
5339    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 5493  static pcre_uchar *compile_assert_matchi
5493  DEFINE_COMPILER;  DEFINE_COMPILER;
5494  int framesize;  int framesize;
5495  int extrasize;  int extrasize;
5496  BOOL needs_control_head = common->control_head_ptr != 0;  BOOL needs_control_head;
5497  int private_data_ptr;  int private_data_ptr;
5498  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5499  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5418  jump_list *tmp = NULL; Line 5503  jump_list *tmp = NULL;
5503  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5504  jump_list **found;  jump_list **found;
5505  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5506    BOOL save_local_exit = common->local_exit;
5507    BOOL save_positive_assert = common->positive_assert;
5508    then_trap_backtrack *save_then_trap = common->then_trap;
5509  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5510  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5511  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5512    jump_list *save_positive_assert_quit = common->positive_assert_quit;
5513  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
 BOOL save_local_exit = common->local_exit;  
5514  struct sljit_jump *jump;  struct sljit_jump *jump;
5515  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5516    
5517    /* Assert captures then. */
5518    common->then_trap = NULL;
5519    
5520  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5521    {    {
5522    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5434  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5525  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5525    }    }
5526  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5527  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5528  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5529  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5530  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5531  opcode = *cc;  opcode = *cc;
# Line 5454  if (bra == OP_BRAMINZERO) Line 5545  if (bra == OP_BRAMINZERO)
5545  if (framesize < 0)  if (framesize < 0)
5546    {    {
5547    extrasize = needs_control_head ? 2 : 1;    extrasize = needs_control_head ? 2 : 1;
5548    if (framesize != no_stack)    if (framesize == no_frame)
5549      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);
5550    allocate_stack(common, extrasize);    allocate_stack(common, extrasize);
5551    if (needs_control_head)    if (needs_control_head)
# Line 5484  else Line 5575  else
5575      }      }
5576    else    else
5577      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5578    init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5579    }    }
5580    
5581  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5582  common->local_exit = TRUE;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5583  common->quit_label = NULL;    {
5584  common->quit = NULL;    /* Negative assert is stronger than positive assert. */
5585      common->local_exit = TRUE;
5586      common->quit_label = NULL;
5587      common->quit = NULL;
5588      common->positive_assert = FALSE;
5589      }
5590    else
5591      common->positive_assert = TRUE;
5592    common->positive_assert_quit = NULL;
5593    
5594  while (1)  while (1)
5595    {    {
5596    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5505  while (1) Line 5605  while (1)
5605    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5606    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5607      {      {
5608      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5609      common->quit_label = save_quit_label;        {
5610          common->local_exit = save_local_exit;
5611          common->quit_label = save_quit_label;
5612          common->quit = save_quit;
5613          }
5614        common->positive_assert = save_positive_assert;
5615        common->then_trap = save_then_trap;
5616      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5617      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5618      common->accept = save_accept;      common->accept = save_accept;
5619      return NULL;      return NULL;
5620      }      }
# Line 5519  while (1) Line 5625  while (1)
5625    /* Reset stack. */    /* Reset stack. */
5626    if (framesize < 0)    if (framesize < 0)
5627      {      {
5628      if (framesize != no_stack)      if (framesize == no_frame)
5629        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);
5630      else      else
5631        free_stack(common, extrasize);        free_stack(common, extrasize);
# Line 5573  while (1) Line 5679  while (1)
5679    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5680    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5681      {      {
5682      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5683      common->quit_label = save_quit_label;        {
5684          common->local_exit = save_local_exit;
5685          common->quit_label = save_quit_label;
5686          common->quit = save_quit;
5687          }
5688        common->positive_assert = save_positive_assert;
5689        common->then_trap = save_then_trap;
5690      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5691      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5692      common->accept = save_accept;      common->accept = save_accept;
5693      return NULL;      return NULL;
5694      }      }
# Line 5589  while (1) Line 5701  while (1)
5701    cc += GET(cc, 1);    cc += GET(cc, 1);
5702    }    }
5703    
5704    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5705      {
5706      SLJIT_ASSERT(common->positive_assert_quit == NULL);
5707      /* Makes the check less complicated below. */
5708      common->positive_assert_quit = common->quit;
5709      }
5710    
5711  /* None of them matched. */  /* None of them matched. */
5712  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
5713    {    {
5714    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5715    set_jumps(common->quit, LABEL());    set_jumps(common->positive_assert_quit, LABEL());
5716    SLJIT_ASSERT(framesize != no_stack);    SLJIT_ASSERT(framesize != no_stack);
5717    if (framesize < 0)    if (framesize < 0)
5718      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
# Line 5753  else Line 5872  else
5872      }      }
5873    }    }
5874    
5875  common->local_exit = save_local_exit;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5876  common->quit_label = save_quit_label;    {
5877      common->local_exit = save_local_exit;
5878      common->quit_label = save_quit_label;
5879      common->quit = save_quit;
5880      }
5881    common->positive_assert = save_positive_assert;
5882    common->then_trap = save_then_trap;
5883  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5884  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
5885  common->accept = save_accept;  common->accept = save_accept;
5886  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5887  }  }
# Line 5871  if (i < name_count) Line 5996  if (i < name_count)
5996  return condition;  return condition;
5997  }  }
5998    
5999    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)
6000    {
6001    DEFINE_COMPILER;
6002    int stacksize;
6003    
6004    if (framesize < 0)
6005      {
6006      if (framesize == no_frame)
6007        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6008      else
6009        {
6010        stacksize = needs_control_head ? 1 : 0;
6011        if (ket != OP_KET || has_alternatives)
6012          stacksize++;
6013        free_stack(common, stacksize);
6014        }
6015    
6016      if (needs_control_head)
6017        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6018    
6019      /* TMP2 which is set here used by OP_KETRMAX below. */
6020      if (ket == OP_KETRMAX)
6021        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6022      else if (ket == OP_KETRMIN)
6023        {
6024        /* Move the STR_PTR to the private_data_ptr. */
6025        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6026        }
6027      }
6028    else
6029      {
6030      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6031      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6032      if (needs_control_head)
6033        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6034    
6035      if (ket == OP_KETRMAX)
6036        {
6037        /* TMP2 which is set here used by OP_KETRMAX below. */
6038        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6039        }
6040      }
6041    if (needs_control_head)
6042      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6043    }
6044    
6045    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6046    {
6047    DEFINE_COMPILER;
6048    
6049    if (common->capture_last_ptr != 0)
6050      {
6051      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6052      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6053      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6054      stacksize++;
6055      }
6056    if (common->optimized_cbracket[offset >> 1] == 0)
6057      {
6058      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6059      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6060      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6061      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6062      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6063      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6064      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6065      stacksize += 2;
6066      }
6067    return stacksize;
6068    }
6069    
6070  /*  /*
6071    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6072    
# Line 5939  pcre_uchar bra = OP_BRA; Line 6135  pcre_uchar bra = OP_BRA;
6135  pcre_uchar ket;  pcre_uchar ket;
6136  assert_backtrack *assert;  assert_backtrack *assert;
6137  BOOL has_alternatives;  BOOL has_alternatives;
6138    BOOL needs_control_head = FALSE;
6139  struct sljit_jump *jump;  struct sljit_jump *jump;
6140  struct sljit_jump *skip;  struct sljit_jump *skip;
6141  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 6014  else if (opcode == OP_ONCE || opcode == Line 6211  else if (opcode == OP_ONCE || opcode ==
6211    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6212    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6213    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6214      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);
6215    }    }
6216    
6217  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6218  stacksize = 0;  stacksize = 0;
6219  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6220    stacksize++;    stacksize++;
6221  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6222    stacksize++;    stacksize++;
# Line 6028  if (stacksize > 0) Line 6225  if (stacksize > 0)
6225    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6226    
6227  stacksize = 0;  stacksize = 0;
6228  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6229    {    {
6230    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6231    stacksize++;    stacksize++;
# Line 6091  if (ket == OP_KETRMAX) Line 6288  if (ket == OP_KETRMAX)
6288  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6289  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6290    {    {
6291      stacksize = 0;
6292      if (needs_control_head)
6293        {
6294        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6295        stacksize++;
6296        }
6297    
6298    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6299      {      {
6300      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6301      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6302        {        {
6303        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6304        allocate_stack(common, 2);        if (!needs_control_head)
6305        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));  
6306        }        }
6307      else if (ket == OP_KETRMAX || has_alternatives)      else
6308        {        {
6309        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6310        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6311        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6312            stacksize++;
6313        }        }
6314      else  
6315        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6316          allocate_stack(common, stacksize);
6317    
6318        stacksize = 0;
6319        if (needs_control_head)
6320          {
6321          stacksize++;
6322          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6323          }
6324    
6325        if (ket == OP_KETRMIN)
6326          {
6327          if (needs_control_head)
6328            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6329          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6330          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6331            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));
6332          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6333          }
6334        else if (ket == OP_KETRMAX || has_alternatives)
6335          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6336      }      }
6337    else    else
6338      {      {
6339      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6340          stacksize++;
6341    
6342        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6343        allocate_stack(common, stacksize);
6344    
6345        if (needs_control_head)
6346          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6347    
6348        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6349        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6350    
6351        stacksize = needs_control_head ? 1 : 0;
6352        if (ket != OP_KET || has_alternatives)
6353        {        {
6354        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);  
6355        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);
6356        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6357        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6358        }        }
6359      else      else
6360        {        {
       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));  
6361        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);
6362        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);  
6363        }        }
6364        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6365      }      }
6366    }    }
6367  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 6497  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6497    return NULL;    return NULL;
6498    
6499  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6500    {    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));  
       }  
     }  
   }  
6501    
6502  stacksize = 0;  stacksize = 0;
6503  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6319  if (ket != OP_KET || bra != OP_BRA) Line 6526  if (ket != OP_KET || bra != OP_BRA)
6526    }    }
6527    
6528  if (offset != 0)  if (offset != 0)
6529    {    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;  
     }  
   }  
6530    
6531  if (has_alternatives)  if (has_alternatives)
6532    {    {
# Line 6409  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6597  if ((ket != OP_KET && bra != OP_BRAMINZE
6597  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6598    cc += GET(cc, 1);    cc += GET(cc, 1);
6599  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6600    
6601    /* Temporarily encoding the needs_control_head in framesize. */
6602    if (opcode == OP_ONCE)
6603      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6604  return cc;  return cc;
6605  }  }
6606    
# Line 6419  backtrack_common *backtrack; Line 6611  backtrack_common *backtrack;
6611  pcre_uchar opcode;  pcre_uchar opcode;
6612  int private_data_ptr;  int private_data_ptr;
6613  int cbraprivptr = 0;  int cbraprivptr = 0;
6614    BOOL needs_control_head;
6615  int framesize;  int framesize;
6616  int stacksize;  int stacksize;
6617  int offset = 0;  int offset = 0;
6618  BOOL zero = FALSE;  BOOL zero = FALSE;
6619  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6620  int stack;  int stack; /* Also contains the offset of control head. */
6621  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6622  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6623    
# Line 6462  switch(opcode) Line 6655  switch(opcode)
6655    break;    break;
6656    }    }
6657    
6658  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6659  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6660  if (framesize < 0)  if (framesize < 0)
6661    {    {
# Line 6475  if (framesize < 0) Line 6668  if (framesize < 0)
6668    else    else
6669      stacksize = 1;      stacksize = 1;
6670    
6671      if (needs_control_head)
6672        stacksize++;
6673    if (!zero)    if (!zero)
6674      stacksize++;      stacksize++;
6675    
# Line 6483  if (framesize < 0) Line 6678  if (framesize < 0)
6678    if (framesize == no_frame)    if (framesize == no_frame)
6679      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);
6680    
6681      stack = 0;
6682    if (offset != 0)    if (offset != 0)
6683      {      {
6684        stack = 2;
6685      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6686      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));
6687      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6688      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6689        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);
6690      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6691        if (needs_control_head)
6692          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6693      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6694          {
6695        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6696          stack = 3;
6697          }
6698      }      }
6699    else    else
6700        {
6701        if (needs_control_head)
6702          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6703      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6704        stack = 1;
6705        }
6706    
6707      if (needs_control_head)
6708        stack++;
6709    if (!zero)    if (!zero)
6710      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);
6711      if (needs_control_head)
6712        {
6713        stack--;
6714        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6715        }
6716    }    }
6717  else  else
6718    {    {
6719    stacksize = framesize + 1;    stacksize = framesize + 1;
6720    if (!zero)    if (!zero)
6721      stacksize++;      stacksize++;
6722    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6723        stacksize++;
6724      if (offset == 0)
6725      stacksize++;      stacksize++;
6726    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6727    
6728    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6729    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);
6730    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6731    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);
6732      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6733    
6734    stack = 0;    stack = 0;
6735    if (!zero)    if (!zero)
6736      {      {
6737      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6738        stack = 1;
6739        }
6740      if (needs_control_head)
6741        {
6742        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6743      stack++;      stack++;
6744      }      }
6745    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6746      {      {
6747      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6748      stack++;      stack++;
6749      }      }
6750    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6751    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6752      stack -= 1 + (offset == 0);
6753    }    }
6754    
6755  if (offset != 0)  if (offset != 0)
# Line 6602  while (*cc != OP_KETRPOS) Line 6825  while (*cc != OP_KETRPOS)
6825          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6826        }        }
6827      }      }
6828    
6829      if (needs_control_head)
6830        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6831    
6832    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6833    flush_stubs(common);    flush_stubs(common);
6834    
# Line 6638  while (*cc != OP_KETRPOS) Line 6865  while (*cc != OP_KETRPOS)
6865    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6866    }    }
6867    
6868    /* We don't have to restore the control head in case of a failed match. */
6869    
6870  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6871  if (!zero)  if (!zero)
6872    {    {
# Line 7026  if (!optimized_cbracket) Line 7255  if (!optimized_cbracket)
7255  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7256  }  }
7257    
7258    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7259    {
7260    DEFINE_COMPILER;
7261    backtrack_common *backtrack;
7262    pcre_uchar opcode = *cc;
7263    pcre_uchar *ccend = cc + 1;
7264    
7265    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7266      ccend += 2 + cc[1];
7267    
7268    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7269    
7270    if (opcode == OP_SKIP)
7271      {
7272      allocate_stack(common, 1);
7273      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7274      return ccend;
7275      }
7276    
7277    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7278      {
7279      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7280      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7281      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7282      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7283      }
7284    
7285    return ccend;
7286    }
7287    
7288    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7289    
7290    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7291    {
7292    DEFINE_COMPILER;
7293    backtrack_common *backtrack;
7294    BOOL needs_control_head;
7295    int size;
7296    
7297    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7298    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7299    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7300    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7301    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7302    
7303    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7304    size = 3 + (size < 0 ? 0 : size);
7305    
7306    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7307    allocate_stack(common, size);
7308    if (size > 3)
7309      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7310    else
7311      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7312    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7313    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7314    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7315    
7316    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7317    if (size >= 0)
7318      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7319    }
7320    
7321  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)
7322  {  {
7323  DEFINE_COMPILER;  DEFINE_COMPILER;
7324  backtrack_common *backtrack;  backtrack_common *backtrack;
7325    BOOL has_then_trap = FALSE;
7326    then_trap_backtrack *save_then_trap = NULL;
7327    
7328    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7329    
7330    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7331      {
7332      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7333      has_then_trap = TRUE;
7334      save_then_trap = common->then_trap;
7335      /* Tail item on backtrack. */
7336      compile_then_trap_matchingpath(common, cc, ccend, parent);
7337      }
7338    
7339  while (cc < ccend)  while (cc < ccend)
7340    {    {
# Line 7246  while (cc < ccend) Line 7551  while (cc < ccend)
7551      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7552      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7553      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);
7554      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7555      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7556      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);
7557      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7558      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);
7559      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);
7560        if (common->has_skip_arg)
7561          {
7562          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7563          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7564          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7565          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7566          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7567          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7568          }
7569      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7570      break;      break;
7571    
     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. */  
   
7572      case OP_PRUNE:      case OP_PRUNE:
7573      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;  
   
7574      case OP_SKIP:      case OP_SKIP:
7575      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      case OP_SKIP_ARG:
7576      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);      case OP_THEN:
7577      allocate_stack(common, 3);      case OP_THEN_ARG:
7578      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);      case OP_COMMIT:
7579      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;  
7580      break;      break;
7581    
7582      case OP_FAIL:      case OP_FAIL:
# Line 7306  while (cc < ccend) Line 7600  while (cc < ccend)
7600    if (cc == NULL)    if (cc == NULL)
7601      return;      return;
7602    }    }
7603    
7604    if (has_then_trap)
7605      {
7606      /* Head item on backtrack. */
7607      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7608      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7609      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7610      common->then_trap = save_then_trap;
7611      }
7612  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7613  }  }
7614    
# Line 7467  switch(opcode) Line 7770  switch(opcode)
7770    }    }
7771  }  }
7772    
7773  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)
7774  {  {
7775  DEFINE_COMPILER;  DEFINE_COMPILER;
7776  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7489  set_jumps(current->topbacktracks, LABEL( Line 7792  set_jumps(current->topbacktracks, LABEL(
7792  free_stack(common, 2);  free_stack(common, 2);
7793  }  }
7794    
7795  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)
7796  {  {
7797  DEFINE_COMPILER;  DEFINE_COMPILER;
7798    
# Line 7599  pcre_uchar bra = OP_BRA; Line 7902  pcre_uchar bra = OP_BRA;
7902  pcre_uchar ket;  pcre_uchar ket;
7903  assert_backtrack *assert;  assert_backtrack *assert;
7904  BOOL has_alternatives;  BOOL has_alternatives;
7905    BOOL needs_control_head = FALSE;
7906  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7907  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7908  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7624  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7928  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7928  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7929    opcode = OP_ONCE;    opcode = OP_ONCE;
7930    
7931    /* Decoding the needs_control_head in framesize. */
7932    if (opcode == OP_ONCE)
7933      {
7934      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7935      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7936      }
7937    
7938  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7939    {    {
7940    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7781  if (has_alternatives) Line 8092  if (has_alternatives)
8092      current->top = NULL;      current->top = NULL;
8093      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8094      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8095        /* Conditional blocks always have an additional alternative, even if it is empty. */
8096      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8097        {        {
8098        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8099        cc += GET(cc, 1);        cc += GET(cc, 1);
8100        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8101          {          {
8102          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8103            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8104              if (private_data_ptr != 0)
8105                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8106              else
8107                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8108              }
8109          else          else
8110            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));
8111          }          }
8112        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8113        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7800  if (has_alternatives) Line 8117  if (has_alternatives)
8117      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8118      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8119      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8120        {        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));  
           }  
         }  
       }  
8121    
8122      stacksize = 0;      stacksize = 0;
8123      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7837  if (has_alternatives) Line 8132  if (has_alternatives)
8132      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8133        stacksize++;        stacksize++;
8134    
8135      if (stacksize > 0) {      if (stacksize > 0)
8136          {
8137        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8138          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
8139        else        else
# Line 7846  if (has_alternatives) Line 8142  if (has_alternatives)
8142          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
8143          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));
8144          }          }
8145      }        }
8146    
8147      stacksize = 0;      stacksize = 0;
8148      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7859  if (has_alternatives) Line 8155  if (has_alternatives)
8155        }        }
8156    
8157      if (offset != 0)      if (offset != 0)
8158        {        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;  
         }  
       }  
8159    
8160      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8161        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 8228  else if (opcode == OP_SBRA || opcode ==
8228  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8229    {    {
8230    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8231      stacksize = needs_control_head ? 1 : 0;
8232    
8233    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8234      {      {
8235      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8236      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);  
8237      }      }
8238    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8239      {      {
8240      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8241      free_stack(common, 1);      stacksize++;
8242      }      }
8243      free_stack(common, stacksize);
8244    
8245    JUMPHERE(once);    JUMPHERE(once);
8246    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 8013  else if (bra == OP_BRAZERO) Line 8292  else if (bra == OP_BRAZERO)
8292    }    }
8293  }  }
8294    
8295  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)
8296  {  {
8297  DEFINE_COMPILER;  DEFINE_COMPILER;
8298  int offset;  int offset;
# Line 8052  if (current->topbacktracks) Line 8331  if (current->topbacktracks)
8331  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));
8332  }  }
8333    
8334  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)
8335  {  {
8336  assert_backtrack backtrack;  assert_backtrack backtrack;
8337    
# Line 8076  else Line 8355  else
8355  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8356  }  }
8357    
8358    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8359    {
8360    DEFINE_COMPILER;
8361    pcre_uchar opcode = *current->cc;
8362    struct sljit_label *loop;
8363    struct sljit_jump *jump;
8364    
8365    if (opcode == OP_THEN || opcode == OP_THEN_ARG)
8366      {
8367      if (common->then_trap != NULL)
8368        {
8369        SLJIT_ASSERT(common->control_head_ptr != 0);
8370    
8371        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8372        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8373        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8374        jump = JUMP(SLJIT_JUMP);
8375    
8376        loop = LABEL();
8377        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8378        JUMPHERE(jump);
8379        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8380        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8381        add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8382        return;
8383        }
8384      else if (common->positive_assert)
8385        {
8386        add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
8387        return;
8388        }
8389      }
8390    
8391    if (common->local_exit)
8392      {
8393      if (common->quit_label == NULL)
8394        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8395      else
8396        JUMPTO(SLJIT_JUMP, common->quit_label);
8397      return;
8398      }
8399    
8400    if (opcode == OP_SKIP_ARG)
8401      {
8402      SLJIT_ASSERT(common->control_head_ptr != 0);
8403      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8404      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8405      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8406      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8407      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8408    
8409      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8410      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8411      return;
8412      }
8413    
8414    if (opcode == OP_SKIP)
8415      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8416    else
8417      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8418    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8419    }
8420    
8421    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8422    {
8423    DEFINE_COMPILER;
8424    struct sljit_jump *jump;
8425    int size;
8426    
8427    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8428      {
8429      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8430      return;
8431      }
8432    
8433    size = CURRENT_AS(then_trap_backtrack)->framesize;
8434    size = 3 + (size < 0 ? 0 : size);
8435    
8436    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8437    free_stack(common, size);
8438    jump = JUMP(SLJIT_JUMP);
8439    
8440    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8441    /* STACK_TOP is set by THEN. */
8442    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8443      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8444    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8445    free_stack(common, 3);
8446    
8447    JUMPHERE(jump);
8448    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8449    }
8450    
8451  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8452  {  {
8453  DEFINE_COMPILER;  DEFINE_COMPILER;
8454    then_trap_backtrack *save_then_trap = common->then_trap;
8455    
8456  while (current)  while (current)
8457    {    {
# Line 8212  while (current) Line 8585  while (current)
8585      break;      break;
8586    
8587      case OP_MARK:      case OP_MARK:
8588      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));
8589      free_stack(common, 1);      if (common->has_skip_arg)
8590          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8591        free_stack(common, common->has_skip_arg ? 5 : 1);
8592      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);
8593        if (common->has_skip_arg)
8594          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8595      break;      break;
8596    
8597        case OP_THEN:
8598        case OP_THEN_ARG:
8599      case OP_PRUNE:      case OP_PRUNE:
8600      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8601      case OP_SKIP:      case OP_SKIP:
8602      if (!common->local_exit)      case OP_SKIP_ARG:
8603        {      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);  
8604      break;      break;
8605    
8606      case OP_COMMIT:      case OP_COMMIT:
# Line 8257  while (current) Line 8619  while (current)
8619      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8620      break;      break;
8621    
8622        case OP_THEN_TRAP:
8623        /* A virtual opcode for then traps. */
8624        compile_then_trap_backtrackingpath(common, current);
8625        break;
8626    
8627      default:      default:
8628      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8629      break;      break;
8630      }      }
8631    current = current->prev;    current = current->prev;
8632    }    }
8633    common->then_trap = save_then_trap;
8634  }  }
8635    
8636  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8271  DEFINE_COMPILER; Line 8639  DEFINE_COMPILER;
8639  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8640  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);
8641  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8642  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8643  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8644    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8645  int alternativesize;  int alternativesize;
8646  BOOL needs_frame;  BOOL needs_frame;
8647  backtrack_common altbacktrack;  backtrack_common altbacktrack;
8648  struct sljit_jump *jump;  struct sljit_jump *jump;
8649    
8650    /* Recurse captures then. */
8651    common->then_trap = NULL;
8652    
8653  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);
8654  needs_frame = framesize >= 0;  needs_frame = framesize >= 0;
8655  if (!needs_frame)  if (!needs_frame)
# Line 8291  set_jumps(common->currententry->calls, c Line 8663  set_jumps(common->currententry->calls, c
8663  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8664  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8665  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);
8666  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);
8667  if (common->control_head_ptr != 0)  if (needs_control_head)
8668    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);
8669  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);
8670  if (needs_frame)  if (needs_frame)
8671    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8672    
8673  if (alternativesize > 0)  if (alternativesize > 0)
8674    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 8738  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8738  JUMPHERE(jump);  JUMPHERE(jump);
8739  if (common->quit != NULL)  if (common->quit != NULL)
8740    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
8741  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);
8742  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8743  if (common->control_head_ptr != 0)  if (needs_control_head)
8744    {    {
8745    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));
8746    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 8932  if (private_data_size > SLJIT_MAX_LOCAL_
8932    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8933    return;    return;
8934    }    }
8935    
8936  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
8937  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
8938    {    {
# Line 8569  if (!common->private_data_ptrs) Line 8942  if (!common->private_data_ptrs)
8942  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8943  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);
8944    
8945    if (common->has_then)
8946      {
8947      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
8948      if (!common->then_offsets)
8949        {
8950        SLJIT_FREE(common->optimized_cbracket);
8951        SLJIT_FREE(common->private_data_ptrs);
8952        return;
8953        }
8954      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
8955      set_then_offsets(common, rootbacktrack.cc, NULL);
8956      }
8957    
8958  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
8959  if (!compiler)  if (!compiler)
8960    {    {
8961    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8962    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
8963      if (common->has_then)
8964        SLJIT_FREE(common->then_offsets);
8965    return;    return;
8966    }    }
8967  common->compiler = compiler;  common->compiler = compiler;
# Line 8665  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9053  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9053    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9054    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9055    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9056      if (common->has_then)
9057        SLJIT_FREE(common->then_offsets);
9058    return;    return;
9059    }    }
9060    
# Line 8700  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9090  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9090    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9091    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9092    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9093      if (common->has_then)
9094        SLJIT_FREE(common->then_offsets);
9095    return;    return;
9096    }    }
9097    
# Line 8767  while (common->currententry != NULL) Line 9159  while (common->currententry != NULL)
9159      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9160      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9161      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9162        if (common->has_then)
9163          SLJIT_FREE(common->then_offsets);
9164      return;      return;
9165      }      }
9166    flush_stubs(common);    flush_stubs(common);
# Line 8875  if (common->getucd != NULL) Line 9269  if (common->getucd != NULL)
9269    
9270  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9271  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9272    if (common->has_then)
9273      SLJIT_FREE(common->then_offsets);
9274    
9275  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9276  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9277  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

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

  ViewVC Help
Powered by ViewVC 1.1.5