Diff for /embedaddon/pcre/pcre_jit_compile.c between versions 1.1.1.4 and 1.1.1.5

version 1.1.1.4, 2013/07/22 08:25:55 version 1.1.1.5, 2014/06/15 19:46:03
Line 371  typedef struct compiler_common { Line 371  typedef struct compiler_common {
   sljit_sw ctypes;    sljit_sw ctypes;
   int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
   /* Named capturing brackets. */    /* Named capturing brackets. */
  sljit_uw name_table;  pcre_uchar *name_table;
   sljit_sw name_count;    sljit_sw name_count;
   sljit_sw name_entry_size;    sljit_sw name_entry_size;
   
Line 481  to characters. The vector data is divided into two gro Line 481  to characters. The vector data is divided into two gro
 group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
 the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
 #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
#define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))#define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
#define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))#define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
 #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
   
 #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
Line 585  switch(*cc) Line 585  switch(*cc)
   case OP_CRMINQUERY:    case OP_CRMINQUERY:
   case OP_CRRANGE:    case OP_CRRANGE:
   case OP_CRMINRANGE:    case OP_CRMINRANGE:
     case OP_CRPOSSTAR:
     case OP_CRPOSPLUS:
     case OP_CRPOSQUERY:
     case OP_CRPOSRANGE:
   case OP_CLASS:    case OP_CLASS:
   case OP_NCLASS:    case OP_NCLASS:
   case OP_REF:    case OP_REF:
   case OP_REFI:    case OP_REFI:
     case OP_DNREF:
     case OP_DNREFI:
   case OP_RECURSE:    case OP_RECURSE:
   case OP_CALLOUT:    case OP_CALLOUT:
   case OP_ALT:    case OP_ALT:
Line 614  switch(*cc) Line 620  switch(*cc)
   case OP_SCBRAPOS:    case OP_SCBRAPOS:
   case OP_SCOND:    case OP_SCOND:
   case OP_CREF:    case OP_CREF:
  case OP_NCREF:  case OP_DNCREF:
   case OP_RREF:    case OP_RREF:
  case OP_NRREF:  case OP_DNRREF:
   case OP_DEF:    case OP_DEF:
   case OP_BRAZERO:    case OP_BRAZERO:
   case OP_BRAMINZERO:    case OP_BRAMINZERO:
Line 736  switch(*cc) Line 742  switch(*cc)
   
 static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
 {  {
pcre_uchar *name;int count;
pcre_uchar *name2;pcre_uchar *slot;
unsigned int cbra_index; 
int i; 
   
 /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
 while (cc < ccend)  while (cc < ccend)
Line 773  while (cc < ccend) Line 777  while (cc < ccend)
     break;      break;
   
     case OP_CREF:      case OP_CREF:
    i = GET2(cc, 1);    common->optimized_cbracket[GET2(cc, 1)] = 0;
    common->optimized_cbracket[i] = 0; 
     cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
     break;      break;
   
    case OP_NCREF:    case OP_DNREF:
    cbra_index = GET2(cc, 1);    case OP_DNREFI:
    name = (pcre_uchar *)common->name_table;    case OP_DNCREF:
    name2 = name;    count = GET2(cc, 1 + IMM2_SIZE);
    for (i = 0; i < common->name_count; i++)    slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
     while (count-- > 0)
       {        {
      if (GET2(name, 0) == cbra_index) break;      common->optimized_cbracket[GET2(slot, 0)] = 0;
      name += common->name_entry_size;      slot += common->name_entry_size;
       }        }
    SLJIT_ASSERT(i != common->name_count);    cc += 1 + 2 * IMM2_SIZE;
 
    for (i = 0; i < common->name_count; i++) 
      { 
      if (STRCMP_UC_UC(name2 + IMM2_SIZE, name + IMM2_SIZE) == 0) 
        common->optimized_cbracket[GET2(name2, 0)] = 0; 
      name2 += common->name_entry_size; 
      } 
    cc += 1 + IMM2_SIZE; 
     break;      break;
   
     case OP_RECURSE:      case OP_RECURSE:
Line 4027  DEFINE_COMPILER; Line 4023  DEFINE_COMPILER;
 jump_list *found = NULL;  jump_list *found = NULL;
 jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
 pcre_int32 c, charoffset;  pcre_int32 c, charoffset;
 const pcre_uint32 *other_cases;  
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
 pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
 int compares, invertcmp, numberofcmps;  int compares, invertcmp, numberofcmps;
   
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
 BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
 BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
 int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
   const pcre_uint32 *other_cases;
 pcre_int32 typeoffset;  pcre_int32 typeoffset;
 #endif  #endif
   
Line 4130  while (*cc != XCL_END) Line 4127  while (*cc != XCL_END)
       case PT_SPACE:        case PT_SPACE:
       case PT_PXSPACE:        case PT_PXSPACE:
       case PT_WORD:        case PT_WORD:
         case PT_PXGRAPH:
         case PT_PXPRINT:
         case PT_PXPUNCT:
       needstype = TRUE;        needstype = TRUE;
       needschar = TRUE;        needschar = TRUE;
       break;        break;
Line 4317  while (*cc != XCL_END) Line 4317  while (*cc != XCL_END)
   
       case PT_SPACE:        case PT_SPACE:
       case PT_PXSPACE:        case PT_PXSPACE:
       if (*cc == PT_SPACE)  
         {  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
         jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);  
         }  
       SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
       if (*cc == PT_SPACE)  
         JUMPHERE(jump);  
   
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
         OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
   
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
         OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
   
       SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
Line 4418  while (*cc != XCL_END) Line 4417  while (*cc != XCL_END)
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
       jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
       break;        break;
   
         case PT_PXGRAPH:
         /* C and Z groups are the farthest two groups. */
         SET_TYPE_OFFSET(ucp_Ll);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
   
         jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
   
         /* In case of ucp_Cf, we overwrite the result. */
         SET_CHAR_OFFSET(0x2066);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
   
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
         OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
   
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
         OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
   
         JUMPHERE(jump);
         jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
         break;
   
         case PT_PXPRINT:
         /* C and Z groups are the farthest two groups. */
         SET_TYPE_OFFSET(ucp_Ll);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
   
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
         OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
   
         jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
   
         /* In case of ucp_Cf, we overwrite the result. */
         SET_CHAR_OFFSET(0x2066);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
   
         OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
         OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
   
         JUMPHERE(jump);
         jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
         break;
   
         case PT_PXPUNCT:
         SET_TYPE_OFFSET(ucp_Sc);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
         OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
   
         SET_CHAR_OFFSET(0);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
         OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
   
         SET_TYPE_OFFSET(ucp_Pc);
         OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
         OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
         jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
         break;
       }        }
     cc += 2;      cc += 2;
     }      }
Line 5056  if (context.length > 0) Line 5116  if (context.length > 0)
 return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
 }  }
   
 static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  
 {  
 DEFINE_COMPILER;  
 int offset = GET2(cc, 1) << 1;  
   
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
 if (!common->jscript_compat)  
   {  
   if (backtracks == NULL)  
     {  
     /* OVECTOR(1) contains the "string begin - 1" constant. */  
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  
     OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);  
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  
     return JUMP(SLJIT_C_NOT_ZERO);  
     }  
   add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));  
   }  
 return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
 }  
   
 /* Forward definitions. */  /* Forward definitions. */
 static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
 static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
Line 5110  static void compile_backtrackingpath(compiler_common * Line 5148  static void compile_backtrackingpath(compiler_common *
   
 #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
   
static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)static void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
 {  {
   /* The OVECTOR offset goes to TMP2. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
int offset = GET2(cc, 1) << 1;int count = GET2(cc, 1 + IMM2_SIZE);
 pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
 unsigned int offset;
 jump_list *found = NULL;
 
 SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
 
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
 
 count--;
 while (count-- > 0)
   {
   offset = GET2(slot, 0) << 1;
   GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
   add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
   slot += common->name_entry_size;
   }
 
 offset = GET2(slot, 0) << 1;
 GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
 if (backtracks != NULL && !common->jscript_compat)
   add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
 
 set_jumps(found, LABEL());
 }
 
 static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
 {
 DEFINE_COMPILER;
 BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
 int offset = 0;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
 struct sljit_jump *partial;  struct sljit_jump *partial;
 struct sljit_jump *nopartial;  struct sljit_jump *nopartial;
   
OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));if (ref)
/* OVECTOR(1) contains the "string begin - 1" constant. */  {
if (withchecks && !common->jscript_compat)  offset = GET2(cc, 1) << 1;
  add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
   /* OVECTOR(1) contains the "string begin - 1" constant. */
   if (withchecks && !common->jscript_compat)
     add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
   }
 else
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
   
 #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
   {    {
   SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);
  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  if (ref)
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
   else
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
 
   if (withchecks)    if (withchecks)
     jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
   
Line 5152  if (common->utf && *cc == OP_REFI) Line 5231  if (common->utf && *cc == OP_REFI)
 else  else
 #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
   {    {
  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);  if (ref)
     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
   else
     OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
 
   if (withchecks)    if (withchecks)
     jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
   
Line 5189  if (jump != NULL) Line 5272  if (jump != NULL)
   else    else
     JUMPHERE(jump);      JUMPHERE(jump);
   }    }
 return cc + 1 + IMM2_SIZE;  
 }  }
   
 static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
   BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
 backtrack_common *backtrack;  backtrack_common *backtrack;
 pcre_uchar type;  pcre_uchar type;
   int offset = 0;
 struct sljit_label *label;  struct sljit_label *label;
 struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
Line 5206  BOOL minimize; Line 5290  BOOL minimize;
   
 PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
   
   if (ref)
     offset = GET2(cc, 1) << 1;
   else
     cc += IMM2_SIZE;
 type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
   
   SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
 minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
 switch(type)  switch(type)
   {    {
Line 5244  if (!minimize) Line 5334  if (!minimize)
   if (min == 0)    if (min == 0)
     {      {
     allocate_stack(common, 2);      allocate_stack(common, 2);
       if (ref)
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
     /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
     OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
    zerolength = compile_ref_checks(common, ccbegin, NULL);    /* Handles both invalid and empty cases. Since the minimum repeat,
     is zero the invalid case is basically the same as an empty case. */
     if (ref)
       zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
     else
       {
       compile_dnref_search(common, ccbegin, NULL);
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
       zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
       }
     /* Restore if not zero length. */      /* Restore if not zero length. */
     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));
     }      }
   else    else
     {      {
     allocate_stack(common, 1);      allocate_stack(common, 1);
       if (ref)
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    if (ref)
       {
       add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
       zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
       }
     else
       {
       compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
       zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
       }
     }      }
   
   if (min > 1 || max > 1)    if (min > 1 || max > 1)
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
   
   label = LABEL();    label = LABEL();
     if (!ref)
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
   compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
   
   if (min > 1 || max > 1)    if (min > 1 || max > 1)
Line 5297  if (!minimize) Line 5414  if (!minimize)
   return cc;    return cc;
   }    }
   
allocate_stack(common, 2);allocate_stack(common, ref ? 2 : 3);
 if (ref)
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
 if (type != OP_CRMINSTAR)  if (type != OP_CRMINSTAR)
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
   
 if (min == 0)  if (min == 0)
   {    {
  zerolength = compile_ref_checks(common, ccbegin, NULL);  /* Handles both invalid and empty cases. Since the minimum repeat,
   is zero the invalid case is basically the same as an empty case. */
   if (ref)
     zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
   else
     {
     compile_dnref_search(common, ccbegin, NULL);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
     zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
     }
   /* Length is non-zero, we can match real repeats. */
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
   jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
   }    }
 else  else
  zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);  {
   if (ref)
     {
     add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
     zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
     }
   else
     {
     compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
     zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
     }
   }
   
 BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
 if (max > 0)  if (max > 0)
   add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
   
   if (!ref)
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
 compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
 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 5902  common->accept = save_accept; Line 6047  common->accept = save_accept;
 return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
 }  }
   
 static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table)  
 {  
 int condition = FALSE;  
 pcre_uchar *slotA = name_table;  
 pcre_uchar *slotB;  
 sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)];  
 sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];  
 sljit_sw no_capture;  
 int i;  
   
 locals += refno & 0xff;  
 refno >>= 8;  
 no_capture = locals[1];  
   
 for (i = 0; i < name_count; i++)  
   {  
   if (GET2(slotA, 0) == refno) break;  
   slotA += name_entry_size;  
   }  
   
 if (i < name_count)  
   {  
   /* Found a name for the number - there can be only one; duplicate names  
   for different numbers are allowed, but not vice versa. First scan down  
   for duplicates. */  
   
   slotB = slotA;  
   while (slotB > name_table)  
     {  
     slotB -= name_entry_size;  
     if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
       {  
       condition = locals[GET2(slotB, 0) << 1] != no_capture;  
       if (condition) break;  
       }  
     else break;  
     }  
   
   /* Scan up for duplicates */  
   if (!condition)  
     {  
     slotB = slotA;  
     for (i++; i < name_count; i++)  
       {  
       slotB += name_entry_size;  
       if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
         {  
         condition = locals[GET2(slotB, 0) << 1] != no_capture;  
         if (condition) break;  
         }  
       else break;  
       }  
     }  
   }  
 return condition;  
 }  
   
 static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table)  
 {  
 int condition = FALSE;  
 pcre_uchar *slotA = name_table;  
 pcre_uchar *slotB;  
 sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)];  
 sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];  
 sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)];  
 sljit_uw i;  
   
 for (i = 0; i < name_count; i++)  
   {  
   if (GET2(slotA, 0) == recno) break;  
   slotA += name_entry_size;  
   }  
   
 if (i < name_count)  
   {  
   /* Found a name for the number - there can be only one; duplicate  
   names for different numbers are allowed, but not vice versa. First  
   scan down for duplicates. */  
   
   slotB = slotA;  
   while (slotB > name_table)  
     {  
     slotB -= name_entry_size;  
     if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
       {  
       condition = GET2(slotB, 0) == group_num;  
       if (condition) break;  
       }  
     else break;  
     }  
   
   /* Scan up for duplicates */  
   if (!condition)  
     {  
     slotB = slotA;  
     for (i++; i < name_count; i++)  
       {  
       slotB += name_entry_size;  
       if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
         {  
         condition = GET2(slotB, 0) == group_num;  
         if (condition) break;  
         }  
       else break;  
       }  
     }  
   }  
 return condition;  
 }  
   
 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)  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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
Line 6144  backtrack_common *backtrack; Line 6179  backtrack_common *backtrack;
 pcre_uchar opcode;  pcre_uchar opcode;
 int private_data_ptr = 0;  int private_data_ptr = 0;
 int offset = 0;  int offset = 0;
int stacksize;int i, stacksize;
 int repeat_ptr = 0, repeat_length = 0;  int repeat_ptr = 0, repeat_length = 0;
 int repeat_type = 0, repeat_count = 0;  int repeat_type = 0, repeat_count = 0;
 pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
 pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
   pcre_uchar *slot;
 pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
 pcre_uchar ket;  pcre_uchar ket;
 assert_backtrack *assert;  assert_backtrack *assert;
Line 6198  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN Line 6234  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN
 cc += GET(cc, 1);  cc += GET(cc, 1);
   
 has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
  {  has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE;
  has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE; 
  if (*matchingpath == OP_NRREF) 
    { 
    stacksize = GET2(matchingpath, 1); 
    if (common->currententry == NULL || stacksize == RREF_ANY) 
      has_alternatives = FALSE; 
    else if (common->currententry->start == 0) 
      has_alternatives = stacksize != 0; 
    else 
      has_alternatives = stacksize != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); 
    } 
  } 
   
 if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
   opcode = OP_SCOND;    opcode = OP_SCOND;
Line 6448  if (opcode == OP_COND || opcode == OP_SCOND) Line 6472  if (opcode == OP_COND || opcode == OP_SCOND)
       CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
     matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
     }      }
  else if (*matchingpath == OP_NCREF)  else if (*matchingpath == OP_DNCREF)
     {      {
     SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
     stacksize = GET2(matchingpath, 1);  
     jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  
   
    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);    i = GET2(matchingpath, 1 + IMM2_SIZE);
    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);    slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);    slot += common->name_entry_size;
    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));    i--;
    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);    while (i-- > 0)
    add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));      {
      OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
    JUMPHERE(jump);      OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
    matchingpath += 1 + IMM2_SIZE;      slot += common->name_entry_size;
       }
     OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO));
     matchingpath += 1 + 2 * IMM2_SIZE;
     }      }
  else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)  else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
     {      {
     /* Never has other case. */      /* Never has other case. */
     BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
       SLJIT_ASSERT(!has_alternatives);
   
    stacksize = GET2(matchingpath, 1);    if (*matchingpath == OP_RREF)
    if (common->currententry == NULL) 
      stacksize = 0; 
    else if (stacksize == RREF_ANY) 
      stacksize = 1; 
    else if (common->currententry->start == 0) 
      stacksize = stacksize == 0; 
    else 
      stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE); 
 
    if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL) 
       {        {
      SLJIT_ASSERT(!has_alternatives);      stacksize = GET2(matchingpath, 1);
       if (common->currententry == NULL)
         stacksize = 0;
       else if (stacksize == RREF_ANY)
         stacksize = 1;
       else if (common->currententry->start == 0)
         stacksize = stacksize == 0;
       else
         stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
 
       if (stacksize != 0)        if (stacksize != 0)
         matchingpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
         }
       else
         {
         if (common->currententry == NULL || common->currententry->start == 0)
           stacksize = 0;
       else        else
         {          {
           stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
           slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
           i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
           while (stacksize > 0)
             {
             if ((int)GET2(slot, 0) == i)
               break;
             slot += common->name_entry_size;
             stacksize--;
             }
           }
   
         if (stacksize != 0)
           matchingpath += 1 + 2 * IMM2_SIZE;
         }
   
         /* The stacksize == 0 is a common "else" case. */
         if (stacksize == 0)
           {
         if (*cc == OP_ALT)          if (*cc == OP_ALT)
           {            {
           matchingpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
Line 6497  if (opcode == OP_COND || opcode == OP_SCOND) Line 6547  if (opcode == OP_COND || opcode == OP_SCOND)
         else          else
           matchingpath = cc;            matchingpath = cc;
         }          }
       }  
     else  
       {  
       SLJIT_ASSERT(has_alternatives);  
   
       stacksize = GET2(matchingpath, 1);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));  
       OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize);  
       GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);  
       OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);  
       sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));  
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
       add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));  
       matchingpath += 1 + IMM2_SIZE;  
       }  
     }      }
   else    else
     {      {
Line 6956  count_match(common); Line 6988  count_match(common);
 return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
 }  }
   
static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *max, int *min, pcre_uchar **end)
 {  {
 int class_len;  int class_len;
   
Line 6992  else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEP Line 7024  else if (*opcode >= OP_TYPESTAR && *opcode <= OP_TYPEP
   }    }
 else  else
   {    {
  SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);  SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
   *type = *opcode;    *type = *opcode;
   cc++;    cc++;
   class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
Line 7003  else Line 7035  else
     if (end != NULL)      if (end != NULL)
       *end = cc + class_len;        *end = cc + class_len;
     }      }
     else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
       {
       *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
       if (end != NULL)
         *end = cc + class_len;
       }
   else    else
     {      {
    SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);    SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
    *arg1 = GET2(cc, (class_len + IMM2_SIZE));    *max = GET2(cc, (class_len + IMM2_SIZE));
    *arg2 = GET2(cc, class_len);    *min = GET2(cc, class_len);
   
    if (*arg2 == 0)    if (*min == 0)
       {        {
      SLJIT_ASSERT(*arg1 != 0);      SLJIT_ASSERT(*max != 0);
      *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;      *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO);
       }        }
    if (*arg1 == *arg2)    if (*max == *min)
       *opcode = OP_EXACT;        *opcode = OP_EXACT;
   
     if (end != NULL)      if (end != NULL)
Line 7025  else Line 7063  else
   
 if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)  if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
   {    {
  *arg1 = GET2(cc, 0);  *max = GET2(cc, 0);
   cc += IMM2_SIZE;    cc += IMM2_SIZE;
   }    }
   
Line 7054  DEFINE_COMPILER; Line 7092  DEFINE_COMPILER;
 backtrack_common *backtrack;  backtrack_common *backtrack;
 pcre_uchar opcode;  pcre_uchar opcode;
 pcre_uchar type;  pcre_uchar type;
int arg1 = -1, arg2 = -1;int max = -1, min = -1;
 pcre_uchar* end;  pcre_uchar* end;
 jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
Line 7067  int tmp_base, tmp_offset; Line 7105  int tmp_base, tmp_offset;
   
 PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
   
cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end);
   
 switch(type)  switch(type)
   {    {
Line 7138  switch(opcode) Line 7176  switch(opcode)
       {        {
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
      if (opcode == OP_CRRANGE && arg2 > 0)      if (opcode == OP_CRRANGE && min > 0)
        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
      if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))      if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0))
        jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);        jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
       }        }
   
Line 7168  switch(opcode) Line 7206  switch(opcode)
     OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
     if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
       JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
    else if (opcode == OP_CRRANGE && arg1 == 0)    else if (opcode == OP_CRRANGE && max == 0)
       {        {
       OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
       JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
Line 7178  switch(opcode) Line 7216  switch(opcode)
       OP1(SLJIT_MOV, TMP1, 0, base, offset1);        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
       OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
       OP1(SLJIT_MOV, base, offset1, TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label);
       }        }
     set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
     if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, min + 1));
     OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
     }      }
   BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
Line 7220  switch(opcode) Line 7258  switch(opcode)
   break;    break;
   
   case OP_EXACT:    case OP_EXACT:
  OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);  OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
   label = LABEL();    label = LABEL();
   compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
   OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
Line 7233  switch(opcode) Line 7271  switch(opcode)
   if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
   if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max);
   OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
   label = LABEL();    label = LABEL();
   compile_char1_matchingpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
Line 7257  switch(opcode) Line 7295  switch(opcode)
   OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
   break;    break;
   
     case OP_CRPOSRANGE:
     /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */
     OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);
     label = LABEL();
     compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
     OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
     JUMPTO(SLJIT_C_NOT_ZERO, label);
   
     if (max != 0)
       {
       SLJIT_ASSERT(max - min > 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max - min);
       }
     OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
     label = LABEL();
     compile_char1_matchingpath(common, type, cc, &nomatch);
     OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
     if (max == 0)
       JUMPTO(SLJIT_JUMP, label);
     else
       {
       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
       JUMPTO(SLJIT_C_NOT_ZERO, label);
       }
     set_jumps(nomatch, LABEL());
     OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     break;
   
   default:    default:
   SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
   break;    break;
Line 7534  while (cc < ccend) Line 7600  while (cc < ccend)
   
     case OP_CLASS:      case OP_CLASS:
     case OP_NCLASS:      case OP_NCLASS:
    if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)    if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRPOSRANGE)
       cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
     else      else
       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
Line 7542  while (cc < ccend) Line 7608  while (cc < ccend)
   
 #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
     case OP_XCLASS:      case OP_XCLASS:
    if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)    if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRPOSRANGE)
       cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
     else      else
       cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);        cc = compile_char1_matchingpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
Line 7551  while (cc < ccend) Line 7617  while (cc < ccend)
   
     case OP_REF:      case OP_REF:
     case OP_REFI:      case OP_REFI:
    if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)    if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRPOSRANGE)
       cc = compile_ref_iterator_matchingpath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
     else      else
      cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);      {
       compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
       cc += 1 + IMM2_SIZE;
       }
     break;      break;
   
       case OP_DNREF:
       case OP_DNREFI:
       if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
         cc = compile_ref_iterator_matchingpath(common, cc, parent);
       else
         {
         compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
         compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
         cc += 1 + 2 * IMM2_SIZE;
         }
       break;
   
     case OP_RECURSE:      case OP_RECURSE:
     cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
     break;      break;
Line 7707  DEFINE_COMPILER; Line 7788  DEFINE_COMPILER;
 pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
 pcre_uchar opcode;  pcre_uchar opcode;
 pcre_uchar type;  pcre_uchar type;
int arg1 = -1, arg2 = -1;int max = -1, min = -1;
 struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
 jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
Line 7716  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_ Line 7797  int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_
 int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
 int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);  int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_sw);
   
cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL);
   
 switch(opcode)  switch(opcode)
   {    {
Line 7735  switch(opcode) Line 7816  switch(opcode)
   else    else
     {      {
     if (opcode == OP_UPTO)      if (opcode == OP_UPTO)
      arg2 = 0;      min = 0;
     if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
       {        {
       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
Line 7745  switch(opcode) Line 7826  switch(opcode)
       {        {
       OP1(SLJIT_MOV, TMP1, 0, base, offset1);        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
       OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1);
       OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
       }        }
     skip_char_back(common);      skip_char_back(common);
Line 7790  switch(opcode) Line 7871  switch(opcode)
   OP1(SLJIT_MOV, base, offset1, TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
   
   if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label);
   
  if (opcode == OP_CRMINRANGE && arg1 == 0)  if (opcode == OP_CRMINRANGE && max == 0)
     JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
   else    else
    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 2, CURRENT_AS(iterator_backtrack)->matchingpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 2, CURRENT_AS(iterator_backtrack)->matchingpath);
   
   set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
   if (private_data_ptr == 0)    if (private_data_ptr == 0)
Line 7830  switch(opcode) Line 7911  switch(opcode)
   
   case OP_EXACT:    case OP_EXACT:
   case OP_POSPLUS:    case OP_POSPLUS:
     case OP_CRPOSRANGE:
   set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
   break;    break;
   
Line 7848  static SLJIT_INLINE void compile_ref_iterator_backtrac Line 7930  static SLJIT_INLINE void compile_ref_iterator_backtrac
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
   BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
 pcre_uchar type;  pcre_uchar type;
   
type = cc[1 + IMM2_SIZE];type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
 
 if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
   {    {
     /* Maximize case. */
   set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
   free_stack(common, 1);    free_stack(common, 1);
Line 7863  if ((type & 0x1) == 0) Line 7948  if ((type & 0x1) == 0)
 OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
 CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
 set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
free_stack(common, 2);free_stack(common, ref ? 2 : 3);
 }  }
   
 static SLJIT_INLINE 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)
Line 8664  while (current) Line 8749  while (current)
   
     case OP_REF:      case OP_REF:
     case OP_REFI:      case OP_REFI:
       case OP_DNREF:
       case OP_DNREFI:
     compile_ref_iterator_backtrackingpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
     break;      break;
   
Line 8958  else Line 9045  else
 common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
 common->ctypes = (sljit_sw)(tables + ctypes_offset);  common->ctypes = (sljit_sw)(tables + ctypes_offset);
 common->digits[0] = -2;  common->digits[0] = -2;
common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset);common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
 common->name_count = re->name_count;  common->name_count = re->name_count;
 common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
 common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
Line 9696  if (extra != NULL && Line 9783  if (extra != NULL &&
   }    }
 }  }
   
   #if defined COMPILE_PCRE8
   PCRE_EXP_DECL void
   pcre_jit_free_unused_memory(void)
   #elif defined COMPILE_PCRE16
   PCRE_EXP_DECL void
   pcre16_jit_free_unused_memory(void)
   #elif defined COMPILE_PCRE32
   PCRE_EXP_DECL void
   pcre32_jit_free_unused_memory(void)
   #endif
   {
   sljit_free_unused_memory_exec();
   }
   
 #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
   
 /* These are dummy functions to avoid linking errors when JIT support is not  /* These are dummy functions to avoid linking errors when JIT support is not
Line 9745  pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_ji Line 9846  pcre32_assign_jit_stack(pcre32_extra *extra, pcre32_ji
 (void)extra;  (void)extra;
 (void)callback;  (void)callback;
 (void)userdata;  (void)userdata;
   }
   
   #if defined COMPILE_PCRE8
   PCRE_EXP_DECL void
   pcre_jit_free_unused_memory(void)
   #elif defined COMPILE_PCRE16
   PCRE_EXP_DECL void
   pcre16_jit_free_unused_memory(void)
   #elif defined COMPILE_PCRE32
   PCRE_EXP_DECL void
   pcre32_jit_free_unused_memory(void)
   #endif
   {
 }  }
   
 #endif  #endif

Removed from v.1.1.1.4  
changed lines
  Added in v.1.1.1.5


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>