/[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 1276 by zherczeg, Sun Mar 10 17:35:23 2013 UTC revision 1277 by zherczeg, Mon Mar 11 09:50:29 2013 UTC
# 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 5245  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 5409  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 5435  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 5872  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 5940  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 6015  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 6029  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 6092  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 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, (BACKTRACK_AS(bracket_backtrack)->u.framesize + 2) * sizeof(sljit_sw));  
       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, (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));  
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 6268  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 6320  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 6410  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 6420  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 = common->control_head_ptr != 0;  BOOL needs_control_head;
6508  int framesize;  int framesize;
6509  int stacksize;  int stacksize;
6510  int offset = 0;  int offset = 0;
# Line 6464  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 7637  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 7662  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 7819  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 7838  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 7875  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 7884  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 7897  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 7989  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 8309  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  BOOL needs_control_head = common->control_head_ptr != 0;  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);  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;

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

  ViewVC Help
Powered by ViewVC 1.1.5