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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 1275 by zherczeg, Sun Mar 10 05:32:10 2013 UTC revision 1277 by zherczeg, Mon Mar 11 09:50:29 2013 UTC
# Line 227  typedef struct backtrack_common { Line 227  typedef struct backtrack_common {
227  typedef struct assert_backtrack {  typedef struct assert_backtrack {
228    backtrack_common common;    backtrack_common common;
229    jump_list *condfailed;    jump_list *condfailed;
230    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
231    int framesize;    int framesize;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int private_data_ptr;    int private_data_ptr;
# Line 248  typedef struct bracket_backtrack { Line 248  typedef struct bracket_backtrack {
248      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
249      jump_list *condfailed;      jump_list *condfailed;
250      assert_backtrack *assert;      assert_backtrack *assert;
251      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
252      int framesize;      int framesize;
253    } u;    } u;
254    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 513  return cc; Line 513  return cc;
513   set_private_data_ptrs   set_private_data_ptrs
514   get_framesize   get_framesize
515   init_frame   init_frame
516   get_private_data_length_for_copy   get_private_data_copy_length
517   copy_private_data   copy_private_data
518   compile_matchingpath   compile_matchingpath
519   compile_backtrackingpath   compile_backtrackingpath
# Line 1148  while (cc < ccend) Line 1148  while (cc < ccend)
1148  }  }
1149    
1150  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1151  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive, BOOL* needs_control_head)
1152  {  {
1153  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1154  int length = 0;  int length = 0;
# Line 1159  BOOL setmark_found = recursive; Line 1159  BOOL setmark_found = recursive;
1159  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1160  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1161    
1162    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1163    SLJIT_ASSERT(common->control_head_ptr != 0);
1164    *needs_control_head = TRUE;
1165    #else
1166    *needs_control_head = FALSE;
1167    #endif
1168    
1169  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1170    {    {
1171    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
# Line 1191  while (cc < ccend) Line 1198  while (cc < ccend)
1198        length += 2;        length += 2;
1199        setmark_found = TRUE;        setmark_found = TRUE;
1200        }        }
1201        if (common->control_head_ptr != 0)
1202          *needs_control_head = TRUE;
1203      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1204      break;      break;
1205    
# Line 1228  while (cc < ccend) Line 1237  while (cc < ccend)
1237      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1238      break;      break;
1239    
1240        case OP_PRUNE:
1241        case OP_SKIP:
1242        case OP_COMMIT:
1243        if (common->control_head_ptr != 0)
1244          *needs_control_head = TRUE;
1245        /* Fall through. */
1246    
1247      default:      default:
1248      stack_restore = TRUE;      stack_restore = TRUE;
1249      /* Fall through. */      /* Fall through. */
# Line 1427  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1443  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1443  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1444  }  }
1445    
1446  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)
1447  {  {
1448  int private_data_length = common->control_head_ptr ? 3 : 2;  int private_data_length = needs_control_head ? 3 : 2;
1449  int size;  int size;
1450  pcre_uchar *alternative;  pcre_uchar *alternative;
1451  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1542  return private_data_length; Line 1558  return private_data_length;
1558  }  }
1559    
1560  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,
1561    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1562  {  {
1563  DEFINE_COMPILER;  DEFINE_COMPILER;
1564  int srcw[2];  int srcw[2];
# Line 1563  stacktop = STACK(stacktop - 1); Line 1579  stacktop = STACK(stacktop - 1);
1579    
1580  if (!save)  if (!save)
1581    {    {
1582    stackptr += (common->control_head_ptr ? 2 : 1) * sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1583    if (stackptr < stacktop)    if (stackptr < stacktop)
1584      {      {
1585      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1588  do Line 1604  do
1604      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1605      count = 1;      count = 1;
1606      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1607      if (common->control_head_ptr != 0)      if (needs_control_head)
1608        {        {
1609          SLJIT_ASSERT(common->control_head_ptr != 0);
1610        count = 2;        count = 2;
1611        srcw[1] = common->control_head_ptr;        srcw[1] = common->control_head_ptr;
1612        }        }
# Line 2005  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT Line 2022  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT
2022  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));
2023  }  }
2024    
2025  static sljit_sw do_check_control_chain(sljit_sw *current)  static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2026  {  {
2027  sljit_sw return_value = 0;  sljit_sw return_value = 0;
2028    
# Line 2106  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 2123  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2123  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));
2124    
2125  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);
2126  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);
2127  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2128  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);
2129  #endif  #endif
# Line 5244  recurse_entry *entry = common->entries; Line 5261  recurse_entry *entry = common->entries;
5261  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5262  int start = GET(cc, 1);  int start = GET(cc, 1);
5263  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5264    BOOL needs_control_head;
5265    
5266  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5267    
5268  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5269  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, TRUE, &needs_control_head) == no_stack)
5270    {    {
5271    start_cc = common->start + start;    start_cc = common->start + start;
5272    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 5426  static pcre_uchar *compile_assert_matchi
5426  DEFINE_COMPILER;  DEFINE_COMPILER;
5427  int framesize;  int framesize;
5428  int extrasize;  int extrasize;
5429  BOOL needs_control_head = common->control_head_ptr != 0;  BOOL needs_control_head;
5430  int private_data_ptr;  int private_data_ptr;
5431  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5432  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5434  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5452  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5452    }    }
5453  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5454  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5455  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE, &needs_control_head);
5456  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5457  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5458  opcode = *cc;  opcode = *cc;
# Line 5454  if (bra == OP_BRAMINZERO) Line 5472  if (bra == OP_BRAMINZERO)
5472  if (framesize < 0)  if (framesize < 0)
5473    {    {
5474    extrasize = needs_control_head ? 2 : 1;    extrasize = needs_control_head ? 2 : 1;
5475    if (framesize != no_stack)    if (framesize == no_frame)
5476      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);
5477    allocate_stack(common, extrasize);    allocate_stack(common, extrasize);
5478    if (needs_control_head)    if (needs_control_head)
# Line 5519  while (1) Line 5537  while (1)
5537    /* Reset stack. */    /* Reset stack. */
5538    if (framesize < 0)    if (framesize < 0)
5539      {      {
5540      if (framesize != no_stack)      if (framesize == no_frame)
5541        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);
5542      else      else
5543        free_stack(common, extrasize);        free_stack(common, extrasize);
# Line 5871  if (i < name_count) Line 5889  if (i < name_count)
5889  return condition;  return condition;
5890  }  }
5891    
5892    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)
5893    {
5894    DEFINE_COMPILER;
5895    int stacksize;
5896    
5897    if (framesize < 0)
5898      {
5899      if (framesize == no_frame)
5900        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5901      else
5902        {
5903        stacksize = needs_control_head ? 1 : 0;
5904        if (ket != OP_KET || has_alternatives)
5905          stacksize++;
5906        free_stack(common, stacksize);
5907        }
5908    
5909      if (needs_control_head)
5910        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
5911    
5912      /* TMP2 which is set here used by OP_KETRMAX below. */
5913      if (ket == OP_KETRMAX)
5914        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5915      else if (ket == OP_KETRMIN)
5916        {
5917        /* Move the STR_PTR to the private_data_ptr. */
5918        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5919        }
5920      }
5921    else
5922      {
5923      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
5924      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
5925      if (needs_control_head)
5926        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
5927    
5928      if (ket == OP_KETRMAX)
5929        {
5930        /* TMP2 which is set here used by OP_KETRMAX below. */
5931        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5932        }
5933      }
5934    if (needs_control_head)
5935      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
5936    }
5937    
5938    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
5939    {
5940    DEFINE_COMPILER;
5941    
5942    if (common->capture_last_ptr != 0)
5943      {
5944      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5945      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
5946      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
5947      stacksize++;
5948      }
5949    if (common->optimized_cbracket[offset >> 1] == 0)
5950      {
5951      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5952      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5953      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
5954      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5955      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
5956      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5957      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5958      stacksize += 2;
5959      }
5960    return stacksize;
5961    }
5962    
5963  /*  /*
5964    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
5965    
# Line 5939  pcre_uchar bra = OP_BRA; Line 6028  pcre_uchar bra = OP_BRA;
6028  pcre_uchar ket;  pcre_uchar ket;
6029  assert_backtrack *assert;  assert_backtrack *assert;
6030  BOOL has_alternatives;  BOOL has_alternatives;
6031    BOOL needs_control_head = FALSE;
6032  struct sljit_jump *jump;  struct sljit_jump *jump;
6033  struct sljit_jump *skip;  struct sljit_jump *skip;
6034  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 6014  else if (opcode == OP_ONCE || opcode == Line 6104  else if (opcode == OP_ONCE || opcode ==
6104    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6105    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6106    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6107      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE, &needs_control_head);
6108    }    }
6109    
6110  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6111  stacksize = 0;  stacksize = 0;
6112  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6113    stacksize++;    stacksize++;
6114  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6115    stacksize++;    stacksize++;
# Line 6028  if (stacksize > 0) Line 6118  if (stacksize > 0)
6118    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6119    
6120  stacksize = 0;  stacksize = 0;
6121  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6122    {    {
6123    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6124    stacksize++;    stacksize++;
# Line 6091  if (ket == OP_KETRMAX) Line 6181  if (ket == OP_KETRMAX)
6181  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6182  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6183    {    {
6184      stacksize = 0;
6185      if (needs_control_head)
6186        {
6187        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6188        stacksize++;
6189        }
6190    
6191    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6192      {      {
6193      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6194      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6195        {        {
6196        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6197        allocate_stack(common, 2);        if (!needs_control_head)
6198        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));  
6199        }        }
6200      else if (ket == OP_KETRMAX || has_alternatives)      else
6201        {        {
6202        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6203        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6204        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6205            stacksize++;
6206        }        }
6207      else  
6208        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6209          allocate_stack(common, stacksize);
6210    
6211        stacksize = 0;
6212        if (needs_control_head)
6213          {
6214          stacksize++;
6215          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6216          }
6217    
6218        if (ket == OP_KETRMIN)
6219          {
6220          if (needs_control_head)
6221            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6222          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6223          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6224            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));
6225          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6226          }
6227        else if (ket == OP_KETRMAX || has_alternatives)
6228          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6229      }      }
6230    else    else
6231      {      {
6232      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6233          stacksize++;
6234    
6235        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6236        allocate_stack(common, stacksize);
6237    
6238        if (needs_control_head)
6239          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6240    
6241        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6242        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6243    
6244        stacksize = needs_control_head ? 1 : 0;
6245        if (ket != OP_KET || has_alternatives)
6246        {        {
6247        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);  
6248        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);
6249        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6250        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6251        }        }
6252      else      else
6253        {        {
       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));  
6254        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);
6255        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);  
6256        }        }
6257        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6258      }      }
6259    }    }
6260  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 6390  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6390    return NULL;    return NULL;
6391    
6392  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6393    {    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));  
       }  
     }  
   }  
6394    
6395  stacksize = 0;  stacksize = 0;
6396  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6319  if (ket != OP_KET || bra != OP_BRA) Line 6419  if (ket != OP_KET || bra != OP_BRA)
6419    }    }
6420    
6421  if (offset != 0)  if (offset != 0)
6422    {    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;  
     }  
   }  
6423    
6424  if (has_alternatives)  if (has_alternatives)
6425    {    {
# Line 6409  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6490  if ((ket != OP_KET && bra != OP_BRAMINZE
6490  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6491    cc += GET(cc, 1);    cc += GET(cc, 1);
6492  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6493    
6494    /* Temporarily encoding the needs_control_head in framesize. */
6495    if (opcode == OP_ONCE)
6496      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6497  return cc;  return cc;
6498  }  }
6499    
# Line 6419  backtrack_common *backtrack; Line 6504  backtrack_common *backtrack;
6504  pcre_uchar opcode;  pcre_uchar opcode;
6505  int private_data_ptr;  int private_data_ptr;
6506  int cbraprivptr = 0;  int cbraprivptr = 0;
6507    BOOL needs_control_head;
6508  int framesize;  int framesize;
6509  int stacksize;  int stacksize;
6510  int offset = 0;  int offset = 0;
6511  BOOL zero = FALSE;  BOOL zero = FALSE;
6512  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6513  int stack;  int stack; /* Also contains the offset of control head. */
6514  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6515  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6516    
# Line 6462  switch(opcode) Line 6548  switch(opcode)
6548    break;    break;
6549    }    }
6550    
6551  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE, &needs_control_head);
6552  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6553  if (framesize < 0)  if (framesize < 0)
6554    {    {
# Line 6475  if (framesize < 0) Line 6561  if (framesize < 0)
6561    else    else
6562      stacksize = 1;      stacksize = 1;
6563    
6564      if (needs_control_head)
6565        stacksize++;
6566    if (!zero)    if (!zero)
6567      stacksize++;      stacksize++;
6568    
# Line 6483  if (framesize < 0) Line 6571  if (framesize < 0)
6571    if (framesize == no_frame)    if (framesize == no_frame)
6572      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);
6573    
6574      stack = 0;
6575    if (offset != 0)    if (offset != 0)
6576      {      {
6577        stack = 2;
6578      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6579      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));
6580      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6581      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6582        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);
6583      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6584        if (needs_control_head)
6585          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6586      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6587          {
6588        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6589          stack = 3;
6590          }
6591      }      }
6592    else    else
6593        {
6594        if (needs_control_head)
6595          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6596      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6597        stack = 1;
6598        }
6599    
6600      if (needs_control_head)
6601        stack++;
6602    if (!zero)    if (!zero)
6603      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);
6604      if (needs_control_head)
6605        {
6606        stack--;
6607        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6608        }
6609    }    }
6610  else  else
6611    {    {
6612    stacksize = framesize + 1;    stacksize = framesize + 1;
6613    if (!zero)    if (!zero)
6614      stacksize++;      stacksize++;
6615    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6616        stacksize++;
6617      if (offset == 0)
6618      stacksize++;      stacksize++;
6619    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6620    
6621    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6622    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);
6623    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6624    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);
6625      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6626    
6627    stack = 0;    stack = 0;
6628    if (!zero)    if (!zero)
6629      {      {
6630      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6631        stack = 1;
6632        }
6633      if (needs_control_head)
6634        {
6635        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6636      stack++;      stack++;
6637      }      }
6638    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6639      {      {
6640      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6641      stack++;      stack++;
6642      }      }
6643    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6644    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
6645      stack -= 1 + (offset == 0);
6646    }    }
6647    
6648  if (offset != 0)  if (offset != 0)
# Line 6602  while (*cc != OP_KETRPOS) Line 6718  while (*cc != OP_KETRPOS)
6718          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6719        }        }
6720      }      }
6721    
6722      if (needs_control_head)
6723        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6724    
6725    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6726    flush_stubs(common);    flush_stubs(common);
6727    
# Line 6638  while (*cc != OP_KETRPOS) Line 6758  while (*cc != OP_KETRPOS)
6758    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6759    }    }
6760    
6761    /* We don't have to restore the control head in case of a failed match. */
6762    
6763  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6764  if (!zero)  if (!zero)
6765    {    {
# Line 7599  pcre_uchar bra = OP_BRA; Line 7721  pcre_uchar bra = OP_BRA;
7721  pcre_uchar ket;  pcre_uchar ket;
7722  assert_backtrack *assert;  assert_backtrack *assert;
7723  BOOL has_alternatives;  BOOL has_alternatives;
7724    BOOL needs_control_head = FALSE;
7725  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7726  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7727  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7624  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7747  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7747  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7748    opcode = OP_ONCE;    opcode = OP_ONCE;
7749    
7750    /* Decoding the needs_control_head in framesize. */
7751    if (opcode == OP_ONCE)
7752      {
7753      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7754      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7755      }
7756    
7757  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7758    {    {
7759    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7781  if (has_alternatives) Line 7911  if (has_alternatives)
7911      current->top = NULL;      current->top = NULL;
7912      current->topbacktracks = NULL;      current->topbacktracks = NULL;
7913      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
7914        /* Conditional blocks always have an additional alternative, even if it is empty. */
7915      if (*cc == OP_ALT)      if (*cc == OP_ALT)
7916        {        {
7917        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
7918        cc += GET(cc, 1);        cc += GET(cc, 1);
7919        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7920          {          {
7921          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
7922            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
7923              if (private_data_ptr != 0)
7924                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7925              else
7926                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7927              }
7928          else          else
7929            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));
7930          }          }
7931        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7932        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7800  if (has_alternatives) Line 7936  if (has_alternatives)
7936      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7937      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
7938      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7939        {        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));  
           }  
         }  
       }  
7940    
7941      stacksize = 0;      stacksize = 0;
7942      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7837  if (has_alternatives) Line 7951  if (has_alternatives)
7951      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7952        stacksize++;        stacksize++;
7953    
7954      if (stacksize > 0) {      if (stacksize > 0)
7955          {
7956        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7957          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
7958        else        else
# Line 7846  if (has_alternatives) Line 7961  if (has_alternatives)
7961          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
7962          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));
7963          }          }
7964      }        }
7965    
7966      stacksize = 0;      stacksize = 0;
7967      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7859  if (has_alternatives) Line 7974  if (has_alternatives)
7974        }        }
7975    
7976      if (offset != 0)      if (offset != 0)
7977        {        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;  
         }  
       }  
7978    
7979      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7980        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 8047  else if (opcode == OP_SBRA || opcode ==
8047  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8048    {    {
8049    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8050      stacksize = needs_control_head ? 1 : 0;
8051    
8052    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8053      {      {
8054      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8055      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);  
8056      }      }
8057    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8058      {      {
8059      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8060      free_stack(common, 1);      stacksize++;
8061      }      }
8062      free_stack(common, stacksize);
8063    
8064    JUMPHERE(once);    JUMPHERE(once);
8065    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 8225  while (current) Line 8323  while (current)
8323        SLJIT_ASSERT(common->control_head_ptr != 0);        SLJIT_ASSERT(common->control_head_ptr != 0);
8324        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8325        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8326        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));        sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8327        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8328    
8329        OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);        OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
# Line 8271  DEFINE_COMPILER; Line 8369  DEFINE_COMPILER;
8369  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8370  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);
8371  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8372  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8373  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE, &needs_control_head);
8374    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8375  int alternativesize;  int alternativesize;
8376  BOOL needs_frame;  BOOL needs_frame;
8377  backtrack_common altbacktrack;  backtrack_common altbacktrack;
# Line 8291  set_jumps(common->currententry->calls, c Line 8390  set_jumps(common->currententry->calls, c
8390  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8391  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8392  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);
8393  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);
8394  if (common->control_head_ptr != 0)  if (needs_control_head)
8395    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);
8396  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);
8397  if (needs_frame)  if (needs_frame)
# Line 8366  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); Line 8465  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8465  JUMPHERE(jump);  JUMPHERE(jump);
8466  if (common->quit != NULL)  if (common->quit != NULL)
8467    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
8468  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);
8469  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8470  if (common->control_head_ptr != 0)  if (needs_control_head)
8471    {    {
8472    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));
8473    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));

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

  ViewVC Help
Powered by ViewVC 1.1.5