/[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 1310 by zherczeg, Sat Apr 6 06:51:09 2013 UTC revision 1426 by zherczeg, Wed Jan 1 13:14:19 2014 UTC
# Line 168  typedef struct jit_arguments { Line 168  typedef struct jit_arguments {
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169    void *callout_data;    void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171      pcre_uint32 limit_match;
172    int real_offset_count;    int real_offset_count;
173    int offset_count;    int offset_count;
   int call_limit;  
174    pcre_uint8 notbol;    pcre_uint8 notbol;
175    pcre_uint8 noteol;    pcre_uint8 noteol;
176    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 182  typedef struct executable_functions { Line 182  typedef struct executable_functions {
182    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
183    void *userdata;    void *userdata;
184    pcre_uint32 top_bracket;    pcre_uint32 top_bracket;
185      pcre_uint32 limit_match;
186    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
187  } executable_functions;  } executable_functions;
188    
# Line 210  typedef int (SLJIT_CALL *jit_function)(j Line 211  typedef int (SLJIT_CALL *jit_function)(j
211    
212  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
213  code generator. It is allocated by compile_matchingpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
214  the aguments for compile_backtrackingpath. Must be the first member  the arguments for compile_backtrackingpath. Must be the first member
215  of its descendants. */  of its descendants. */
216  typedef struct backtrack_common {  typedef struct backtrack_common {
217    /* Concatenation stack. */    /* Concatenation stack. */
# Line 305  typedef struct then_trap_backtrack { Line 306  typedef struct then_trap_backtrack {
306    int framesize;    int framesize;
307  } then_trap_backtrack;  } then_trap_backtrack;
308    
309  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 4
310    
311  typedef struct compiler_common {  typedef struct compiler_common {
312    /* The sljit ceneric compiler. */    /* The sljit ceneric compiler. */
# Line 362  typedef struct compiler_common { Line 363  typedef struct compiler_common {
363    BOOL positive_assert;    BOOL positive_assert;
364    /* Newline control. */    /* Newline control. */
365    int nltype;    int nltype;
366      pcre_uint32 nlmax;
367      pcre_uint32 nlmin;
368    int newline;    int newline;
369    int bsr_nltype;    int bsr_nltype;
370      pcre_uint32 bsr_nlmax;
371      pcre_uint32 bsr_nlmin;
372    /* Dollar endonly. */    /* Dollar endonly. */
373    int endonly;    int endonly;
374    /* Tables. */    /* Tables. */
375    sljit_sw ctypes;    sljit_sw ctypes;
   int digits[2 + MAX_RANGE_SIZE];  
376    /* Named capturing brackets. */    /* Named capturing brackets. */
377    sljit_uw name_table;    pcre_uchar *name_table;
378    sljit_sw name_count;    sljit_sw name_count;
379    sljit_sw name_entry_size;    sljit_sw name_entry_size;
380    
# Line 403  typedef struct compiler_common { Line 407  typedef struct compiler_common {
407  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
408    BOOL use_ucp;    BOOL use_ucp;
409  #endif  #endif
 #ifndef COMPILE_PCRE32  
   jump_list *utfreadchar;  
 #endif  
410  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
411      jump_list *utfreadchar;
412      jump_list *utfreadchar16;
413    jump_list *utfreadtype8;    jump_list *utfreadtype8;
414  #endif  #endif
415  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
# Line 463  typedef struct compare_context { Line 466  typedef struct compare_context {
466  #define STACK_TOP     SLJIT_SCRATCH_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
467  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
468  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
469  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define COUNT_MATCH   SLJIT_SAVED_EREG2
470  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
471    
472  /* Local space layout. */  /* Local space layout. */
# Line 474  typedef struct compare_context { Line 477  typedef struct compare_context {
477  #define POSSESSIVE0      (2 * sizeof(sljit_sw))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
478  #define POSSESSIVE1      (3 * sizeof(sljit_sw))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
479  /* Max limit of recursions. */  /* Max limit of recursions. */
480  #define CALL_LIMIT       (4 * sizeof(sljit_sw))  #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
481  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
482  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
483  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
484  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. */
485  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
486  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
487  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
488  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
489    
490  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 523  the start pointers when the end of the c Line 526  the start pointers when the end of the c
526  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
527    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
528    
529    #define READ_CHAR_MAX 0x7fffffff
530    
531  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
532  {  {
533  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
# Line 532  cc += 1 + LINK_SIZE; Line 537  cc += 1 + LINK_SIZE;
537  return cc;  return cc;
538  }  }
539    
540    static int ones_in_half_byte[16] = {
541      /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
542      /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
543    };
544    
545  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
546   next_opcode   next_opcode
547   check_opcode_types   check_opcode_types
# Line 584  switch(*cc) Line 594  switch(*cc)
594    case OP_CRMINQUERY:    case OP_CRMINQUERY:
595    case OP_CRRANGE:    case OP_CRRANGE:
596    case OP_CRMINRANGE:    case OP_CRMINRANGE:
597      case OP_CRPOSSTAR:
598      case OP_CRPOSPLUS:
599      case OP_CRPOSQUERY:
600      case OP_CRPOSRANGE:
601    case OP_CLASS:    case OP_CLASS:
602    case OP_NCLASS:    case OP_NCLASS:
603    case OP_REF:    case OP_REF:
604    case OP_REFI:    case OP_REFI:
605      case OP_DNREF:
606      case OP_DNREFI:
607    case OP_RECURSE:    case OP_RECURSE:
608    case OP_CALLOUT:    case OP_CALLOUT:
609    case OP_ALT:    case OP_ALT:
# Line 613  switch(*cc) Line 629  switch(*cc)
629    case OP_SCBRAPOS:    case OP_SCBRAPOS:
630    case OP_SCOND:    case OP_SCOND:
631    case OP_CREF:    case OP_CREF:
632    case OP_NCREF:    case OP_DNCREF:
633    case OP_RREF:    case OP_RREF:
634    case OP_NRREF:    case OP_DNRREF:
635    case OP_DEF:    case OP_DEF:
636    case OP_BRAZERO:    case OP_BRAZERO:
637    case OP_BRAMINZERO:    case OP_BRAMINZERO:
# Line 735  switch(*cc) Line 751  switch(*cc)
751    
752  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)
753  {  {
754  pcre_uchar *name;  int count;
755  pcre_uchar *name2;  pcre_uchar *slot;
 unsigned int cbra_index;  
 int i;  
756    
757  /* 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. */
758  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 786  while (cc < ccend)
786      break;      break;
787    
788      case OP_CREF:      case OP_CREF:
789      i = GET2(cc, 1);      common->optimized_cbracket[GET2(cc, 1)] = 0;
     common->optimized_cbracket[i] = 0;  
790      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
791      break;      break;
792    
793      case OP_NCREF:      case OP_DNREF:
794      cbra_index = GET2(cc, 1);      case OP_DNREFI:
795      name = (pcre_uchar *)common->name_table;      case OP_DNCREF:
796      name2 = name;      count = GET2(cc, 1 + IMM2_SIZE);
797      for (i = 0; i < common->name_count; i++)      slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
798        {      while (count-- > 0)
799        if (GET2(name, 0) == cbra_index) break;        {
800        name += common->name_entry_size;        common->optimized_cbracket[GET2(slot, 0)] = 0;
801        }        slot += common->name_entry_size;
     SLJIT_ASSERT(i != common->name_count);  
   
     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;  
802        }        }
803      cc += 1 + IMM2_SIZE;      cc += 1 + 2 * IMM2_SIZE;
804      break;      break;
805    
806      case OP_RECURSE:      case OP_RECURSE:
# Line 2022  while (list_item) Line 2028  while (list_item)
2028  common->stubs = NULL;  common->stubs = NULL;
2029  }  }
2030    
2031  static SLJIT_INLINE void decrease_call_count(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2032  {  {
2033  DEFINE_COMPILER;  DEFINE_COMPILER;
2034    
2035  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
2036  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
2037  }  }
2038    
# Line 2373  return (bit < 256) ? ((0 << 8) | bit) : Line 2379  return (bit < 256) ? ((0 << 8) | bit) :
2379    
2380  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
2381  {  {
2382  /* Checks whether a partial matching is occured. Does not modify registers. */  /* Checks whether a partial matching is occurred. Does not modify registers. */
2383  DEFINE_COMPILER;  DEFINE_COMPILER;
2384  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2385    
# Line 2460  else Line 2466  else
2466  JUMPHERE(jump);  JUMPHERE(jump);
2467  }  }
2468    
2469  static void read_char(compiler_common *common)  static void peek_char(compiler_common *common, pcre_uint32 max)
2470  {  {
2471  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2472  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2473  DEFINE_COMPILER;  DEFINE_COMPILER;
2474  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2475  struct sljit_jump *jump;  struct sljit_jump *jump;
2476  #endif  #endif
2477    
2478    SLJIT_UNUSED_ARG(max);
2479    
2480  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2481  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2482  if (common->utf)  if (common->utf)
2483    {    {
2484  #if defined COMPILE_PCRE8    if (max < 128) return;
2485    
2486    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2487  #elif defined COMPILE_PCRE16    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);  
 #endif /* COMPILE_PCRE[8|16] */  
2488    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2489      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2490    JUMPHERE(jump);    JUMPHERE(jump);
2491    }    }
2492  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2493    
2494    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2495    if (common->utf)
2496      {
2497      if (max < 0xd800) return;
2498    
2499      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2500      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2501      /* TMP2 contains the high surrogate. */
2502      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2503      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2504      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2505      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2506      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2507      JUMPHERE(jump);
2508      }
2509    #endif
2510    }
2511    
2512    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2513    
2514    static BOOL is_char7_bitset(const pcre_uint8* bitset, BOOL nclass)
2515    {
2516    /* Tells whether the character codes below 128 are enough
2517    to determine a match. */
2518    const pcre_uint8 value = nclass ? 0xff : 0;
2519    const pcre_uint8* end = bitset + 32;
2520    
2521    bitset += 16;
2522    do
2523      {
2524      if (*bitset++ != value)
2525        return FALSE;
2526      }
2527    while (bitset < end);
2528    return TRUE;
2529    }
2530    
2531    static void read_char7_type(compiler_common *common, BOOL full_read)
2532    {
2533    /* Reads the precise character type of a character into TMP1, if the character
2534    is less than 128. Otherwise it returns with zero. Does not check STR_END. The
2535    full_read argument tells whether characters above max are accepted or not. */
2536    DEFINE_COMPILER;
2537    struct sljit_jump *jump;
2538    
2539    SLJIT_ASSERT(common->utf);
2540    
2541    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2542  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2543    
2544    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2545    
2546    if (full_read)
2547      {
2548      jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2549      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2550      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2551      JUMPHERE(jump);
2552      }
2553  }  }
2554    
2555  static void peek_char(compiler_common *common)  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2556    
2557    static void read_char_range(compiler_common *common, pcre_uint32 min, pcre_uint32 max, BOOL update_str_ptr)
2558  {  {
2559  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the precise value of a character into TMP1, if the character is
2560  Does not check STR_END. TMP2 Destroyed. */  between min and max (c >= min && c <= max). Otherwise it returns with a value
2561    outside the range. Does not check STR_END. */
2562  DEFINE_COMPILER;  DEFINE_COMPILER;
2563  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2564  struct sljit_jump *jump;  struct sljit_jump *jump;
2565  #endif  #endif
2566    
2567    SLJIT_UNUSED_ARG(update_str_ptr);
2568    SLJIT_UNUSED_ARG(min);
2569    SLJIT_UNUSED_ARG(max);
2570    SLJIT_ASSERT(min <= max);
2571    
2572  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2573  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2574    
2575    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2576  if (common->utf)  if (common->utf)
2577    {    {
2578  #if defined COMPILE_PCRE8    if (max < 128 && !update_str_ptr) return;
2579    
2580    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2581  #elif defined COMPILE_PCRE16    if (max >= 0x800)
2582    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2583  #endif /* COMPILE_PCRE[8|16] */    else if (max < 128)
2584    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));      {
2585    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2586        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2587        }
2588      else
2589        {
2590        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2591        if (!update_str_ptr)
2592          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2593        else
2594          OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2595        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2596        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2597        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2598        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2599        if (update_str_ptr)
2600          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2601        }
2602    JUMPHERE(jump);    JUMPHERE(jump);
2603    }    }
2604  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif
2605    
2606    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2607    if (common->utf)
2608      {
2609      if (max >= 0x10000)
2610        {
2611        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2612        jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2613        /* TMP2 contains the high surrogate. */
2614        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2615        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2616        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2617        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2618        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2619        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2620        JUMPHERE(jump);
2621        return;
2622        }
2623    
2624      if (max < 0xd800 && !update_str_ptr) return;
2625    
2626      /* Skip low surrogate if necessary. */
2627      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2628      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2629      if (update_str_ptr)
2630        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2631      if (max >= 0xd800)
2632        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
2633      JUMPHERE(jump);
2634      }
2635    #endif
2636    }
2637    
2638    static SLJIT_INLINE void read_char(compiler_common *common)
2639    {
2640    read_char_range(common, 0, READ_CHAR_MAX, TRUE);
2641  }  }
2642    
2643  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common, BOOL update_str_ptr)
2644  {  {
2645  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2646  DEFINE_COMPILER;  DEFINE_COMPILER;
2647  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2648  struct sljit_jump *jump;  struct sljit_jump *jump;
2649  #endif  #endif
2650    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2651    struct sljit_jump *jump2;
2652    #endif
2653    
2654  #ifdef SUPPORT_UTF  SLJIT_UNUSED_ARG(update_str_ptr);
2655    
2656    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2657    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2658    
2659    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2660  if (common->utf)  if (common->utf)
2661    {    {
   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 #if defined COMPILE_PCRE8  
2662    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2663    it is needed in most cases. */    it is needed in most cases. */
2664    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2665    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2666    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    if (!update_str_ptr)
2667    JUMPHERE(jump);      {
2668  #elif defined COMPILE_PCRE16      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2669    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2670    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2671    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2672    JUMPHERE(jump);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2673    /* Skip low surrogate if necessary. */      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
2674    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2675    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);      jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2676    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2677    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      JUMPHERE(jump2);
2678    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);      }
2679  #elif defined COMPILE_PCRE32    else
2680    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  
2681    JUMPHERE(jump);    JUMPHERE(jump);
 #endif /* COMPILE_PCRE[8|16|32] */  
2682    return;    return;
2683    }    }
2684  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2685  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
2686  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  #if !defined COMPILE_PCRE8
 #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  
2687  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2688  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2689  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2690  #endif  #endif
2691  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2692  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if !defined COMPILE_PCRE8
2693  JUMPHERE(jump);  JUMPHERE(jump);
2694  #endif  #endif
2695    
2696    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2697    if (common->utf && update_str_ptr)
2698      {
2699      /* Skip low surrogate if necessary. */
2700      OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2701      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2702      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2703      JUMPHERE(jump);
2704      }
2705    #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
2706  }  }
2707    
2708  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
# Line 2598  if (common->utf) Line 2740  if (common->utf)
2740  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2741  }  }
2742    
2743  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpifmatch)
2744  {  {
2745  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2746  DEFINE_COMPILER;  DEFINE_COMPILER;
2747    struct sljit_jump *jump;
2748    
2749  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2750    {    {
2751    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2752    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpifmatch ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2753    }    }
2754  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2755    {    {
2756    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    if (jumpifmatch)
2757    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      {
2758    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR));
2759    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2760    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));      }
2761      else
2762        {
2763        jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
2764        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
2765        JUMPHERE(jump);
2766        }
2767    }    }
2768  else  else
2769    {    {
2770    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2771    add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpifmatch ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2772    }    }
2773  }  }
2774    
# Line 2629  else Line 2778  else
2778  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2779  {  {
2780  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2781  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */
2782  DEFINE_COMPILER;  DEFINE_COMPILER;
2783  struct sljit_jump *jump;  struct sljit_jump *jump;
2784    
2785  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2786    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2787    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2788    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2789    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2790    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2791    
2792  /* Searching for the first zero. */  /* Searching for the first zero. */
2793  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
2794  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2795  /* Two byte sequence. */  /* Two byte sequence. */
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
2796  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2797  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2798    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2799    
2800    JUMPHERE(jump);
2801    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2802    OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2803  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2804  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2805  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
2806    
2807  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2808  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2809  /* Three byte sequence. */  /* Three byte sequence. */
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  
2810  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2811  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));  
2812  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2813    
2814  /* Four byte sequence. */  /* Four byte sequence. */
2815  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  JUMPHERE(jump);
2816  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2817  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2818    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2819    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2820  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
2821  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2822  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
2823    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2824    }
2825    
2826    static void do_utfreadchar16(compiler_common *common)
2827    {
2828    /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2829    of the character (>= 0xc0). Return value in TMP1. */
2830    DEFINE_COMPILER;
2831    struct sljit_jump *jump;
2832    
2833    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2834    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2835    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2836    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2837  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
2838  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2839  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));  
2840  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));  /* Searching for the first zero. */
2841    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
2842    jump = JUMP(SLJIT_C_NOT_ZERO);
2843    /* Two byte sequence. */
2844    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2845    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2846    
2847    JUMPHERE(jump);
2848    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400);
2849    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_NOT_ZERO);
2850    /* This code runs only in 8 bit mode. No need to shift the value. */
2851    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2852    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2853    OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2854    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2855  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2856  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2857  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));  /* Three byte sequence. */
2858    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2859  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2860  }  }
2861    
# Line 2700  jump = JUMP(SLJIT_C_NOT_ZERO); Line 2875  jump = JUMP(SLJIT_C_NOT_ZERO);
2875  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2876  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2877  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2878    /* The upper 5 bits are known at this point. */
2879    compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
2880  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2881  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2882  OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);  OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
 compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  
2883  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2884  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2885    
2886  JUMPHERE(compare);  JUMPHERE(compare);
2887  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2888  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2889    
2890  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 }  
   
 #elif defined COMPILE_PCRE16  
   
 static void do_utfreadchar(compiler_common *common)  
 {  
 /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  
 of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */  
 DEFINE_COMPILER;  
 struct sljit_jump *jump;  
   
 sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  
 jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  
 /* Do nothing, only return. */  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
   
2891  JUMPHERE(jump);  JUMPHERE(jump);
2892  /* Combine two 16 bit characters. */  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2893  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2894  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  
2895  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2896  }  }
2897    
2898  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE8 */
2899    
2900  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2901    
# Line 2821  if (firstline) Line 2970  if (firstline)
2970      mainloop = LABEL();      mainloop = LABEL();
2971      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2972      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2973      read_char(common);      read_char_range(common, common->nlmin, common->nlmax, TRUE);
2974      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2975      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2976      JUMPHERE(end);      JUMPHERE(end);
# Line 2897  if (newlinecheck) Line 3046  if (newlinecheck)
3046  return mainloop;  return mainloop;
3047  }  }
3048    
3049  #define MAX_N_CHARS 3  static int scan_prefix(compiler_common *common, pcre_uchar *cc, pcre_uint32 *chars, int max_chars)
   
 static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)  
3050  {  {
3051  DEFINE_COMPILER;  /* Recursive function, which scans prefix literals. */
3052  struct sljit_label *start;  int len, repeat, len_save, consumed = 0;
3053  struct sljit_jump *quit;  pcre_uint32 caseless, chr, mask;
3054  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uchar *alternative, *cc_save;
3055  pcre_uchar *cc = common->start + 1 + LINK_SIZE;  BOOL last, any;
 int location = 0;  
 pcre_int32 len, c, bit, caseless;  
 int must_stop;  
   
 /* We do not support alternatives now. */  
 if (*(common->start + GET(common->start, 1)) == OP_ALT)  
   return FALSE;  
3056    
3057    repeat = 1;
3058  while (TRUE)  while (TRUE)
3059    {    {
3060      last = TRUE;
3061      any = FALSE;
3062    caseless = 0;    caseless = 0;
3063    must_stop = 1;    switch (*cc)
   switch(*cc)  
3064      {      {
     case OP_CHAR:  
     must_stop = 0;  
     cc++;  
     break;  
   
3065      case OP_CHARI:      case OP_CHARI:
3066      caseless = 1;      caseless = 1;
3067      must_stop = 0;      case OP_CHAR:
3068        last = FALSE;
3069      cc++;      cc++;
3070      break;      break;
3071    
# Line 2952  while (TRUE) Line 3090  while (TRUE)
3090      cc++;      cc++;
3091      break;      break;
3092    
3093        case OP_EXACTI:
3094        caseless = 1;
3095      case OP_EXACT:      case OP_EXACT:
3096        repeat = GET2(cc, 1);
3097        last = FALSE;
3098      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
3099      break;      break;
3100    
# Line 2963  while (TRUE) Line 3105  while (TRUE)
3105      cc++;      cc++;
3106      break;      break;
3107    
3108      case OP_EXACTI:      case OP_KET:
3109      caseless = 1;      cc += 1 + LINK_SIZE;
3110      cc += 1 + IMM2_SIZE;      continue;
     break;  
   
     default:  
     must_stop = 2;  
     break;  
     }  
   
   if (must_stop == 2)  
       break;  
3111    
3112    len = 1;      case OP_ALT:
3113  #ifdef SUPPORT_UTF      cc += GET(cc, 1);
3114    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);      continue;
 #endif  
3115    
3116    if (caseless && char_has_othercase(common, cc))      case OP_ONCE:
3117      {      case OP_ONCE_NC:
3118        case OP_BRA:
3119        case OP_BRAPOS:
3120        case OP_CBRA:
3121        case OP_CBRAPOS:
3122        alternative = cc + GET(cc, 1);
3123        while (*alternative == OP_ALT)
3124          {
3125          max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars);
3126          if (max_chars == 0)
3127            return consumed;
3128          alternative += GET(alternative, 1);
3129          }
3130    
3131        if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3132          cc += IMM2_SIZE;
3133        cc += 1 + LINK_SIZE;
3134        continue;
3135    
3136        case OP_CLASS:
3137        case OP_NCLASS:
3138        any = TRUE;
3139        cc += 1 + 32 / sizeof(pcre_uchar);
3140        break;
3141    
3142    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3143        case OP_XCLASS:
3144        any = TRUE;
3145        cc += GET(cc, 1);
3146        break;
3147    #endif
3148    
3149        case OP_NOT_DIGIT:
3150        case OP_DIGIT:
3151        case OP_NOT_WHITESPACE:
3152        case OP_WHITESPACE:
3153        case OP_NOT_WORDCHAR:
3154        case OP_WORDCHAR:
3155        case OP_ANY:
3156        case OP_ALLANY:
3157        any = TRUE;
3158        cc++;
3159        break;
3160    
3161    #ifdef SUPPORT_UCP
3162        case OP_NOTPROP:
3163        case OP_PROP:
3164        any = TRUE;
3165        cc += 1 + 2;
3166        break;
3167    #endif
3168    
3169        case OP_TYPEEXACT:
3170        repeat = GET2(cc, 1);
3171        cc += 1 + IMM2_SIZE;
3172        continue;
3173    
3174        default:
3175        return consumed;
3176        }
3177    
3178      if (any)
3179        {
3180    #ifdef SUPPORT_UTF
3181        if (common->utf) return consumed;
3182    #endif
3183    #if defined COMPILE_PCRE8
3184        mask = 0xff;
3185    #elif defined COMPILE_PCRE16
3186        mask = 0xffff;
3187    #elif defined COMPILE_PCRE32
3188        mask = 0xffffffff;
3189    #else
3190        SLJIT_ASSERT_STOP();
3191    #endif
3192    
3193        do
3194          {
3195          chars[0] = mask;
3196          chars[1] = mask;
3197    
3198          if (--max_chars == 0)
3199            return consumed;
3200          consumed++;
3201          chars += 2;
3202          }
3203        while (--repeat > 0);
3204    
3205        repeat = 1;
3206        continue;
3207        }
3208    
3209      len = 1;
3210    #ifdef SUPPORT_UTF
3211      if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3212    #endif
3213    
3214      if (caseless != 0 && char_has_othercase(common, cc))
3215        {
3216      caseless = char_get_othercase_bit(common, cc);      caseless = char_get_othercase_bit(common, cc);
3217      if (caseless == 0)      if (caseless == 0)
3218        return FALSE;        return consumed;
3219  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3220      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
3221  #else  #else
# Line 2998  while (TRUE) Line 3228  while (TRUE)
3228    else    else
3229      caseless = 0;      caseless = 0;
3230    
3231    while (len > 0 && location < MAX_N_CHARS * 2)    len_save = len;
3232      {    cc_save = cc;
3233      c = *cc;    while (TRUE)
3234      bit = 0;      {
3235      if (len == (caseless & 0xff))      do
3236        {        {
3237        bit = caseless >> 8;        chr = *cc;
3238        c |= bit;  #ifdef COMPILE_PCRE32
3239          if (SLJIT_UNLIKELY(chr == NOTACHAR))
3240            return consumed;
3241    #endif
3242          mask = 0;
3243          if ((pcre_uint32)len == (caseless & 0xff))
3244            {
3245            mask = caseless >> 8;
3246            chr |= mask;
3247            }
3248    
3249          if (chars[0] == NOTACHAR)
3250            {
3251            chars[0] = chr;
3252            chars[1] = mask;
3253            }
3254          else
3255            {
3256            mask |= chars[0] ^ chr;
3257            chr |= mask;
3258            chars[0] = chr;
3259            chars[1] |= mask;
3260            }
3261    
3262          len--;
3263          if (--max_chars == 0)
3264            return consumed;
3265          consumed++;
3266          chars += 2;
3267          cc++;
3268        }        }
3269        while (len > 0);
3270    
3271      chars[location] = c;      if (--repeat == 0)
3272      chars[location + 1] = bit;        break;
3273    
3274      len--;      len = len_save;
3275      location += 2;      cc = cc_save;
     cc++;  
3276      }      }
3277    
3278    if (location >= MAX_N_CHARS * 2 || must_stop != 0)    repeat = 1;
3279      if (last)
3280        return consumed;
3281      }
3282    }
3283    
3284    #define MAX_N_CHARS 16
3285    
3286    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
3287    {
3288    DEFINE_COMPILER;
3289    struct sljit_label *start;
3290    struct sljit_jump *quit;
3291    pcre_uint32 chars[MAX_N_CHARS * 2];
3292    pcre_uint8 ones[MAX_N_CHARS];
3293    pcre_uint32 mask;
3294    int i, max;
3295    int offsets[3];
3296    
3297    for (i = 0; i < MAX_N_CHARS; i++)
3298      {
3299      chars[i << 1] = NOTACHAR;
3300      chars[(i << 1) + 1] = 0;
3301      }
3302    
3303    max = scan_prefix(common, common->start, chars, MAX_N_CHARS);
3304    
3305    if (max <= 1)
3306      return FALSE;
3307    
3308    for (i = 0; i < max; i++)
3309      {
3310      mask = chars[(i << 1) + 1];
3311      ones[i] = ones_in_half_byte[mask & 0xf];
3312      mask >>= 4;
3313      while (mask != 0)
3314        {
3315        ones[i] += ones_in_half_byte[mask & 0xf];
3316        mask >>= 4;
3317        }
3318      }
3319    
3320    offsets[0] = -1;
3321    /* Scan forward. */
3322    for (i = 0; i < max; i++)
3323      if (ones[i] <= 2) {
3324        offsets[0] = i;
3325      break;      break;
3326    }    }
3327    
3328  /* At least two characters are required. */  if (offsets[0] == -1)
3329  if (location < 2 * 2)    return FALSE;
3330      return FALSE;  
3331    /* Scan backward. */
3332    offsets[1] = -1;
3333    for (i = max - 1; i > offsets[0]; i--)
3334      if (ones[i] <= 2) {
3335        offsets[1] = i;
3336        break;
3337      }
3338    
3339    offsets[2] = -1;
3340    if (offsets[1] >= 0)
3341      {
3342      /* Scan from middle. */
3343      for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
3344        if (ones[i] <= 2)
3345          {
3346          offsets[2] = i;
3347          break;
3348          }
3349    
3350      if (offsets[2] == -1)
3351        {
3352        for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)
3353          if (ones[i] <= 2)
3354            {
3355            offsets[2] = i;
3356            break;
3357            }
3358        }
3359      }
3360    
3361    SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));
3362    SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
3363    
3364    chars[0] = chars[offsets[0] << 1];
3365    chars[1] = chars[(offsets[0] << 1) + 1];
3366    if (offsets[2] >= 0)
3367      {
3368      chars[2] = chars[offsets[2] << 1];
3369      chars[3] = chars[(offsets[2] << 1) + 1];
3370      }
3371    if (offsets[1] >= 0)
3372      {
3373      chars[4] = chars[offsets[1] << 1];
3374      chars[5] = chars[(offsets[1] << 1) + 1];
3375      }
3376    
3377    max -= 1;
3378  if (firstline)  if (firstline)
3379    {    {
3380    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3381    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3382    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS(max));
3383    }    }
3384  else  else
3385    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3386    
3387  start = LABEL();  start = LABEL();
3388  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3389    
3390  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[0]));
3391  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  if (offsets[1] >= 0)
3392      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
3393  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3394    
3395  if (chars[1] != 0)  if (chars[1] != 0)
3396    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3397  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3398  if (location > 2 * 2)  if (offsets[2] >= 0)
3399    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[2] - 1));
3400  if (chars[3] != 0)  
3401    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);  if (offsets[1] >= 0)
 CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);  
 if (location > 2 * 2)  
3402    {    {
3403    if (chars[5] != 0)    if (chars[5] != 0)
3404      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
3405    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);
3406      }
3407    
3408    if (offsets[2] >= 0)
3409      {
3410      if (chars[3] != 0)
3411        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);
3412      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);
3413    }    }
3414  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3415    
# Line 3060  JUMPHERE(quit); Line 3418  JUMPHERE(quit);
3418  if (firstline)  if (firstline)
3419    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3420  else  else
3421    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS(max));
3422  return TRUE;  return TRUE;
3423  }  }
3424    
# Line 3180  firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_ Line 3538  firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_
3538  skip_char_back(common);  skip_char_back(common);
3539    
3540  loop = LABEL();  loop = LABEL();
3541  read_char(common);  read_char_range(common, common->nlmin, common->nlmax, TRUE);
3542  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  lastchar = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3543  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
3544    foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    foundcr = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
# Line 3209  if (firstline) Line 3567  if (firstline)
3567    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3568  }  }
3569    
3570  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks);
3571    
3572  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, pcre_uint8 *start_bits, BOOL firstline)
3573  {  {
3574  DEFINE_COMPILER;  DEFINE_COMPILER;
3575  struct sljit_label *start;  struct sljit_label *start;
3576  struct sljit_jump *quit;  struct sljit_jump *quit;
3577  struct sljit_jump *found = NULL;  struct sljit_jump *found = NULL;
3578  jump_list *matches = NULL;  jump_list *matches = NULL;
 pcre_uint8 inverted_start_bits[32];  
 int i;  
3579  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3580  struct sljit_jump *jump;  struct sljit_jump *jump;
3581  #endif  #endif
3582    
 for (i = 0; i < 32; ++i)  
   inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);  
   
3583  if (firstline)  if (firstline)
3584    {    {
3585    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 3242  if (common->utf) Line 3595  if (common->utf)
3595    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3596  #endif  #endif
3597    
3598  if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))  if (!check_class_ranges(common, start_bits, (start_bits[31] & 0x80) != 0, TRUE, &matches))
3599    {    {
3600  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3601    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
# Line 3251  if (!check_class_ranges(common, inverted Line 3604  if (!check_class_ranges(common, inverted
3604  #endif  #endif
3605    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3606    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3607    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
3608    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3609    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3610    found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
# Line 3454  JUMPHERE(skipread); Line 3807  JUMPHERE(skipread);
3807    
3808  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3809  check_str_end(common, &skipread_list);  check_str_end(common, &skipread_list);
3810  peek_char(common);  peek_char(common, READ_CHAR_MAX);
3811    
3812  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3813  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 3500  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3853  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3853  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3854  }  }
3855    
3856  /*  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
   range format:  
   
   ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).  
   ranges[1] = first bit (0 or 1)  
   ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)  
 */  
   
 static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)  
3857  {  {
3858  DEFINE_COMPILER;  DEFINE_COMPILER;
3859  struct sljit_jump *jump;  int ranges[MAX_RANGE_SIZE];
   
 if (ranges[0] < 0)  
   return FALSE;  
   
 switch(ranges[0])  
   {  
   case 1:  
   if (readch)  
     read_char(common);  
   add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));  
   return TRUE;  
   
   case 2:  
   if (readch)  
     read_char(common);  
   OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);  
   add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));  
   return TRUE;  
   
   case 4:  
   if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])  
     {  
     if (readch)  
       read_char(common);  
     if (ranges[1] != 0)  
       {  
       add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));  
       add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));  
       }  
     else  
       {  
       jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);  
       add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));  
       JUMPHERE(jump);  
       }  
     return TRUE;  
     }  
   if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))  
     {  
     if (readch)  
       read_char(common);  
     OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);  
     OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);  
     add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));  
     return TRUE;  
     }  
   return FALSE;  
   
   default:  
   return FALSE;  
   }  
 }  
   
 static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)  
 {  
 int i, bit, length;  
 const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;  
   
 bit = ctypes[0] & flag;  
 ranges[0] = -1;  
 ranges[1] = bit != 0 ? 1 : 0;  
 length = 0;  
   
 for (i = 1; i < 256; i++)  
   if ((ctypes[i] & flag) != bit)  
     {  
     if (length >= MAX_RANGE_SIZE)  
       return;  
     ranges[2 + length] = i;  
     length++;  
     bit ^= flag;  
     }  
   
 if (bit != 0)  
   {  
   if (length >= MAX_RANGE_SIZE)  
     return;  
   ranges[2 + length] = 256;  
   length++;  
   }  
 ranges[0] = length;  
 }  
   
 static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)  
 {  
 int ranges[2 + MAX_RANGE_SIZE];  
3860  pcre_uint8 bit, cbit, all;  pcre_uint8 bit, cbit, all;
3861  int i, byte, length = 0;  int i, byte, length = 0;
3862    
3863  bit = bits[0] & 0x1;  bit = bits[0] & 0x1;
3864  ranges[1] = bit;  /* All bits will be zero or one (since bit is zero or one). */
 /* Can be 0 or 255. */  
3865  all = -bit;  all = -bit;
3866    
3867  for (i = 0; i < 256; )  for (i = 0; i < 256; )
# Line 3618  for (i = 0; i < 256; ) Line 3876  for (i = 0; i < 256; )
3876        {        {
3877        if (length >= MAX_RANGE_SIZE)        if (length >= MAX_RANGE_SIZE)
3878          return FALSE;          return FALSE;
3879        ranges[2 + length] = i;        ranges[length] = i;
3880        length++;        length++;
3881        bit = cbit;        bit = cbit;
3882        all = -cbit;        all = -cbit;
# Line 3631  if (((bit == 0) && nclass) || ((bit == 1 Line 3889  if (((bit == 0) && nclass) || ((bit == 1
3889    {    {
3890    if (length >= MAX_RANGE_SIZE)    if (length >= MAX_RANGE_SIZE)
3891      return FALSE;      return FALSE;
3892    ranges[2 + length] = 256;    ranges[length] = 256;
3893    length++;    length++;
3894    }    }
 ranges[0] = length;  
3895    
3896  return check_ranges(common, ranges, backtracks, FALSE);  if (length < 0 || length > 4)
3897      return FALSE;
3898    
3899    bit = bits[0] & 0x1;
3900    if (invert) bit ^= 0x1;
3901    
3902    /* No character is accepted. */
3903    if (length == 0 && bit == 0)
3904      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3905    
3906    switch(length)
3907      {
3908      case 0:
3909      /* When bit != 0, all characters are accepted. */
3910      return TRUE;
3911    
3912      case 1:
3913      add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3914      return TRUE;
3915    
3916      case 2:
3917      if (ranges[0] + 1 != ranges[1])
3918        {
3919        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3920        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3921        }
3922      else
3923        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3924      return TRUE;
3925    
3926      case 3:
3927      if (bit != 0)
3928        {
3929        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3930        if (ranges[0] + 1 != ranges[1])
3931          {
3932          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3933          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3934          }
3935        else
3936          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3937        return TRUE;
3938        }
3939    
3940      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
3941      if (ranges[1] + 1 != ranges[2])
3942        {
3943        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
3944        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
3945        }
3946      else
3947        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
3948      return TRUE;
3949    
3950      case 4:
3951      if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
3952          && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
3953          && is_powerof2(ranges[2] - ranges[0]))
3954        {
3955        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
3956        if (ranges[2] + 1 != ranges[3])
3957          {
3958          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3959          add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3960          }
3961        else
3962          add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3963        return TRUE;
3964        }
3965    
3966      if (bit != 0)
3967        {
3968        i = 0;
3969        if (ranges[0] + 1 != ranges[1])
3970          {
3971          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3972          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3973          i = ranges[0];
3974          }
3975        else
3976          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3977    
3978        if (ranges[2] + 1 != ranges[3])
3979          {
3980          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
3981          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3982          }
3983        else
3984          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
3985        return TRUE;
3986        }
3987    
3988      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3989      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
3990      if (ranges[1] + 1 != ranges[2])
3991        {
3992        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
3993        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
3994        }
3995      else
3996        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3997      return TRUE;
3998    
3999      default:
4000      SLJIT_ASSERT_STOP();
4001      return FALSE;
4002      }
4003  }  }
4004    
4005  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 4003  return cc; Line 4366  return cc;
4366  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
4367    if ((value) != typeoffset) \    if ((value) != typeoffset) \
4368      { \      { \
4369      if ((value) > typeoffset) \      if ((value) < typeoffset) \
       OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \  
     else \  
4370        OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \        OP2(SLJIT_ADD, typereg, 0, typereg, 0, SLJIT_IMM, typeoffset - (value)); \
4371        else \
4372          OP2(SLJIT_SUB, typereg, 0, typereg, 0, SLJIT_IMM, (value) - typeoffset); \
4373      } \      } \
4374    typeoffset = (value);    typeoffset = (value);
4375    
4376  #define SET_CHAR_OFFSET(value) \  #define SET_CHAR_OFFSET(value) \
4377    if ((value) != charoffset) \    if ((value) != charoffset) \
4378      { \      { \
4379      if ((value) > charoffset) \      if ((value) < charoffset) \
4380        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (value) - charoffset); \        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(charoffset - (value))); \
4381      else \      else \
4382        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, charoffset - (value)); \        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)((value) - charoffset)); \
4383      } \      } \
4384    charoffset = (value);    charoffset = (value);
4385    
# Line 4024  static void compile_xclass_matchingpath( Line 4387  static void compile_xclass_matchingpath(
4387  {  {
4388  DEFINE_COMPILER;  DEFINE_COMPILER;
4389  jump_list *found = NULL;  jump_list *found = NULL;
4390  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
4391  pcre_int32 c, charoffset;  sljit_uw c, charoffset, max = 256, min = READ_CHAR_MAX;
 const pcre_uint32 *other_cases;  
4392  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4393  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4394  int compares, invertcmp, numberofcmps;  int compares, invertcmp, numberofcmps;
4395    #if defined SUPPORT_UTF && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
4396    BOOL utf = common->utf;
4397    #endif
4398    
4399  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4400  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
4401  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
4402  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
4403  pcre_int32 typeoffset;  const pcre_uint32 *other_cases;
4404    sljit_uw typeoffset;
4405  #endif  #endif
4406    
4407  /* Although SUPPORT_UTF must be defined, we are  /* Scanning the necessary info. */
4408     not necessary in utf mode even in 8 bit mode. */  cc++;
4409  detect_partial_match(common, backtracks);  ccbegin = cc;
4410  read_char(common);  compares = 0;
4411    if (cc[-1] & XCL_MAP)
 if ((*cc++ & XCL_MAP) != 0)  
4412    {    {
4413    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    min = 0;
 #ifndef COMPILE_PCRE8  
   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #elif defined SUPPORT_UTF  
   if (common->utf)  
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #endif  
   
   if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))  
     {  
     OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  
     OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);  
     OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
     OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
     add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));  
     }  
   
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (common->utf)  
     JUMPHERE(jump);  
 #endif  
   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  
 #ifdef SUPPORT_UCP  
   charsaved = TRUE;  
 #endif  
4414    cc += 32 / sizeof(pcre_uchar);    cc += 32 / sizeof(pcre_uchar);
4415    }    }
4416    
 /* Scanning the necessary info. */  
 ccbegin = cc;  
 compares = 0;  
4417  while (*cc != XCL_END)  while (*cc != XCL_END)
4418    {    {
4419    compares++;    compares++;
4420    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
4421      {      {
4422      cc += 2;      cc ++;
4423  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4424      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (c > max) max = c;
4425  #endif      if (c < min) min = c;
4426  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4427      needschar = TRUE;      needschar = TRUE;
4428  #endif  #endif
4429      }      }
4430    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
4431      {      {
4432      cc += 2;      cc ++;
4433  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4434      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (c < min) min = c;
4435  #endif      GETCHARINCTEST(c, cc);
4436      cc++;      if (c > max) max = c;
 #ifdef SUPPORT_UTF  
     if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
4437  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4438      needschar = TRUE;      needschar = TRUE;
4439  #endif  #endif
# Line 4110  while (*cc != XCL_END) Line 4443  while (*cc != XCL_END)
4443      {      {
4444      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);      SLJIT_ASSERT(*cc == XCL_PROP || *cc == XCL_NOTPROP);
4445      cc++;      cc++;
4446        if (*cc == PT_CLIST)
4447          {
4448          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4449          while (*other_cases != NOTACHAR)
4450            {
4451            if (*other_cases > max) max = *other_cases;
4452            if (*other_cases < min) min = *other_cases;
4453            other_cases++;
4454            }
4455          }
4456        else
4457          {
4458          max = READ_CHAR_MAX;
4459          min = 0;
4460          }
4461    
4462      switch(*cc)      switch(*cc)
4463        {        {
4464        case PT_ANY:        case PT_ANY:
# Line 4129  while (*cc != XCL_END) Line 4478  while (*cc != XCL_END)
4478        case PT_SPACE:        case PT_SPACE:
4479        case PT_PXSPACE:        case PT_PXSPACE:
4480        case PT_WORD:        case PT_WORD:
4481          case PT_PXGRAPH:
4482          case PT_PXPRINT:
4483          case PT_PXPUNCT:
4484        needstype = TRUE;        needstype = TRUE;
4485        needschar = TRUE;        needschar = TRUE;
4486        break;        break;
# Line 4147  while (*cc != XCL_END) Line 4499  while (*cc != XCL_END)
4499  #endif  #endif
4500    }    }
4501    
4502    /* We are not necessary in utf mode even in 8 bit mode. */
4503    cc = ccbegin;
4504    detect_partial_match(common, backtracks);
4505    read_char_range(common, min, max, (cc[0] & XCL_NOT) != 0);
4506    
4507    if ((cc[-1] & XCL_HASPROP) == 0)
4508      {
4509      if ((cc[-1] & XCL_MAP) != 0)
4510        {
4511        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4512        if (!check_class_ranges(common, (const pcre_uint8 *)cc, (((const pcre_uint8 *)cc)[31] & 0x80) != 0, TRUE, &found))
4513          {
4514          OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4515          OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4516          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4517          OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4518          OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4519          add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));
4520          }
4521    
4522        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4523        JUMPHERE(jump);
4524    
4525        cc += 32 / sizeof(pcre_uchar);
4526        }
4527      else
4528        add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff));
4529      }
4530    else if ((cc[-1] & XCL_MAP) != 0)
4531      {
4532      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4533    #ifdef SUPPORT_UCP
4534      charsaved = TRUE;
4535    #endif
4536      if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
4537        {
4538    #ifdef COMPILE_PCRE8
4539        SLJIT_ASSERT(common->utf);
4540    #endif
4541        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4542    
4543        OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4544        OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4545        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4546        OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4547        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4548        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
4549    
4550        JUMPHERE(jump);
4551        }
4552    
4553      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
4554      cc += 32 / sizeof(pcre_uchar);
4555      }
4556    
4557  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4558  /* Simple register allocation. TMP1 is preferred if possible. */  /* Simple register allocation. TMP1 is preferred if possible. */
4559  if (needstype || needsscript)  if (needstype || needsscript)
# Line 4188  if (needstype || needsscript) Line 4595  if (needstype || needsscript)
4595  #endif  #endif
4596    
4597  /* Generating code. */  /* Generating code. */
 cc = ccbegin;  
4598  charoffset = 0;  charoffset = 0;
4599  numberofcmps = 0;  numberofcmps = 0;
4600  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4204  while (*cc != XCL_END) Line 4610  while (*cc != XCL_END)
4610    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
4611      {      {
4612      cc ++;      cc ++;
4613  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
     if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
4614    
4615      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4616        {        {
4617        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4618        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
4619        numberofcmps++;        numberofcmps++;
4620        }        }
4621      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4622        {        {
4623        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4624        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4625        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4626        numberofcmps = 0;        numberofcmps = 0;
4627        }        }
4628      else      else
4629        {        {
4630        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);        jump = CMP(SLJIT_C_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4631        numberofcmps = 0;        numberofcmps = 0;
4632        }        }
4633      }      }
4634    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
4635      {      {
4636      cc ++;      cc ++;
4637  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
     if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
4638      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
4639  #ifdef SUPPORT_UTF      GETCHARINCTEST(c, cc);
4640      if (common->utf)  
       {  
       GETCHARINC(c, cc);  
       }  
     else  
 #endif  
       c = *cc++;  
4641      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4642        {        {
4643        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4644        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4645        numberofcmps++;        numberofcmps++;
4646        }        }
4647      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4648        {        {
4649        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4650        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);
4651        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4652        numberofcmps = 0;        numberofcmps = 0;
4653        }        }
4654      else      else
4655        {        {
4656        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, c - charoffset);        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, TMP1, 0, SLJIT_IMM, (sljit_sw)(c - charoffset));
4657        numberofcmps = 0;        numberofcmps = 0;
4658        }        }
4659      }      }
# Line 4316  while (*cc != XCL_END) Line 4702  while (*cc != XCL_END)
4702    
4703        case PT_SPACE:        case PT_SPACE:
4704        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);  
         }  
4705        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4706        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);
4707        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);
4708        if (*cc == PT_SPACE)  
4709          JUMPHERE(jump);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
4710          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4711    
4712          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
4713          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4714    
4715        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4716        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);
# Line 4334  while (*cc != XCL_END) Line 4719  while (*cc != XCL_END)
4719        break;        break;
4720    
4721        case PT_WORD:        case PT_WORD:
4722        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_UNDERSCORE - charoffset));
4723        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4724        /* Fall through. */        /* Fall through. */
4725    
# Line 4382  while (*cc != XCL_END) Line 4767  while (*cc != XCL_END)
4767          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4768          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4769    
4770          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(other_cases[0] - charoffset));
4771          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4772    
4773          other_cases += 3;          other_cases += 3;
4774          }          }
4775        else        else
4776          {          {
4777          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
4778          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4779          }          }
4780    
4781        while (*other_cases != NOTACHAR)        while (*other_cases != NOTACHAR)
4782          {          {
4783          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(*other_cases++ - charoffset));
4784          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4785          }          }
4786        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4787        break;        break;
4788    
4789        case PT_UCNC:        case PT_UCNC:
4790        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_DOLLAR_SIGN - charoffset));
4791        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4792        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_COMMERCIAL_AT - charoffset));
4793        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4794        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(CHAR_GRAVE_ACCENT - charoffset));
4795        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4796    
4797        SET_CHAR_OFFSET(0xa0);        SET_CHAR_OFFSET(0xa0);
4798        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)(0xd7ff - charoffset));
4799        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4800          SET_CHAR_OFFSET(0);
4801          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4802          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4803          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4804          break;
4805    
4806          case PT_PXGRAPH:
4807          /* C and Z groups are the farthest two groups. */
4808          SET_TYPE_OFFSET(ucp_Ll);
4809          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
4810          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
4811    
4812          jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
4813    
4814          /* In case of ucp_Cf, we overwrite the result. */
4815          SET_CHAR_OFFSET(0x2066);
4816          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
4817          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4818    
4819          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
4820          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4821    
4822          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
4823          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4824    
4825          JUMPHERE(jump);
4826          jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4827          break;
4828    
4829          case PT_PXPRINT:
4830          /* C and Z groups are the farthest two groups. */
4831          SET_TYPE_OFFSET(ucp_Ll);
4832          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
4833          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
4834    
4835          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
4836          OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4837    
4838          jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
4839    
4840          /* In case of ucp_Cf, we overwrite the result. */
4841          SET_CHAR_OFFSET(0x2066);
4842          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
4843          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4844    
4845          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
4846          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4847    
4848          JUMPHERE(jump);
4849          jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4850          break;
4851    
4852          case PT_PXPUNCT:
4853          SET_TYPE_OFFSET(ucp_Sc);
4854          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
4855          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4856    
4857        SET_CHAR_OFFSET(0);        SET_CHAR_OFFSET(0);
4858        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
4859        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);        OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4860    
4861          SET_TYPE_OFFSET(ucp_Pc);
4862          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
4863          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4864        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4865        break;        break;
4866        }        }
# Line 4448  struct sljit_label *label; Line 4894  struct sljit_label *label;
4894  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4895  pcre_uchar propdata[5];  pcre_uchar propdata[5];
4896  #endif  #endif
4897  #endif  #endif /* SUPPORT_UTF */
4898    
4899  switch(type)  switch(type)
4900    {    {
# Line 4473  switch(type) Line 4919  switch(type)
4919    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4920    case OP_DIGIT:    case OP_DIGIT:
4921    /* Digits are usually 0-9, so it is worth to optimize them. */    /* Digits are usually 0-9, so it is worth to optimize them. */
   if (common->digits[0] == -2)  
     get_ctype_ranges(common, ctype_digit, common->digits);  
4922    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4923    /* Flip the starting bit in the negative case. */  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4924    if (type == OP_NOT_DIGIT)    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))
4925      common->digits[1] ^= 1;      read_char7_type(common, type == OP_NOT_DIGIT);
4926    if (!check_ranges(common, common->digits, backtracks, TRUE))    else
4927      {  #endif
4928      read_char8_type(common);      read_char8_type(common, type == OP_NOT_DIGIT);
4929      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      /* Flip the starting bit in the negative case. */
4930      add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4931      }    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
   if (type == OP_NOT_DIGIT)  
     common->digits[1] ^= 1;  
4932    return cc;    return cc;
4933    
4934    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4935    case OP_WHITESPACE:    case OP_WHITESPACE:
4936    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4937    read_char8_type(common);  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4938      if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))
4939        read_char7_type(common, type == OP_NOT_WHITESPACE);
4940      else
4941    #endif
4942        read_char8_type(common, type == OP_NOT_WHITESPACE);
4943    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
4944    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4945    return cc;    return cc;
# Line 4500  switch(type) Line 4947  switch(type)
4947    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4948    case OP_WORDCHAR:    case OP_WORDCHAR:
4949    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4950    read_char8_type(common);  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4951      if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))
4952        read_char7_type(common, type == OP_NOT_WORDCHAR);
4953      else
4954    #endif
4955        read_char8_type(common, type == OP_NOT_WORDCHAR);
4956    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
4957    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4958    return cc;    return cc;
4959    
4960    case OP_ANY:    case OP_ANY:
4961    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4962    read_char(common);    read_char_range(common, common->nlmin, common->nlmax, TRUE);
4963    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4964      {      {
4965      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
# Line 4563  switch(type) Line 5015  switch(type)
5015  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
5016    case OP_NOTPROP:    case OP_NOTPROP:
5017    case OP_PROP:    case OP_PROP:
5018    propdata[0] = 0;    propdata[0] = XCL_HASPROP;
5019    propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;    propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
5020    propdata[2] = cc[0];    propdata[2] = cc[0];
5021    propdata[3] = cc[1];    propdata[3] = cc[1];
# Line 4575  switch(type) Line 5027  switch(type)
5027    
5028    case OP_ANYNL:    case OP_ANYNL:
5029    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5030    read_char(common);    read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE);
5031    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
5032    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
5033    end_list = NULL;    end_list = NULL;
# Line 4597  switch(type) Line 5049  switch(type)
5049    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
5050    case OP_HSPACE:    case OP_HSPACE:
5051    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5052    read_char(common);    read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE);
5053    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
5054    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
5055    return cc;    return cc;
# Line 4605  switch(type) Line 5057  switch(type)
5057    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
5058    case OP_VSPACE:    case OP_VSPACE:
5059    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5060    read_char(common);    read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE);
5061    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
5062    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
5063    return cc;    return cc;
# Line 4704  switch(type) Line 5156  switch(type)
5156      else      else
5157        {        {
5158        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
5159        read_char(common);        read_char_range(common, common->nlmin, common->nlmax, TRUE);
5160        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
5161        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
5162        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
# Line 4752  switch(type) Line 5204  switch(type)
5204    else    else
5205      {      {
5206      skip_char_back(common);      skip_char_back(common);
5207      read_char(common);      read_char_range(common, common->nlmin, common->nlmax, TRUE);
5208      check_newlinechar(common, common->nltype, backtracks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
5209      }      }
5210    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
# Line 4803  switch(type) Line 5255  switch(type)
5255      }      }
5256    else    else
5257      {      {
5258      peek_char(common);      peek_char(common, common->nlmax);
5259      check_newlinechar(common, common->nltype, backtracks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
5260      }      }
5261    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
# Line 4827  switch(type) Line 5279  switch(type)
5279  #endif  #endif
5280      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
5281      }      }
5282    
5283    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
   read_char(common);  
5284  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
5285    if (common->utf)    if (common->utf)
5286      {      {
# Line 4837  switch(type) Line 5289  switch(type)
5289    else    else
5290  #endif  #endif
5291      c = *cc;      c = *cc;
5292    
5293    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
5294      {      {
5295        read_char_range(common, c, c, FALSE);
5296      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
5297      return cc + length;      return cc + length;
5298      }      }
5299    oc = char_othercase(common, c);    oc = char_othercase(common, c);
5300      read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE);
5301    bit = c ^ oc;    bit = c ^ oc;
5302    if (is_powerof2(bit))    if (is_powerof2(bit))
5303      {      {
# Line 4850  switch(type) Line 5305  switch(type)
5305      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
5306      return cc + length;      return cc + length;
5307      }      }
5308    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    jump[0] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c);
5309    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc));
5310    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);    JUMPHERE(jump[0]);
   OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  
   add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));  
5311    return cc + length;    return cc + length;
5312    
5313    case OP_NOT:    case OP_NOT:
# Line 4889  switch(type) Line 5342  switch(type)
5342  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
5343        {        {
5344        GETCHARLEN(c, cc, length);        GETCHARLEN(c, cc, length);
       read_char(common);  
5345        }        }
5346      }      }
5347    else    else
5348  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
     {  
     read_char(common);  
5349      c = *cc;      c = *cc;
     }  
5350    
5351    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
5352        {
5353        read_char_range(common, c, c, TRUE);
5354      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
5355        }
5356    else    else
5357      {      {
5358      oc = char_othercase(common, c);      oc = char_othercase(common, c);
5359        read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE);
5360      bit = c ^ oc;      bit = c ^ oc;
5361      if (is_powerof2(bit))      if (is_powerof2(bit))
5362        {        {
# Line 4921  switch(type) Line 5374  switch(type)
5374    case OP_CLASS:    case OP_CLASS:
5375    case OP_NCLASS:    case OP_NCLASS:
5376    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5377    read_char(common);  
5378    if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5379      bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;
5380      read_char_range(common, 0, bit, type == OP_NCLASS);
5381    #else
5382      read_char_range(common, 0, 255, type == OP_NCLASS);
5383    #endif
5384    
5385      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))
5386      return cc + 32 / sizeof(pcre_uchar);      return cc + 32 / sizeof(pcre_uchar);
5387    
5388  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5389    jump[0] = NULL;    jump[0] = NULL;
 #ifdef COMPILE_PCRE8  
   /* This check only affects 8 bit mode. In other modes, we  
   always need to compare the value with 255. */  
5390    if (common->utf)    if (common->utf)
 #endif /* COMPILE_PCRE8 */  
5391      {      {
5392      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit);
5393      if (type == OP_CLASS)      if (type == OP_CLASS)
5394        {        {
5395        add_jump(compiler, backtracks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
5396        jump[0] = NULL;        jump[0] = NULL;
5397        }        }
5398      }      }
5399  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #elif !defined COMPILE_PCRE8
5400      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
5401      if (type == OP_CLASS)
5402        {
5403        add_jump(compiler, backtracks, jump[0]);
5404        jump[0] = NULL;
5405        }
5406    #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
5407    
5408    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
5409    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
5410    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
5411    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5412    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
5413    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
5414    
5415  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
5416    if (jump[0] != NULL)    if (jump[0] != NULL)
5417      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
5418  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif
5419    
5420    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
5421    
5422  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 5055  if (context.length > 0) Line 5521  if (context.length > 0)
5521  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
5522  }  }
5523    
 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));  
 }  
   
5524  /* Forward definitions. */  /* Forward definitions. */
5525  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
5526  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
# Line 5109  static void compile_backtrackingpath(com Line 5553  static void compile_backtrackingpath(com
5553    
5554  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
5555    
5556  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)
5557    {
5558    /* The OVECTOR offset goes to TMP2. */
5559    DEFINE_COMPILER;
5560    int count = GET2(cc, 1 + IMM2_SIZE);
5561    pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
5562    unsigned int offset;
5563    jump_list *found = NULL;
5564    
5565    SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
5566    
5567    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5568    
5569    count--;
5570    while (count-- > 0)
5571      {
5572      offset = GET2(slot, 0) << 1;
5573      GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5574      add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5575      slot += common->name_entry_size;
5576      }
5577    
5578    offset = GET2(slot, 0) << 1;
5579    GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5580    if (backtracks != NULL && !common->jscript_compat)
5581      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5582    
5583    set_jumps(found, LABEL());
5584    }
5585    
5586    static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
5587  {  {
5588  DEFINE_COMPILER;  DEFINE_COMPILER;
5589  int offset = GET2(cc, 1) << 1;  BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5590    int offset = 0;
5591  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5592  struct sljit_jump *partial;  struct sljit_jump *partial;
5593  struct sljit_jump *nopartial;  struct sljit_jump *nopartial;
5594    
5595  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  if (ref)
5596  /* OVECTOR(1) contains the "string begin - 1" constant. */    {
5597  if (withchecks && !common->jscript_compat)    offset = GET2(cc, 1) << 1;
5598    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));
5599      /* OVECTOR(1) contains the "string begin - 1" constant. */
5600      if (withchecks && !common->jscript_compat)
5601        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5602      }
5603    else
5604      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5605    
5606  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5607  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5608    {    {
5609    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);
5610    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    if (ref)
5611        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5612      else
5613        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5614    
5615    if (withchecks)    if (withchecks)
5616      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5617    
# Line 5151  if (common->utf && *cc == OP_REFI) Line 5636  if (common->utf && *cc == OP_REFI)
5636  else  else
5637  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
5638    {    {
5639    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    if (ref)
5640        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
5641      else
5642        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
5643    
5644    if (withchecks)    if (withchecks)
5645      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
5646    
# Line 5188  if (jump != NULL) Line 5677  if (jump != NULL)
5677    else    else
5678      JUMPHERE(jump);      JUMPHERE(jump);
5679    }    }
 return cc + 1 + IMM2_SIZE;  
5680  }  }
5681    
5682  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)
5683  {  {
5684  DEFINE_COMPILER;  DEFINE_COMPILER;
5685    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5686  backtrack_common *backtrack;  backtrack_common *backtrack;
5687  pcre_uchar type;  pcre_uchar type;
5688    int offset = 0;
5689  struct sljit_label *label;  struct sljit_label *label;
5690  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
5691  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5205  BOOL minimize; Line 5695  BOOL minimize;
5695    
5696  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5697    
5698    if (ref)
5699      offset = GET2(cc, 1) << 1;
5700    else
5701      cc += IMM2_SIZE;
5702  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
5703    
5704    SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
5705  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
5706  switch(type)  switch(type)
5707    {    {
# Line 5243  if (!minimize) Line 5739  if (!minimize)
5739    if (min == 0)    if (min == 0)
5740      {      {
5741      allocate_stack(common, 2);      allocate_stack(common, 2);
5742        if (ref)
5743          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5744      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5745      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5746      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
5747      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));
5748      zerolength = compile_ref_checks(common, ccbegin, NULL);      /* Handles both invalid and empty cases. Since the minimum repeat,
5749        is zero the invalid case is basically the same as an empty case. */
5750        if (ref)
5751          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5752        else
5753          {
5754          compile_dnref_search(common, ccbegin, NULL);
5755          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5756          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5757          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5758          }
5759      /* Restore if not zero length. */      /* Restore if not zero length. */
5760      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));
5761      }      }
5762    else    else
5763      {      {
5764      allocate_stack(common, 1);      allocate_stack(common, 1);
5765        if (ref)
5766          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5767      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5768      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);      if (ref)
5769          {
5770          add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5771          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5772          }
5773        else
5774          {
5775          compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5776          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5777          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5778          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5779          }
5780      }      }
5781    
5782    if (min > 1 || max > 1)    if (min > 1 || max > 1)
5783      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5784    
5785    label = LABEL();    label = LABEL();
5786      if (!ref)
5787        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5788    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
5789    
5790    if (min > 1 || max > 1)    if (min > 1 || max > 1)
# Line 5292  if (!minimize) Line 5815  if (!minimize)
5815    JUMPHERE(zerolength);    JUMPHERE(zerolength);
5816    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5817    
5818    decrease_call_count(common);    count_match(common);
5819    return cc;    return cc;
5820    }    }
5821    
5822  allocate_stack(common, 2);  allocate_stack(common, ref ? 2 : 3);
5823    if (ref)
5824      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5825  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5826  if (type != OP_CRMINSTAR)  if (type != OP_CRMINSTAR)
5827    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5828    
5829  if (min == 0)  if (min == 0)
5830    {    {
5831    zerolength = compile_ref_checks(common, ccbegin, NULL);    /* Handles both invalid and empty cases. Since the minimum repeat,
5832      is zero the invalid case is basically the same as an empty case. */
5833      if (ref)
5834        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5835      else
5836        {
5837        compile_dnref_search(common, ccbegin, NULL);
5838        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5839        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5840        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5841        }
5842      /* Length is non-zero, we can match real repeats. */
5843    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5844    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5845    }    }
5846  else  else
5847    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    {
5848      if (ref)
5849        {
5850        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5851        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5852        }
5853      else
5854        {
5855        compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5856        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5857        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5858        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5859        }
5860      }
5861    
5862  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5863  if (max > 0)  if (max > 0)
5864    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));
5865    
5866    if (!ref)
5867      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
5868  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
5869  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5870    
# Line 5331  if (jump != NULL) Line 5882  if (jump != NULL)
5882    JUMPHERE(jump);    JUMPHERE(jump);
5883  JUMPHERE(zerolength);  JUMPHERE(zerolength);
5884    
5885  decrease_call_count(common);  count_match(common);
5886  return cc;  return cc;
5887  }  }
5888    
# Line 5901  common->accept = save_accept; Line 6452  common->accept = save_accept;
6452  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
6453  }  }
6454    
 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;  
 }  
   
6455  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)
6456  {  {
6457  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 6143  backtrack_common *backtrack; Line 6584  backtrack_common *backtrack;
6584  pcre_uchar opcode;  pcre_uchar opcode;
6585  int private_data_ptr = 0;  int private_data_ptr = 0;
6586  int offset = 0;  int offset = 0;
6587  int stacksize;  int i, stacksize;
6588  int repeat_ptr = 0, repeat_length = 0;  int repeat_ptr = 0, repeat_length = 0;
6589  int repeat_type = 0, repeat_count = 0;  int repeat_type = 0, repeat_count = 0;
6590  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6591  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6592    pcre_uchar *slot;
6593  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6594  pcre_uchar ket;  pcre_uchar ket;
6595  assert_backtrack *assert;  assert_backtrack *assert;
# Line 6197  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket Line 6639  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket
6639  cc += GET(cc, 1);  cc += GET(cc, 1);
6640    
6641  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6642  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
6643    {    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);  
     }  
   }  
6644    
6645  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
6646    opcode = OP_SCOND;    opcode = OP_SCOND;
# Line 6447  if (opcode == OP_COND || opcode == OP_SC Line 6877  if (opcode == OP_COND || opcode == OP_SC
6877        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)));
6878      matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
6879      }      }
6880    else if (*matchingpath == OP_NCREF)    else if (*matchingpath == OP_DNCREF)
6881      {      {
6882      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);  
     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_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));  
     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_searchovector));  
     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));  
6883    
6884      JUMPHERE(jump);      i = GET2(matchingpath, 1 + IMM2_SIZE);
6885      matchingpath += 1 + IMM2_SIZE;      slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6886        OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
6887        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6888        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6889        slot += common->name_entry_size;
6890        i--;
6891        while (i-- > 0)
6892          {
6893          OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6894          OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
6895          slot += common->name_entry_size;
6896          }
6897        OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
6898        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO));
6899        matchingpath += 1 + 2 * IMM2_SIZE;
6900      }      }
6901    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
6902      {      {
6903      /* Never has other case. */      /* Never has other case. */
6904      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
6905        SLJIT_ASSERT(!has_alternatives);
6906    
6907      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)  
6908        {        {
6909        SLJIT_ASSERT(!has_alternatives);        stacksize = GET2(matchingpath, 1);
6910          if (common->currententry == NULL)
6911            stacksize = 0;
6912          else if (stacksize == RREF_ANY)
6913            stacksize = 1;
6914          else if (common->currententry->start == 0)
6915            stacksize = stacksize == 0;
6916          else
6917            stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6918    
6919        if (stacksize != 0)        if (stacksize != 0)
6920          matchingpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
6921          }
6922        else
6923          {
6924          if (common->currententry == NULL || common->currententry->start == 0)
6925            stacksize = 0;
6926        else        else
6927          {          {
6928            stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
6929            slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6930            i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6931            while (stacksize > 0)
6932              {
6933              if ((int)GET2(slot, 0) == i)
6934                break;
6935              slot += common->name_entry_size;
6936              stacksize--;
6937              }
6938            }
6939    
6940          if (stacksize != 0)
6941            matchingpath += 1 + 2 * IMM2_SIZE;
6942          }
6943    
6944          /* The stacksize == 0 is a common "else" case. */
6945          if (stacksize == 0)
6946            {
6947          if (*cc == OP_ALT)          if (*cc == OP_ALT)
6948            {            {
6949            matchingpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
# Line 6496  if (opcode == OP_COND || opcode == OP_SC Line 6952  if (opcode == OP_COND || opcode == OP_SC
6952          else          else
6953            matchingpath = cc;            matchingpath = cc;
6954          }          }
       }  
     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;  
       }  
6955      }      }
6956    else    else
6957      {      {
# Line 6664  if (bra == OP_BRAMINZERO) Line 7102  if (bra == OP_BRAMINZERO)
7102    }    }
7103    
7104  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
7105    decrease_call_count(common);    count_match(common);
7106    
7107  /* Skip the other alternatives. */  /* Skip the other alternatives. */
7108  while (*cc == OP_ALT)  while (*cc == OP_ALT)
# Line 6951  if (!zero) Line 7389  if (!zero)
7389    
7390  /* None of them matched. */  /* None of them matched. */
7391  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
7392  decrease_call_count(common);  count_match(common);
7393  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
7394  }  }
7395    
7396  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)
7397  {  {
7398  int class_len;  int class_len;
7399    
# Line 6991  else if (*opcode >= OP_TYPESTAR && *opco Line 7429  else if (*opcode >= OP_TYPESTAR && *opco
7429    }    }
7430  else  else
7431    {    {
7432    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
7433    *type = *opcode;    *type = *opcode;
7434    cc++;    cc++;
7435    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 7002  else Line 7440  else
7440      if (end != NULL)      if (end != NULL)
7441        *end = cc + class_len;        *end = cc + class_len;
7442      }      }
7443      else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
7444        {
7445        *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
7446        if (end != NULL)
7447          *end = cc + class_len;
7448        }
7449    else    else
7450      {      {
7451      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
7452      *arg1 = GET2(cc, (class_len + IMM2_SIZE));      *max = GET2(cc, (class_len + IMM2_SIZE));
7453      *arg2 = GET2(cc, class_len);      *min = GET2(cc, class_len);
7454    
7455      if (*arg2 == 0)      if (*min == 0)
7456        {        {
7457        SLJIT_ASSERT(*arg1 != 0);        SLJIT_ASSERT(*max != 0);
7458        *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;        *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO);
7459        }        }
7460      if (*arg1 == *arg2)      if (*max == *min)
7461        *opcode = OP_EXACT;        *opcode = OP_EXACT;
7462    
7463      if (end != NULL)      if (end != NULL)
# Line 7024  else Line 7468  else
7468    
7469  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)
7470    {    {
7471    *arg1 = GET2(cc, 0);    *max = GET2(cc, 0);
7472    cc += IMM2_SIZE;    cc += IMM2_SIZE;
7473    }    }
7474    
# Line 7053  DEFINE_COMPILER; Line 7497  DEFINE_COMPILER;
7497  backtrack_common *backtrack;  backtrack_common *backtrack;
7498  pcre_uchar opcode;  pcre_uchar opcode;
7499  pcre_uchar type;  pcre_uchar type;
7500  int arg1 = -1, arg2 = -1;  int max = -1, min = -1;
7501  pcre_uchar* end;  pcre_uchar* end;
7502  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
7503  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 7066  int tmp_base, tmp_offset; Line 7510  int tmp_base, tmp_offset;
7510    
7511  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
7512    
7513  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end);
7514    
7515  switch(type)  switch(type)
7516    {    {
# Line 7137  switch(opcode) Line 7581  switch(opcode)
7581        {        {
7582        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
7583        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7584        if (opcode == OP_CRRANGE && arg2 > 0)        if (opcode == OP_CRRANGE && min > 0)
7585          CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);          CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
7586        if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))        if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0))
7587          jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);          jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
7588        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
7589        }        }
7590    
# Line 7167  switch(opcode) Line 7611  switch(opcode)
7611      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
7612      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
7613        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
7614      else if (opcode == OP_CRRANGE && arg1 == 0)      else if (opcode == OP_CRRANGE && max == 0)
7615        {        {
7616        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
7617        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 7177  switch(opcode) Line 7621  switch(opcode)
7621        OP1(SLJIT_MOV, TMP1, 0, base, offset1);        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
7622        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7623        OP1(SLJIT_MOV, base, offset1, TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
7624        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label);
7625        }        }
7626      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
7627      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
7628        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));
7629      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
7630      }      }
7631    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
# Line 7219  switch(opcode) Line 7663  switch(opcode)
7663    break;    break;
7664    
7665    case OP_EXACT:    case OP_EXACT:
7666    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
7667    label = LABEL();    label = LABEL();
7668    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
7669    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 7232  switch(opcode) Line 7676  switch(opcode)
7676    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
7677      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
7678    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
7679      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max);
7680    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
7681    label = LABEL();    label = LABEL();
7682    compile_char1_matchingpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
# Line 7256  switch(opcode) Line 7700  switch(opcode)
7700    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
7701    break;    break;
7702    
7703      case OP_CRPOSRANGE:
7704      /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */
7705      OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);
7706      label = LABEL();
7707      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
7708      OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
7709      JUMPTO(SLJIT_C_NOT_ZERO, label);
7710    
7711      if (max != 0)
7712        {
7713        SLJIT_ASSERT(max - min > 0);
7714        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max - min);
7715        }
7716      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
7717      label = LABEL();
7718      compile_char1_matchingpath(common, type, cc, &nomatch);
7719      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
7720      if (max == 0)
7721        JUMPTO(SLJIT_JUMP, label);
7722      else
7723        {
7724        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
7725        JUMPTO(SLJIT_C_NOT_ZERO, label);
7726        }
7727      set_jumps(nomatch, LABEL());
7728      OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
7729      break;
7730    
7731    default:    default:
7732    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
7733    break;    break;
7734    }    }
7735    
7736  decrease_call_count(common);  count_match(common);
7737  return end;  return end;
7738  }  }
7739    
# Line 7533  while (cc < ccend) Line 8005  while (cc < ccend)
8005    
8006      case OP_CLASS:      case OP_CLASS:
8007      case OP_NCLASS:      case OP_NCLASS:
8008      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)
8009        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
8010      else      else
8011        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 7541  while (cc < ccend) Line 8013  while (cc < ccend)
8013    
8014  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
8015      case OP_XCLASS:      case OP_XCLASS:
8016      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)
8017        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
8018      else      else
8019        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 7550  while (cc < ccend) Line 8022  while (cc < ccend)
8022    
8023      case OP_REF:      case OP_REF:
8024      case OP_REFI:      case OP_REFI:
8025      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)
8026          cc = compile_ref_iterator_matchingpath(common, cc, parent);
8027        else
8028          {
8029          compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
8030          cc += 1 + IMM2_SIZE;
8031          }
8032        break;
8033    
8034        case OP_DNREF:
8035        case OP_DNREFI:
8036        if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
8037        cc = compile_ref_iterator_matchingpath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
8038      else      else
8039        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        {
8040          compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
8041          compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
8042          cc += 1 + 2 * IMM2_SIZE;
8043          }
8044      break;      break;
8045    
8046      case OP_RECURSE:      case OP_RECURSE:
# Line 7588  while (cc < ccend) Line 8075  while (cc < ccend)
8075        }        }
8076      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
8077      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
8078        decrease_call_count(common);        count_match(common);
8079      break;      break;
8080    
8081      case OP_ONCE:      case OP_ONCE:
# Line 7706  DEFINE_COMPILER; Line 8193  DEFINE_COMPILER;
8193  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8194  pcre_uchar opcode;  pcre_uchar opcode;
8195  pcre_uchar type;  pcre_uchar type;
8196  int arg1 = -1, arg2 = -1;  int max = -1, min = -1;
8197  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
8198  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
8199  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
# Line 7715  int base = (private_data_ptr == 0) ? SLJ Line 8202  int base = (private_data_ptr == 0) ? SLJ
8202  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
8203  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);
8204    
8205  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL);
8206    
8207  switch(opcode)  switch(opcode)
8208    {    {
# Line 7734  switch(opcode) Line 8221  switch(opcode)
8221    else    else
8222      {      {
8223      if (opcode == OP_UPTO)      if (opcode == OP_UPTO)
8224        arg2 = 0;        min = 0;
8225      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
8226        {        {
8227        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
# Line 7744  switch(opcode) Line 8231  switch(opcode)
8231        {        {
8232        OP1(SLJIT_MOV, TMP1, 0, base, offset1);        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
8233        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
8234        jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);        jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1);
8235        OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
8236        }        }
8237      skip_char_back(common);      skip_char_back(common);
# Line 7789  switch(opcode) Line 8276  switch(opcode)
8276    OP1(SLJIT_MOV, base, offset1, TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
8277    
8278    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
8279      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label);
8280    
8281    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && max == 0)
8282      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
8283    else    else
8284      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);
8285    
8286    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
8287    if (private_data_ptr == 0)    if (private_data_ptr == 0)
# Line 7829  switch(opcode) Line 8316  switch(opcode)
8316    
8317    case OP_EXACT:    case OP_EXACT:
8318    case OP_POSPLUS:    case OP_POSPLUS:
8319      case OP_CRPOSRANGE:
8320    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8321    break;    break;
8322    
# Line 7847  static SLJIT_INLINE void compile_ref_ite Line 8335  static SLJIT_INLINE void compile_ref_ite
8335  {  {
8336  DEFINE_COMPILER;  DEFINE_COMPILER;
8337  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8338    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
8339  pcre_uchar type;  pcre_uchar type;
8340    
8341  type = cc[1 + IMM2_SIZE];  type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
8342    
8343  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
8344    {    {
8345      /* Maximize case. */
8346    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8347    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8348    free_stack(common, 1);    free_stack(common, 1);
# Line 7862  if ((type & 0x1) == 0) Line 8353  if ((type & 0x1) == 0)
8353  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8354  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);
8355  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
8356  free_stack(common, 2);  free_stack(common, ref ? 2 : 3);
8357  }  }
8358    
8359  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 8226  if (has_alternatives) Line 8717  if (has_alternatives)
8717          return;          return;
8718        }        }
8719    
8720      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is successfully matched. */
8721      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8722      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8723        match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);        match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
# Line 8663  while (current) Line 9154  while (current)
9154    
9155      case OP_REF:      case OP_REF:
9156      case OP_REFI:      case OP_REFI:
9157        case OP_DNREF:
9158        case OP_DNREFI:
9159      compile_ref_iterator_backtrackingpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
9160      break;      break;
9161    
# Line 8942  switch(re->options & PCRE_NEWLINE_BITS) Line 9435  switch(re->options & PCRE_NEWLINE_BITS)
9435    case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;    case PCRE_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break;
9436    default: return;    default: return;
9437    }    }
9438    common->nlmax = READ_CHAR_MAX;
9439    common->nlmin = 0;
9440  if ((re->options & PCRE_BSR_ANYCRLF) != 0)  if ((re->options & PCRE_BSR_ANYCRLF) != 0)
9441    common->bsr_nltype = NLTYPE_ANYCRLF;    common->bsr_nltype = NLTYPE_ANYCRLF;
9442  else if ((re->options & PCRE_BSR_UNICODE) != 0)  else if ((re->options & PCRE_BSR_UNICODE) != 0)
# Line 8954  else Line 9449  else
9449    common->bsr_nltype = NLTYPE_ANY;    common->bsr_nltype = NLTYPE_ANY;
9450  #endif  #endif
9451    }    }
9452    common->bsr_nlmax = READ_CHAR_MAX;
9453    common->bsr_nlmin = 0;
9454  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
9455  common->ctypes = (sljit_sw)(tables + ctypes_offset);  common->ctypes = (sljit_sw)(tables + ctypes_offset);
9456  common->digits[0] = -2;  common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
 common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset);  
9457  common->name_count = re->name_count;  common->name_count = re->name_count;
9458  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
9459  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
# Line 8967  common->utf = (re->options & PCRE_UTF8) Line 9463  common->utf = (re->options & PCRE_UTF8)
9463  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
9464  common->use_ucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
9465  #endif  #endif
9466    if (common->utf)
9467      {
9468      if (common->nltype == NLTYPE_ANY)
9469        common->nlmax = 0x2029;
9470      else if (common->nltype == NLTYPE_ANYCRLF)
9471        common->nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
9472      else
9473        {
9474        /* We only care about the first newline character. */
9475        common->nlmax = common->newline & 0xff;
9476        }
9477    
9478      if (common->nltype == NLTYPE_FIXED)
9479        common->nlmin = common->newline & 0xff;
9480      else
9481        common->nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
9482    
9483      if (common->bsr_nltype == NLTYPE_ANY)
9484        common->bsr_nlmax = 0x2029;
9485      else
9486        common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL;
9487      common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL;
9488      }
9489  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
9490  ccend = bracketend(rootbacktrack.cc);  ccend = bracketend(rootbacktrack.cc);
9491    
9492  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
9493  common->ovector_start = CALL_LIMIT + sizeof(sljit_sw);  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
9494  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
9495  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
9496    return;    return;
# Line 9103  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 9622  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
9622  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9623  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
9624  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
9625  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit));  OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
9626  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
9627  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
9628  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0);
9629    
9630  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9631    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
# Line 9130  if ((re->options & PCRE_ANCHORED) == 0) Line 9649  if ((re->options & PCRE_ANCHORED) == 0)
9649      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
9650        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
9651      else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)      else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
9652        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
9653      }      }
9654    }    }
9655  else  else
# Line 9148  if (common->req_char_ptr != 0) Line 9667  if (common->req_char_ptr != 0)
9667  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
9668  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
9669  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9670  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH);
9671  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9672    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
9673    
# Line 9368  if (common->reset_match != NULL) Line 9887  if (common->reset_match != NULL)
9887    JUMPTO(SLJIT_JUMP, reset_match_label);    JUMPTO(SLJIT_JUMP, reset_match_label);
9888    }    }
9889  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9890  #ifndef COMPILE_PCRE32  #ifdef COMPILE_PCRE8
9891  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
9892    {    {
9893    set_jumps(common->utfreadchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
9894    do_utfreadchar(common);    do_utfreadchar(common);
9895    }    }
9896  #endif /* !COMPILE_PCRE32 */  if (common->utfreadchar16 != NULL)
9897  #ifdef COMPILE_PCRE8    {
9898      set_jumps(common->utfreadchar16, LABEL());
9899      do_utfreadchar16(common);
9900      }
9901  if (common->utfreadtype8 != NULL)  if (common->utfreadtype8 != NULL)
9902    {    {
9903    set_jumps(common->utfreadtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
# Line 9426  else Line 9948  else
9948      }      }
9949    memset(functions, 0, sizeof(executable_functions));    memset(functions, 0, sizeof(executable_functions));
9950    functions->top_bracket = (re->top_bracket + 1) * 2;    functions->top_bracket = (re->top_bracket + 1) * 2;
9951      functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0;
9952    extra->executable_jit = functions;    extra->executable_jit = functions;
9953    extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;    extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
9954    }    }
# Line 9480  arguments.begin = subject; Line 10003  arguments.begin = subject;
10003  arguments.end = subject + length;  arguments.end = subject + length;
10004  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
10005  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
10006  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
10007    if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
10008      arguments.limit_match = functions->limit_match;
10009  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
10010  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
10011  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 9571  arguments.begin = subject_ptr; Line 10096  arguments.begin = subject_ptr;
10096  arguments.end = subject_ptr + length;  arguments.end = subject_ptr + length;
10097  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
10098  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
10099  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
10100    if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
10101      arguments.limit_match = functions->limit_match;
10102  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
10103  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
10104  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 9690  if (extra != NULL && Line 10217  if (extra != NULL &&
10217    }    }
10218  }  }
10219    
10220    #if defined COMPILE_PCRE8
10221    PCRE_EXP_DECL void
10222    pcre_jit_free_unused_memory(void)
10223    #elif defined COMPILE_PCRE16
10224    PCRE_EXP_DECL void
10225    pcre16_jit_free_unused_memory(void)
10226    #elif defined COMPILE_PCRE32
10227    PCRE_EXP_DECL void
10228    pcre32_jit_free_unused_memory(void)
10229    #endif
10230    {
10231    sljit_free_unused_memory_exec();
10232    }
10233    
10234  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
10235    
10236  /* 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 9741  pcre32_assign_jit_stack(pcre32_extra *ex Line 10282  pcre32_assign_jit_stack(pcre32_extra *ex
10282  (void)userdata;  (void)userdata;
10283  }  }
10284    
10285    #if defined COMPILE_PCRE8
10286    PCRE_EXP_DECL void
10287    pcre_jit_free_unused_memory(void)
10288    #elif defined COMPILE_PCRE16
10289    PCRE_EXP_DECL void
10290    pcre16_jit_free_unused_memory(void)
10291    #elif defined COMPILE_PCRE32
10292    PCRE_EXP_DECL void
10293    pcre32_jit_free_unused_memory(void)
10294    #endif
10295    {
10296    }
10297    
10298  #endif  #endif
10299    
10300  /* End of pcre_jit_compile.c */  /* End of pcre_jit_compile.c */

Legend:
Removed from v.1310  
changed lines
  Added in v.1426

  ViewVC Help
Powered by ViewVC 1.1.5