/[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 1308 by zherczeg, Tue Apr 2 06:58:55 2013 UTC revision 1422 by zherczeg, Mon Dec 30 19:05:36 2013 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 368  typedef struct compiler_common { Line 369  typedef struct compiler_common {
369    int endonly;    int endonly;
370    /* Tables. */    /* Tables. */
371    sljit_sw ctypes;    sljit_sw ctypes;
   int digits[2 + MAX_RANGE_SIZE];  
372    /* Named capturing brackets. */    /* Named capturing brackets. */
373    sljit_uw name_table;    pcre_uchar *name_table;
374    sljit_sw name_count;    sljit_sw name_count;
375    sljit_sw name_entry_size;    sljit_sw name_entry_size;
376    
# Line 403  typedef struct compiler_common { Line 403  typedef struct compiler_common {
403  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
404    BOOL use_ucp;    BOOL use_ucp;
405  #endif  #endif
 #ifndef COMPILE_PCRE32  
   jump_list *utfreadchar;  
 #endif  
406  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
407      jump_list *utfreadchar;
408      jump_list *utfreadchar16;
409    jump_list *utfreadtype8;    jump_list *utfreadtype8;
410  #endif  #endif
411  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
# Line 463  typedef struct compare_context { Line 462  typedef struct compare_context {
462  #define STACK_TOP     SLJIT_SCRATCH_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
463  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
464  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
465  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define COUNT_MATCH   SLJIT_SAVED_EREG2
466  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
467    
468  /* Local space layout. */  /* Local space layout. */
# Line 474  typedef struct compare_context { Line 473  typedef struct compare_context {
473  #define POSSESSIVE0      (2 * sizeof(sljit_sw))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
474  #define POSSESSIVE1      (3 * sizeof(sljit_sw))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
475  /* Max limit of recursions. */  /* Max limit of recursions. */
476  #define CALL_LIMIT       (4 * sizeof(sljit_sw))  #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
477  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
478  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
479  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
480  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. */
481  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
482  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
483  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
484  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
485    
486  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 532  cc += 1 + LINK_SIZE; Line 531  cc += 1 + LINK_SIZE;
531  return cc;  return cc;
532  }  }
533    
534    static int ones_in_half_byte[16] = {
535      /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
536      /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
537    };
538    
539  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
540   next_opcode   next_opcode
541   check_opcode_types   check_opcode_types
# Line 584  switch(*cc) Line 588  switch(*cc)
588    case OP_CRMINQUERY:    case OP_CRMINQUERY:
589    case OP_CRRANGE:    case OP_CRRANGE:
590    case OP_CRMINRANGE:    case OP_CRMINRANGE:
591      case OP_CRPOSSTAR:
592      case OP_CRPOSPLUS:
593      case OP_CRPOSQUERY:
594      case OP_CRPOSRANGE:
595    case OP_CLASS:    case OP_CLASS:
596    case OP_NCLASS:    case OP_NCLASS:
597    case OP_REF:    case OP_REF:
598    case OP_REFI:    case OP_REFI:
599      case OP_DNREF:
600      case OP_DNREFI:
601    case OP_RECURSE:    case OP_RECURSE:
602    case OP_CALLOUT:    case OP_CALLOUT:
603    case OP_ALT:    case OP_ALT:
# Line 613  switch(*cc) Line 623  switch(*cc)
623    case OP_SCBRAPOS:    case OP_SCBRAPOS:
624    case OP_SCOND:    case OP_SCOND:
625    case OP_CREF:    case OP_CREF:
626    case OP_NCREF:    case OP_DNCREF:
627    case OP_RREF:    case OP_RREF:
628    case OP_NRREF:    case OP_DNRREF:
629    case OP_DEF:    case OP_DEF:
630    case OP_BRAZERO:    case OP_BRAZERO:
631    case OP_BRAMINZERO:    case OP_BRAMINZERO:
# Line 735  switch(*cc) Line 745  switch(*cc)
745    
746  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)
747  {  {
748  pcre_uchar *name;  int count;
749  pcre_uchar *name2;  pcre_uchar *slot;
 int i, cbra_index;  
750    
751  /* 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. */
752  while (cc < ccend)  while (cc < ccend)
# Line 771  while (cc < ccend) Line 780  while (cc < ccend)
780      break;      break;
781    
782      case OP_CREF:      case OP_CREF:
783      i = GET2(cc, 1);      common->optimized_cbracket[GET2(cc, 1)] = 0;
     common->optimized_cbracket[i] = 0;  
784      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
785      break;      break;
786    
787      case OP_NCREF:      case OP_DNREF:
788      cbra_index = GET2(cc, 1);      case OP_DNREFI:
789      name = (pcre_uchar *)common->name_table;      case OP_DNCREF:
790      name2 = name;      count = GET2(cc, 1 + IMM2_SIZE);
791      for (i = 0; i < common->name_count; i++)      slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
792        {      while (count-- > 0)
793        if (GET2(name, 0) == cbra_index) break;        {
794        name += common->name_entry_size;        common->optimized_cbracket[GET2(slot, 0)] = 0;
795        }        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;  
796        }        }
797      cc += 1 + IMM2_SIZE;      cc += 1 + 2 * IMM2_SIZE;
798      break;      break;
799    
800      case OP_RECURSE:      case OP_RECURSE:
# Line 892  pcre_uchar *next; Line 893  pcre_uchar *next;
893  pcre_uchar *next_end;  pcre_uchar *next_end;
894  pcre_uchar *max_end;  pcre_uchar *max_end;
895  pcre_uchar type;  pcre_uchar type;
896  sljit_uw length = end - begin;  sljit_sw length = end - begin;
897  int min, max, i;  int min, max, i;
898    
899  /* Detect fixed iterations first. */  /* Detect fixed iterations first. */
# Line 2021  while (list_item) Line 2022  while (list_item)
2022  common->stubs = NULL;  common->stubs = NULL;
2023  }  }
2024    
2025  static SLJIT_INLINE void decrease_call_count(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2026  {  {
2027  DEFINE_COMPILER;  DEFINE_COMPILER;
2028    
2029  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);
2030  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
2031  }  }
2032    
# Line 2372  return (bit < 256) ? ((0 << 8) | bit) : Line 2373  return (bit < 256) ? ((0 << 8) | bit) :
2373    
2374  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
2375  {  {
2376  /* Checks whether a partial matching is occured. Does not modify registers. */  /* Checks whether a partial matching is occurred. Does not modify registers. */
2377  DEFINE_COMPILER;  DEFINE_COMPILER;
2378  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2379    
# Line 2459  else Line 2460  else
2460  JUMPHERE(jump);  JUMPHERE(jump);
2461  }  }
2462    
2463  static void read_char(compiler_common *common)  static void peek_char(compiler_common *common)
2464  {  {
2465  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2466  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2467  DEFINE_COMPILER;  DEFINE_COMPILER;
2468  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
# Line 2469  struct sljit_jump *jump; Line 2470  struct sljit_jump *jump;
2470  #endif  #endif
2471    
2472  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2473  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2474  if (common->utf)  if (common->utf)
2475    {    {
 #if defined COMPILE_PCRE8  
2476    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2477  #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] */  
2478    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2479      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2480    JUMPHERE(jump);    JUMPHERE(jump);
2481    }    }
2482  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2483    
2484    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2485    if (common->utf)
2486      {
2487      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2488      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2489      /* TMP2 contains the high surrogate. */
2490      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2491      OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2492      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2493      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2494      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2495      JUMPHERE(jump);
2496      }
2497    #endif
2498    }
2499    
2500    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2501    
2502    static BOOL is_char7_bitset(const pcre_uint8* bitset, BOOL nclass)
2503    {
2504    /* Tells whether the character codes below 128 are enough
2505    to determine a match. */
2506    const pcre_uint8 value = nclass ? 0xff : 0;
2507    const pcre_uint8* end = bitset + 32;
2508    
2509    bitset += 16;
2510    do
2511      {
2512      if (*bitset++ != value)
2513        return FALSE;
2514      }
2515    while (bitset < end);
2516    return TRUE;
2517    }
2518    
2519    static void read_char7_type(compiler_common *common, BOOL full_read)
2520    {
2521    /* Reads the precise character type of a character into TMP1, if the character
2522    is less than 128. Otherwise it returns with zero. Does not check STR_END. The
2523    full_read argument tells whether characters above max are accepted or not. */
2524    DEFINE_COMPILER;
2525    struct sljit_jump *jump;
2526    
2527    SLJIT_ASSERT(common->utf);
2528    
2529    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2530  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));
2531    
2532    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2533    
2534    if (full_read)
2535      {
2536      jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2537      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2538      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2539      JUMPHERE(jump);
2540      }
2541  }  }
2542    
2543  static void peek_char(compiler_common *common)  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2544    
2545    static void read_char_max(compiler_common *common, pcre_uint32 max, BOOL full_read)
2546  {  {
2547  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the precise value of a character into TMP1, if the character is
2548  Does not check STR_END. TMP2 Destroyed. */  less than or equal to max. Otherwise it returns with a value greater than max.
2549    Does not check STR_END. The full_read argument tells whether characters above
2550    max are accepted or not. */
2551  DEFINE_COMPILER;  DEFINE_COMPILER;
2552  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2553  struct sljit_jump *jump;  struct sljit_jump *jump;
2554  #endif  #endif
2555    
2556    SLJIT_UNUSED_ARG(full_read);
2557    SLJIT_UNUSED_ARG(max);
2558    
2559  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2560  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2561    
2562    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2563  if (common->utf)  if (common->utf)
2564    {    {
2565  #if defined COMPILE_PCRE8    if (max < 128 && !full_read)
2566        return;
2567    
2568    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2569  #elif defined COMPILE_PCRE16    if (max >= 0x800)
2570    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2571  #endif /* COMPILE_PCRE[8|16] */    else if (max < 128)
2572    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));      {
2573    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);
2574        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2575        }
2576      else
2577        {
2578        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2579        if (!full_read)
2580          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2581        else
2582          OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2583        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2584        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2585        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2586        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2587        if (full_read)
2588          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2589        }
2590    JUMPHERE(jump);    JUMPHERE(jump);
2591    }    }
2592  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif
2593    
2594    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2595    if (common->utf)
2596      {
2597      if (max >= 0x10000)
2598        {
2599        OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2600        jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2601        /* TMP2 contains the high surrogate. */
2602        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2603        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40);
2604        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10);
2605        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2606        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2607        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2608        JUMPHERE(jump);
2609        return;
2610        }
2611    
2612      if (max < 0xd800 && !full_read)
2613        return;
2614    
2615      /* Skip low surrogate if necessary. */
2616      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2617      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2618      if (full_read)
2619        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2620      if (max >= 0xd800)
2621        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
2622      JUMPHERE(jump);
2623      }
2624    #endif
2625    }
2626    
2627    static SLJIT_INLINE void read_char(compiler_common *common)
2628    {
2629    read_char_max(common, 0x7fffffff, TRUE);
2630  }  }
2631    
2632  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common, BOOL full_read)
2633  {  {
2634  /* 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.
2635    The full_read argument tells whether characters above max are accepted or not. */
2636  DEFINE_COMPILER;  DEFINE_COMPILER;
2637  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2638  struct sljit_jump *jump;  struct sljit_jump *jump;
2639  #endif  #endif
2640    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2641    struct sljit_jump *jump2;
2642    #endif
2643    
2644  #ifdef SUPPORT_UTF  SLJIT_UNUSED_ARG(full_read);
2645    
2646    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2647    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2648    
2649    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2650  if (common->utf)  if (common->utf)
2651    {    {
   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  
2652    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2653    it is needed in most cases. */    it is needed in most cases. */
2654    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2655    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2656    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    if (!full_read)
2657    JUMPHERE(jump);      {
2658  #elif defined COMPILE_PCRE16      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2659    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2660    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2661    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2662    JUMPHERE(jump);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2663    /* Skip low surrogate if necessary. */      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
2664    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2665    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);      jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2666    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2667    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      JUMPHERE(jump2);
2668    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);      }
2669  #elif defined COMPILE_PCRE32    else
2670    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);  
2671    JUMPHERE(jump);    JUMPHERE(jump);
 #endif /* COMPILE_PCRE[8|16|32] */  
2672    return;    return;
2673    }    }
2674  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2675  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
2676  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  
2677  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2678  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2679  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2680  #endif  #endif
2681  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2682  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if !defined COMPILE_PCRE8
2683  JUMPHERE(jump);  JUMPHERE(jump);
2684  #endif  #endif
2685    
2686    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2687    if (common->utf && full_read)
2688      {
2689      /* Skip low surrogate if necessary. */
2690      OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2691      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2692      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2693      JUMPHERE(jump);
2694      }
2695    #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
2696  }  }
2697    
2698  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
# Line 2628  else Line 2761  else
2761  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2762  {  {
2763  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2764  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. */
2765  DEFINE_COMPILER;  DEFINE_COMPILER;
2766  struct sljit_jump *jump;  struct sljit_jump *jump;
2767    
2768  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2769    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2770    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2771    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2772    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2773    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2774    
2775  /* Searching for the first zero. */  /* Searching for the first zero. */
2776  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);
2777  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2778  /* Two byte sequence. */  /* Two byte sequence. */
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
2779  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));
2780  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2781    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2782    
2783    JUMPHERE(jump);
2784    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2785    OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2786  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2787  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2788  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);  
2789    
2790  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);
2791  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2792  /* 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));  
2793  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));
2794  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));  
2795  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2796    
2797  /* Four byte sequence. */  /* Four byte sequence. */
2798  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  JUMPHERE(jump);
2799  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2800  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2801    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2802    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2803  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);  
2804  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2805  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
2806    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2807    }
2808    
2809    static void do_utfreadchar16(compiler_common *common)
2810    {
2811    /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2812    of the character (>= 0xc0). Return value in TMP1. */
2813    DEFINE_COMPILER;
2814    struct sljit_jump *jump;
2815    
2816    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2817    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2818    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2819    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
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, 6);  
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(3));  
2823  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));  /* Searching for the first zero. */
2824    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800);
2825    jump = JUMP(SLJIT_C_NOT_ZERO);
2826    /* Two byte sequence. */
2827    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2828    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2829    
2830    JUMPHERE(jump);
2831    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2832    OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2833    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2834  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2835  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2836  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));  /* Three byte sequence. */
2837    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2838  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2839  }  }
2840    
# Line 2699  jump = JUMP(SLJIT_C_NOT_ZERO); Line 2854  jump = JUMP(SLJIT_C_NOT_ZERO);
2854  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2855  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));
2856  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2857    /* The upper 5 bits are known at this point. */
2858    compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
2859  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2860  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2861  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);  
2862  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2863  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2864    
2865  JUMPHERE(compare);  JUMPHERE(compare);
2866  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2867  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2868    
2869  /* 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);  
   
2870  JUMPHERE(jump);  JUMPHERE(jump);
2871  /* Combine two 16 bit characters. */  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2872  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2873  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);  
2874  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2875  }  }
2876    
2877  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE8 */
2878    
2879  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2880    
# Line 2896  if (newlinecheck) Line 3025  if (newlinecheck)
3025  return mainloop;  return mainloop;
3026  }  }
3027    
3028  #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)  
3029  {  {
3030  DEFINE_COMPILER;  /* Recursive function, which scans prefix literals. */
3031  struct sljit_label *start;  int len, repeat, len_save, consumed = 0;
3032  struct sljit_jump *quit;  pcre_uint32 caseless, chr, mask;
3033  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uchar *alternative, *cc_save;
3034  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;  
3035    
3036    repeat = 1;
3037  while (TRUE)  while (TRUE)
3038    {    {
3039      last = TRUE;
3040      any = FALSE;
3041    caseless = 0;    caseless = 0;
3042    must_stop = 1;    switch (*cc)
   switch(*cc)  
3043      {      {
     case OP_CHAR:  
     must_stop = 0;  
     cc++;  
     break;  
   
3044      case OP_CHARI:      case OP_CHARI:
3045      caseless = 1;      caseless = 1;
3046      must_stop = 0;      case OP_CHAR:
3047        last = FALSE;
3048      cc++;      cc++;
3049      break;      break;
3050    
# Line 2951  while (TRUE) Line 3069  while (TRUE)
3069      cc++;      cc++;
3070      break;      break;
3071    
3072        case OP_EXACTI:
3073        caseless = 1;
3074      case OP_EXACT:      case OP_EXACT:
3075        repeat = GET2(cc, 1);
3076        last = FALSE;
3077      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
3078      break;      break;
3079    
# Line 2962  while (TRUE) Line 3084  while (TRUE)
3084      cc++;      cc++;
3085      break;      break;
3086    
3087      case OP_EXACTI:      case OP_KET:
3088      caseless = 1;      cc += 1 + LINK_SIZE;
3089      cc += 1 + IMM2_SIZE;      continue;
     break;  
3090    
3091      default:      case OP_ALT:
3092      must_stop = 2;      cc += GET(cc, 1);
3093      break;      continue;
     }  
3094    
3095    if (must_stop == 2)      case OP_ONCE:
3096        break;      case OP_ONCE_NC:
3097        case OP_BRA:
3098        case OP_BRAPOS:
3099        case OP_CBRA:
3100        case OP_CBRAPOS:
3101        alternative = cc + GET(cc, 1);
3102        while (*alternative == OP_ALT)
3103          {
3104          max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars);
3105          if (max_chars == 0)
3106            return consumed;
3107          alternative += GET(alternative, 1);
3108          }
3109    
3110    len = 1;      if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3111  #ifdef SUPPORT_UTF        cc += IMM2_SIZE;
3112    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);      cc += 1 + LINK_SIZE;
3113  #endif      continue;
3114    
3115    if (caseless && char_has_othercase(common, cc))      case OP_CLASS:
3116      {      case OP_NCLASS:
3117        any = TRUE;
3118        cc += 1 + 32 / sizeof(pcre_uchar);
3119        break;
3120    
3121    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3122        case OP_XCLASS:
3123        any = TRUE;
3124        cc += GET(cc, 1);
3125        break;
3126    #endif
3127    
3128        case OP_NOT_DIGIT:
3129        case OP_DIGIT:
3130        case OP_NOT_WHITESPACE:
3131        case OP_WHITESPACE:
3132        case OP_NOT_WORDCHAR:
3133        case OP_WORDCHAR:
3134        case OP_ANY:
3135        case OP_ALLANY:
3136        any = TRUE;
3137        cc++;
3138        break;
3139    
3140    #ifdef SUPPORT_UCP
3141        case OP_NOTPROP:
3142        case OP_PROP:
3143        any = TRUE;
3144        cc += 1 + 2;
3145        break;
3146    #endif
3147    
3148        case OP_TYPEEXACT:
3149        repeat = GET2(cc, 1);
3150        cc += 1 + IMM2_SIZE;
3151        continue;
3152    
3153        default:
3154        return consumed;
3155        }
3156    
3157      if (any)
3158        {
3159    #ifdef SUPPORT_UTF
3160        if (common->utf) return consumed;
3161    #endif
3162    #if defined COMPILE_PCRE8
3163        mask = 0xff;
3164    #elif defined COMPILE_PCRE16
3165        mask = 0xffff;
3166    #elif defined COMPILE_PCRE32
3167        mask = 0xffffffff;
3168    #else
3169        SLJIT_ASSERT_STOP();
3170    #endif
3171    
3172        do
3173          {
3174          chars[0] = mask;
3175          chars[1] = mask;
3176    
3177          if (--max_chars == 0)
3178            return consumed;
3179          consumed++;
3180          chars += 2;
3181          }
3182        while (--repeat > 0);
3183    
3184        repeat = 1;
3185        continue;
3186        }
3187    
3188      len = 1;
3189    #ifdef SUPPORT_UTF
3190      if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3191    #endif
3192    
3193      if (caseless != 0 && char_has_othercase(common, cc))
3194        {
3195      caseless = char_get_othercase_bit(common, cc);      caseless = char_get_othercase_bit(common, cc);
3196      if (caseless == 0)      if (caseless == 0)
3197        return FALSE;        return consumed;
3198  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3199      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
3200  #else  #else
# Line 2997  while (TRUE) Line 3207  while (TRUE)
3207    else    else
3208      caseless = 0;      caseless = 0;
3209    
3210    while (len > 0 && location < MAX_N_CHARS * 2)    len_save = len;
3211      {    cc_save = cc;
3212      c = *cc;    while (TRUE)
3213      bit = 0;      {
3214      if (len == (caseless & 0xff))      do
3215        {        {
3216        bit = caseless >> 8;        chr = *cc;
3217        c |= bit;  #ifdef COMPILE_PCRE32
3218          if (SLJIT_UNLIKELY(chr == NOTACHAR))
3219            return consumed;
3220    #endif
3221          mask = 0;
3222          if (len == (caseless & 0xff))
3223            {
3224            mask = caseless >> 8;
3225            chr |= mask;
3226            }
3227    
3228          if (chars[0] == NOTACHAR)
3229            {
3230            chars[0] = chr;
3231            chars[1] = mask;
3232            }
3233          else
3234            {
3235            mask |= chars[0] ^ chr;
3236            chr |= mask;
3237            chars[0] = chr;
3238            chars[1] |= mask;
3239            }
3240    
3241          len--;
3242          if (--max_chars == 0)
3243            return consumed;
3244          consumed++;
3245          chars += 2;
3246          cc++;
3247        }        }
3248        while (len > 0);
3249    
3250      chars[location] = c;      if (--repeat == 0)
3251      chars[location + 1] = bit;        break;
3252    
3253      len--;      len = len_save;
3254      location += 2;      cc = cc_save;
3255      cc++;      }
3256    
3257      repeat = 1;
3258      if (last)
3259        return consumed;
3260      }
3261    }
3262    
3263    #define MAX_N_CHARS 16
3264    
3265    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
3266    {
3267    DEFINE_COMPILER;
3268    struct sljit_label *start;
3269    struct sljit_jump *quit;
3270    pcre_uint32 chars[MAX_N_CHARS * 2];
3271    pcre_uint8 ones[MAX_N_CHARS];
3272    pcre_uint32 mask;
3273    int i, max;
3274    int offsets[3];
3275    
3276    for (i = 0; i < MAX_N_CHARS; i++)
3277      {
3278      chars[i << 1] = NOTACHAR;
3279      chars[(i << 1) + 1] = 0;
3280      }
3281    
3282    max = scan_prefix(common, common->start, chars, MAX_N_CHARS);
3283    
3284    if (max <= 1)
3285      return FALSE;
3286    
3287    for (i = 0; i < max; i++)
3288      {
3289      mask = chars[(i << 1) + 1];
3290      ones[i] = ones_in_half_byte[mask & 0xf];
3291      mask >>= 4;
3292      while (mask != 0)
3293        {
3294        ones[i] += ones_in_half_byte[mask & 0xf];
3295        mask >>= 4;
3296      }      }
3297      }
3298    
3299    if (location >= MAX_N_CHARS * 2 || must_stop != 0)  offsets[0] = -1;
3300    /* Scan forward. */
3301    for (i = 0; i < max; i++)
3302      if (ones[i] <= 2) {
3303        offsets[0] = i;
3304      break;      break;
3305    }    }
3306    
3307  /* At least two characters are required. */  if (offsets[0] == -1)
3308  if (location < 2 * 2)    return FALSE;
3309      return FALSE;  
3310    /* Scan backward. */
3311    offsets[1] = -1;
3312    for (i = max - 1; i > offsets[0]; i--)
3313      if (ones[i] <= 2) {
3314        offsets[1] = i;
3315        break;
3316      }
3317    
3318    offsets[2] = -1;
3319    if (offsets[1] >= 0)
3320      {
3321      /* Scan from middle. */
3322      for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
3323        if (ones[i] <= 2)
3324          {
3325          offsets[2] = i;
3326          break;
3327          }
3328    
3329      if (offsets[2] == -1)
3330        {
3331        for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)
3332          if (ones[i] <= 2)
3333            {
3334            offsets[2] = i;
3335            break;
3336            }
3337        }
3338      }
3339    
3340    SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));
3341    SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
3342    
3343    chars[0] = chars[offsets[0] << 1];
3344    chars[1] = chars[(offsets[0] << 1) + 1];
3345    if (offsets[2] >= 0)
3346      {
3347      chars[2] = chars[offsets[2] << 1];
3348      chars[3] = chars[(offsets[2] << 1) + 1];
3349      }
3350    if (offsets[1] >= 0)
3351      {
3352      chars[4] = chars[offsets[1] << 1];
3353      chars[5] = chars[(offsets[1] << 1) + 1];
3354      }
3355    
3356    max -= 1;
3357  if (firstline)  if (firstline)
3358    {    {
3359    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3360    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3361    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));
3362    }    }
3363  else  else
3364    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));
3365    
3366  start = LABEL();  start = LABEL();
3367  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3368    
3369  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]));
3370  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  if (offsets[1] >= 0)
3371      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
3372  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));
3373    
3374  if (chars[1] != 0)  if (chars[1] != 0)
3375    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3376  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3377  if (location > 2 * 2)  if (offsets[2] >= 0)
3378    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));
3379  if (chars[3] != 0)  
3380    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)  
3381    {    {
3382    if (chars[5] != 0)    if (chars[5] != 0)
3383      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
3384    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);
3385      }
3386    
3387    if (offsets[2] >= 0)
3388      {
3389      if (chars[3] != 0)
3390        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);
3391      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);
3392    }    }
3393  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));
3394    
# Line 3059  JUMPHERE(quit); Line 3397  JUMPHERE(quit);
3397  if (firstline)  if (firstline)
3398    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3399  else  else
3400    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));
3401  return TRUE;  return TRUE;
3402  }  }
3403    
# Line 3208  if (firstline) Line 3546  if (firstline)
3546    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3547  }  }
3548    
3549  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);
3550    
3551  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)
3552  {  {
3553  DEFINE_COMPILER;  DEFINE_COMPILER;
3554  struct sljit_label *start;  struct sljit_label *start;
3555  struct sljit_jump *quit;  struct sljit_jump *quit;
3556  struct sljit_jump *found = NULL;  struct sljit_jump *found = NULL;
3557  jump_list *matches = NULL;  jump_list *matches = NULL;
 pcre_uint8 inverted_start_bits[32];  
 int i;  
3558  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3559  struct sljit_jump *jump;  struct sljit_jump *jump;
3560  #endif  #endif
3561    
 for (i = 0; i < 32; ++i)  
   inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);  
   
3562  if (firstline)  if (firstline)
3563    {    {
3564    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 3241  if (common->utf) Line 3574  if (common->utf)
3574    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3575  #endif  #endif
3576    
3577  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))
3578    {    {
3579  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3580    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
# Line 3250  if (!check_class_ranges(common, inverted Line 3583  if (!check_class_ranges(common, inverted
3583  #endif  #endif
3584    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3585    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3586    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
3587    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3588    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);
3589    found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
# Line 3499  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3832  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3832  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3833  }  }
3834    
3835  /*  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)  
3836  {  {
3837  DEFINE_COMPILER;  DEFINE_COMPILER;
3838  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];  
3839  pcre_uint8 bit, cbit, all;  pcre_uint8 bit, cbit, all;
3840  int i, byte, length = 0;  int i, byte, length = 0;
3841    
3842  bit = bits[0] & 0x1;  bit = bits[0] & 0x1;
3843  ranges[1] = bit;  /* All bits will be zero or one (since bit is zero or one). */
 /* Can be 0 or 255. */  
3844  all = -bit;  all = -bit;
3845    
3846  for (i = 0; i < 256; )  for (i = 0; i < 256; )
# Line 3617  for (i = 0; i < 256; ) Line 3855  for (i = 0; i < 256; )
3855        {        {
3856        if (length >= MAX_RANGE_SIZE)        if (length >= MAX_RANGE_SIZE)
3857          return FALSE;          return FALSE;
3858        ranges[2 + length] = i;        ranges[length] = i;
3859        length++;        length++;
3860        bit = cbit;        bit = cbit;
3861        all = -cbit;        all = -cbit;
# Line 3630  if (((bit == 0) && nclass) || ((bit == 1 Line 3868  if (((bit == 0) && nclass) || ((bit == 1
3868    {    {
3869    if (length >= MAX_RANGE_SIZE)    if (length >= MAX_RANGE_SIZE)
3870      return FALSE;      return FALSE;
3871    ranges[2 + length] = 256;    ranges[length] = 256;
3872    length++;    length++;
3873    }    }
 ranges[0] = length;  
3874    
3875  return check_ranges(common, ranges, backtracks, FALSE);  if (length < 0 || length > 4)
3876      return FALSE;
3877    
3878    bit = bits[0] & 0x1;
3879    if (invert) bit ^= 0x1;
3880    
3881    /* No character is accepted. */
3882    if (length == 0 && bit == 0)
3883      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3884    
3885    switch(length)
3886      {
3887      case 0:
3888      /* When bit != 0, all characters are accepted. */
3889      return TRUE;
3890    
3891      case 1:
3892      add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3893      return TRUE;
3894    
3895      case 2:
3896      if (ranges[0] + 1 != ranges[1])
3897        {
3898        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3899        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3900        }
3901      else
3902        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3903      return TRUE;
3904    
3905      case 3:
3906      if (bit != 0)
3907        {
3908        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3909        if (ranges[0] + 1 != ranges[1])
3910          {
3911          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3912          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3913          }
3914        else
3915          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3916        return TRUE;
3917        }
3918    
3919      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
3920      if (ranges[1] + 1 != ranges[2])
3921        {
3922        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
3923        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
3924        }
3925      else
3926        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
3927      return TRUE;
3928    
3929      case 4:
3930      if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
3931          && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
3932          && is_powerof2(ranges[2] - ranges[0]))
3933        {
3934        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
3935        if (ranges[2] + 1 != ranges[3])
3936          {
3937          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3938          add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3939          }
3940        else
3941          add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3942        return TRUE;
3943        }
3944    
3945      if (bit != 0)
3946        {
3947        i = 0;
3948        if (ranges[0] + 1 != ranges[1])
3949          {
3950          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3951          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3952          i = ranges[0];
3953          }
3954        else
3955          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3956    
3957        if (ranges[2] + 1 != ranges[3])
3958          {
3959          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
3960          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3961          }
3962        else
3963          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
3964        return TRUE;
3965        }
3966    
3967      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3968      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
3969      if (ranges[1] + 1 != ranges[2])
3970        {
3971        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
3972        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
3973        }
3974      else
3975        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3976      return TRUE;
3977    
3978      default:
3979      SLJIT_ASSERT_STOP();
3980      return FALSE;
3981      }
3982  }  }
3983    
3984  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 4023  static void compile_xclass_matchingpath( Line 4366  static void compile_xclass_matchingpath(
4366  {  {
4367  DEFINE_COMPILER;  DEFINE_COMPILER;
4368  jump_list *found = NULL;  jump_list *found = NULL;
4369  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
4370  pcre_int32 c, charoffset;  pcre_int32 c, charoffset;
 const pcre_uint32 *other_cases;  
4371  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4372  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4373  int compares, invertcmp, numberofcmps;  int compares, invertcmp, numberofcmps;
4374    
4375  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4376  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
4377  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
4378  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
4379    const pcre_uint32 *other_cases;
4380  pcre_int32 typeoffset;  pcre_int32 typeoffset;
4381  #endif  #endif
4382    
# Line 4041  pcre_int32 typeoffset; Line 4385  pcre_int32 typeoffset;
4385  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
4386  read_char(common);  read_char(common);
4387    
4388  if ((*cc++ & XCL_MAP) != 0)  cc++;
4389    if ((cc[-1] & XCL_HASPROP) == 0)
4390    {    {
4391    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    if ((cc[-1] & XCL_MAP) != 0)
4392  #ifndef COMPILE_PCRE8      {
4393    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4394  #elif defined SUPPORT_UTF  #ifdef SUPPORT_UCP
4395    if (common->utf)      charsaved = TRUE;
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
4396  #endif  #endif
4397        if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, FALSE, backtracks))
4398          {
4399          jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4400    
4401          OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4402          OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4403          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4404          OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4405          OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4406          add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));
4407          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4408    
4409          JUMPHERE(jump);
4410          }
4411        else
4412          add_jump(compiler, &found, CMP(SLJIT_C_LESS_EQUAL, TMP3, 0, SLJIT_IMM, 0xff));
4413    
4414    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
4415        cc += 32 / sizeof(pcre_uchar);
4416        }
4417      else
4418        add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff));
4419      }
4420    else if ((cc[-1] & XCL_MAP) != 0)
4421      {
4422      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4423    #ifdef SUPPORT_UCP
4424      charsaved = TRUE;
4425    #endif
4426      if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
4427      {      {
4428    #ifdef COMPILE_PCRE8
4429        SLJIT_ASSERT(common->utf);
4430    #endif
4431        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4432    
4433      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4434      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4435      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4436      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4437      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);
4438      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
     }  
4439    
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (common->utf)  
4440      JUMPHERE(jump);      JUMPHERE(jump);
4441  #endif      }
4442    
4443    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
 #ifdef SUPPORT_UCP  
   charsaved = TRUE;  
 #endif  
4444    cc += 32 / sizeof(pcre_uchar);    cc += 32 / sizeof(pcre_uchar);
4445    }    }
4446    
# Line 4128  while (*cc != XCL_END) Line 4498  while (*cc != XCL_END)
4498        case PT_SPACE:        case PT_SPACE:
4499        case PT_PXSPACE:        case PT_PXSPACE:
4500        case PT_WORD:        case PT_WORD:
4501          case PT_PXGRAPH:
4502          case PT_PXPRINT:
4503          case PT_PXPUNCT:
4504        needstype = TRUE;        needstype = TRUE;
4505        needschar = TRUE;        needschar = TRUE;
4506        break;        break;
# Line 4315  while (*cc != XCL_END) Line 4688  while (*cc != XCL_END)
4688    
4689        case PT_SPACE:        case PT_SPACE:
4690        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);  
         }  
4691        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4692        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);
4693        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);
4694        if (*cc == PT_SPACE)  
4695          JUMPHERE(jump);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
4696          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4697    
4698          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
4699          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4700    
4701        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4702        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 4400  while (*cc != XCL_END) Line 4772  while (*cc != XCL_END)
4772        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4773        break;        break;
4774    
4775        case PT_UCNC:        case PT_UCNC:
4776        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, CHAR_DOLLAR_SIGN - charoffset);
4777        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4778        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, CHAR_COMMERCIAL_AT - charoffset);
4779        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4780        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, CHAR_GRAVE_ACCENT - charoffset);
4781          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4782    
4783          SET_CHAR_OFFSET(0xa0);
4784          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4785          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4786          SET_CHAR_OFFSET(0);
4787          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4788          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4789          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4790          break;
4791    
4792          case PT_PXGRAPH:
4793          /* C and Z groups are the farthest two groups. */
4794          SET_TYPE_OFFSET(ucp_Ll);
4795          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
4796          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
4797    
4798          jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
4799    
4800          /* In case of ucp_Cf, we overwrite the result. */
4801          SET_CHAR_OFFSET(0x2066);
4802          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
4803          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4804    
4805          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
4806          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4807    
4808          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
4809          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4810    
4811          JUMPHERE(jump);
4812          jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4813          break;
4814    
4815          case PT_PXPRINT:
4816          /* C and Z groups are the farthest two groups. */
4817          SET_TYPE_OFFSET(ucp_Ll);
4818          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
4819          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
4820    
4821          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
4822          OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4823    
4824          jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
4825    
4826          /* In case of ucp_Cf, we overwrite the result. */
4827          SET_CHAR_OFFSET(0x2066);
4828          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
4829          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4830    
4831          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
4832        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4833    
4834        SET_CHAR_OFFSET(0xa0);        JUMPHERE(jump);
4835        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);        jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4836        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);        break;
4837    
4838          case PT_PXPUNCT:
4839          SET_TYPE_OFFSET(ucp_Sc);
4840          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
4841          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4842    
4843        SET_CHAR_OFFSET(0);        SET_CHAR_OFFSET(0);
4844        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);
4845        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);
4846    
4847          SET_TYPE_OFFSET(ucp_Pc);
4848          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
4849          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4850        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4851        break;        break;
4852        }        }
# Line 4447  struct sljit_label *label; Line 4880  struct sljit_label *label;
4880  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4881  pcre_uchar propdata[5];  pcre_uchar propdata[5];
4882  #endif  #endif
4883  #endif  #endif /* SUPPORT_UTF */
4884    
4885  switch(type)  switch(type)
4886    {    {
# Line 4472  switch(type) Line 4905  switch(type)
4905    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4906    case OP_DIGIT:    case OP_DIGIT:
4907    /* 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);  
4908    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4909    /* Flip the starting bit in the negative case. */  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4910    if (type == OP_NOT_DIGIT)    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))
4911      common->digits[1] ^= 1;      read_char7_type(common, type == OP_NOT_DIGIT);
4912    if (!check_ranges(common, common->digits, backtracks, TRUE))    else
4913      {  #endif
4914      read_char8_type(common);      read_char8_type(common, type == OP_NOT_DIGIT);
4915      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      /* Flip the starting bit in the negative case. */
4916      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);
4917      }    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
   if (type == OP_NOT_DIGIT)  
     common->digits[1] ^= 1;  
4918    return cc;    return cc;
4919    
4920    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4921    case OP_WHITESPACE:    case OP_WHITESPACE:
4922    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4923    read_char8_type(common);  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4924      if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))
4925        read_char7_type(common, type == OP_NOT_WHITESPACE);
4926      else
4927    #endif
4928        read_char8_type(common, type == OP_NOT_WHITESPACE);
4929    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);
4930    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));
4931    return cc;    return cc;
# Line 4499  switch(type) Line 4933  switch(type)
4933    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4934    case OP_WORDCHAR:    case OP_WORDCHAR:
4935    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4936    read_char8_type(common);  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4937      if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))
4938        read_char7_type(common, type == OP_NOT_WORDCHAR);
4939      else
4940    #endif
4941        read_char8_type(common, type == OP_NOT_WORDCHAR);
4942    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);
4943    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));
4944    return cc;    return cc;
# Line 4562  switch(type) Line 5001  switch(type)
5001  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
5002    case OP_NOTPROP:    case OP_NOTPROP:
5003    case OP_PROP:    case OP_PROP:
5004    propdata[0] = 0;    propdata[0] = XCL_HASPROP;
5005    propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;    propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
5006    propdata[2] = cc[0];    propdata[2] = cc[0];
5007    propdata[3] = cc[1];    propdata[3] = cc[1];
# Line 4888  switch(type) Line 5327  switch(type)
5327  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
5328        {        {
5329        GETCHARLEN(c, cc, length);        GETCHARLEN(c, cc, length);
       read_char(common);  
5330        }        }
5331      }      }
5332    else    else
5333  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
     {  
     read_char(common);  
5334      c = *cc;      c = *cc;
     }  
5335    
5336    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
5337        {
5338        read_char_max(common, c, TRUE);
5339      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));
5340        }
5341    else    else
5342      {      {
5343      oc = char_othercase(common, c);      oc = char_othercase(common, c);
5344        read_char_max(common, c > oc ? c : oc, TRUE);
5345      bit = c ^ oc;      bit = c ^ oc;
5346      if (is_powerof2(bit))      if (is_powerof2(bit))
5347        {        {
# Line 4920  switch(type) Line 5359  switch(type)
5359    case OP_CLASS:    case OP_CLASS:
5360    case OP_NCLASS:    case OP_NCLASS:
5361    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5362    read_char(common);  
5363    if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5364      bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;
5365      read_char_max(common, bit, type == OP_NCLASS);
5366    #else
5367      read_char_max(common, 255, type == OP_NCLASS);
5368    #endif
5369    
5370      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))
5371      return cc + 32 / sizeof(pcre_uchar);      return cc + 32 / sizeof(pcre_uchar);
5372    
5373  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5374    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. */  
5375    if (common->utf)    if (common->utf)
 #endif /* COMPILE_PCRE8 */  
5376      {      {
5377      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit);
5378      if (type == OP_CLASS)      if (type == OP_CLASS)
5379        {        {
5380        add_jump(compiler, backtracks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
5381        jump[0] = NULL;        jump[0] = NULL;
5382        }        }
5383      }      }
5384  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #elif !defined COMPILE_PCRE8
5385      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
5386      if (type == OP_CLASS)
5387        {
5388        add_jump(compiler, backtracks, jump[0]);
5389        jump[0] = NULL;
5390        }
5391    #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
5392    
5393    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
5394    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
5395    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
5396    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5397    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);
5398    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
5399    
5400  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
5401    if (jump[0] != NULL)    if (jump[0] != NULL)
5402      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
5403  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif
5404    
5405    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
5406    
5407  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 5054  if (context.length > 0) Line 5506  if (context.length > 0)
5506  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
5507  }  }
5508    
 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));  
 }  
   
5509  /* Forward definitions. */  /* Forward definitions. */
5510  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
5511  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
# Line 5108  static void compile_backtrackingpath(com Line 5538  static void compile_backtrackingpath(com
5538    
5539  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
5540    
5541  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)
5542    {
5543    /* The OVECTOR offset goes to TMP2. */
5544    DEFINE_COMPILER;
5545    int count = GET2(cc, 1 + IMM2_SIZE);
5546    pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
5547    unsigned int offset;
5548    jump_list *found = NULL;
5549    
5550    SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
5551    
5552    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5553    
5554    count--;
5555    while (count-- > 0)
5556      {
5557      offset = GET2(slot, 0) << 1;
5558      GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5559      add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5560      slot += common->name_entry_size;
5561      }
5562    
5563    offset = GET2(slot, 0) << 1;
5564    GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5565    if (backtracks != NULL && !common->jscript_compat)
5566      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5567    
5568    set_jumps(found, LABEL());
5569    }
5570    
5571    static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
5572  {  {
5573  DEFINE_COMPILER;  DEFINE_COMPILER;
5574  int offset = GET2(cc, 1) << 1;  BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5575    int offset = 0;
5576  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5577  struct sljit_jump *partial;  struct sljit_jump *partial;
5578  struct sljit_jump *nopartial;  struct sljit_jump *nopartial;
5579    
5580  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  if (ref)
5581  /* OVECTOR(1) contains the "string begin - 1" constant. */    {
5582  if (withchecks && !common->jscript_compat)    offset = GET2(cc, 1) << 1;
5583    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));
5584      /* OVECTOR(1) contains the "string begin - 1" constant. */
5585      if (withchecks && !common->jscript_compat)
5586        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5587      }
5588    else
5589      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5590    
5591  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5592  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5593    {    {
5594    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);
5595    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    if (ref)
5596        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5597      else
5598        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5599    
5600    if (withchecks)    if (withchecks)
5601      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5602    
# Line 5150  if (common->utf && *cc == OP_REFI) Line 5621  if (common->utf && *cc == OP_REFI)
5621  else  else
5622  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
5623    {    {
5624    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    if (ref)
5625        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
5626      else
5627        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
5628    
5629    if (withchecks)    if (withchecks)
5630      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
5631    
# Line 5187  if (jump != NULL) Line 5662  if (jump != NULL)
5662    else    else
5663      JUMPHERE(jump);      JUMPHERE(jump);
5664    }    }
 return cc + 1 + IMM2_SIZE;  
5665  }  }
5666    
5667  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)
5668  {  {
5669  DEFINE_COMPILER;  DEFINE_COMPILER;
5670    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5671  backtrack_common *backtrack;  backtrack_common *backtrack;
5672  pcre_uchar type;  pcre_uchar type;
5673    int offset = 0;
5674  struct sljit_label *label;  struct sljit_label *label;
5675  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
5676  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5204  BOOL minimize; Line 5680  BOOL minimize;
5680    
5681  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5682    
5683    if (ref)
5684      offset = GET2(cc, 1) << 1;
5685    else
5686      cc += IMM2_SIZE;
5687  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
5688    
5689    SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
5690  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
5691  switch(type)  switch(type)
5692    {    {
# Line 5242  if (!minimize) Line 5724  if (!minimize)
5724    if (min == 0)    if (min == 0)
5725      {      {
5726      allocate_stack(common, 2);      allocate_stack(common, 2);
5727        if (ref)
5728          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5729      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5730      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5731      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
5732      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));
5733      zerolength = compile_ref_checks(common, ccbegin, NULL);      /* Handles both invalid and empty cases. Since the minimum repeat,
5734        is zero the invalid case is basically the same as an empty case. */
5735        if (ref)
5736          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5737        else
5738          {
5739          compile_dnref_search(common, ccbegin, NULL);
5740          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5741          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5742          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5743          }
5744      /* Restore if not zero length. */      /* Restore if not zero length. */
5745      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));
5746      }      }
5747    else    else
5748      {      {
5749      allocate_stack(common, 1);      allocate_stack(common, 1);
5750        if (ref)
5751          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5752      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5753      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);      if (ref)
5754          {
5755          add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5756          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5757          }
5758        else
5759          {
5760          compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5761          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5762          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5763          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5764          }
5765      }      }
5766    
5767    if (min > 1 || max > 1)    if (min > 1 || max > 1)
5768      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5769    
5770    label = LABEL();    label = LABEL();
5771      if (!ref)
5772        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5773    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
5774    
5775    if (min > 1 || max > 1)    if (min > 1 || max > 1)
# Line 5291  if (!minimize) Line 5800  if (!minimize)
5800    JUMPHERE(zerolength);    JUMPHERE(zerolength);
5801    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5802    
5803    decrease_call_count(common);    count_match(common);
5804    return cc;    return cc;
5805    }    }
5806    
5807  allocate_stack(common, 2);  allocate_stack(common, ref ? 2 : 3);
5808    if (ref)
5809      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5810  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5811  if (type != OP_CRMINSTAR)  if (type != OP_CRMINSTAR)
5812    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5813    
5814  if (min == 0)  if (min == 0)
5815    {    {
5816    zerolength = compile_ref_checks(common, ccbegin, NULL);    /* Handles both invalid and empty cases. Since the minimum repeat,
5817      is zero the invalid case is basically the same as an empty case. */
5818      if (ref)
5819        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5820      else
5821        {
5822        compile_dnref_search(common, ccbegin, NULL);
5823        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5824        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5825        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5826        }
5827      /* Length is non-zero, we can match real repeats. */
5828    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5829    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5830    }    }
5831  else  else
5832    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    {
5833      if (ref)
5834        {
5835        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5836        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5837        }
5838      else
5839        {
5840        compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5841        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5842        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5843        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5844        }
5845      }
5846    
5847  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5848  if (max > 0)  if (max > 0)
5849    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));
5850    
5851    if (!ref)
5852      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
5853  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
5854  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5855    
# Line 5330  if (jump != NULL) Line 5867  if (jump != NULL)
5867    JUMPHERE(jump);    JUMPHERE(jump);
5868  JUMPHERE(zerolength);  JUMPHERE(zerolength);
5869    
5870  decrease_call_count(common);  count_match(common);
5871  return cc;  return cc;
5872  }  }
5873    
# Line 5900  common->accept = save_accept; Line 6437  common->accept = save_accept;
6437  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
6438  }  }
6439    
 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;  
 }  
   
6440  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)
6441  {  {
6442  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 6142  backtrack_common *backtrack; Line 6569  backtrack_common *backtrack;
6569  pcre_uchar opcode;  pcre_uchar opcode;
6570  int private_data_ptr = 0;  int private_data_ptr = 0;
6571  int offset = 0;  int offset = 0;
6572  int stacksize;  int i, stacksize;
6573  int repeat_ptr = 0, repeat_length = 0;  int repeat_ptr = 0, repeat_length = 0;
6574  int repeat_type = 0, repeat_count = 0;  int repeat_type = 0, repeat_count = 0;
6575  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6576  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6577    pcre_uchar *slot;
6578  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6579  pcre_uchar ket;  pcre_uchar ket;
6580  assert_backtrack *assert;  assert_backtrack *assert;
# Line 6196  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket Line 6624  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket
6624  cc += GET(cc, 1);  cc += GET(cc, 1);
6625    
6626  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6627  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
6628    {    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);  
     }  
   }  
6629    
6630  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
6631    opcode = OP_SCOND;    opcode = OP_SCOND;
# Line 6446  if (opcode == OP_COND || opcode == OP_SC Line 6862  if (opcode == OP_COND || opcode == OP_SC
6862        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)));
6863      matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
6864      }      }
6865    else if (*matchingpath == OP_NCREF)    else if (*matchingpath == OP_DNCREF)
6866      {      {
6867      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));  
6868    
6869      JUMPHERE(jump);      i = GET2(matchingpath, 1 + IMM2_SIZE);
6870      matchingpath += 1 + IMM2_SIZE;      slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6871        OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
6872        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6873        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6874        slot += common->name_entry_size;
6875        i--;
6876        while (i-- > 0)
6877          {
6878          OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6879          OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
6880          slot += common->name_entry_size;
6881          }
6882        OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
6883        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO));
6884        matchingpath += 1 + 2 * IMM2_SIZE;
6885      }      }
6886    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
6887      {      {
6888      /* Never has other case. */      /* Never has other case. */
6889      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
6890        SLJIT_ASSERT(!has_alternatives);
6891    
6892      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)  
6893        {        {
6894        SLJIT_ASSERT(!has_alternatives);        stacksize = GET2(matchingpath, 1);
6895          if (common->currententry == NULL)
6896            stacksize = 0;
6897          else if (stacksize == RREF_ANY)
6898            stacksize = 1;
6899          else if (common->currententry->start == 0)
6900            stacksize = stacksize == 0;
6901          else
6902            stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6903    
6904        if (stacksize != 0)        if (stacksize != 0)
6905          matchingpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
6906          }
6907        else
6908          {
6909          if (common->currententry == NULL || common->currententry->start == 0)
6910            stacksize = 0;
6911        else        else
6912          {          {
6913            stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
6914            slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6915            i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6916            while (stacksize > 0)
6917              {
6918              if ((int)GET2(slot, 0) == i)
6919                break;
6920              slot += common->name_entry_size;
6921              stacksize--;
6922              }
6923            }
6924    
6925          if (stacksize != 0)
6926            matchingpath += 1 + 2 * IMM2_SIZE;
6927          }
6928    
6929          /* The stacksize == 0 is a common "else" case. */
6930          if (stacksize == 0)
6931            {
6932          if (*cc == OP_ALT)          if (*cc == OP_ALT)
6933            {            {
6934            matchingpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
# Line 6495  if (opcode == OP_COND || opcode == OP_SC Line 6937  if (opcode == OP_COND || opcode == OP_SC
6937          else          else
6938            matchingpath = cc;            matchingpath = cc;
6939          }          }
       }  
     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;  
       }  
6940      }      }
6941    else    else
6942      {      {
# Line 6663  if (bra == OP_BRAMINZERO) Line 7087  if (bra == OP_BRAMINZERO)
7087    }    }
7088    
7089  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
7090    decrease_call_count(common);    count_match(common);
7091    
7092  /* Skip the other alternatives. */  /* Skip the other alternatives. */
7093  while (*cc == OP_ALT)  while (*cc == OP_ALT)
# Line 6950  if (!zero) Line 7374  if (!zero)
7374    
7375  /* None of them matched. */  /* None of them matched. */
7376  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
7377  decrease_call_count(common);  count_match(common);
7378  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
7379  }  }
7380    
7381  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)
7382  {  {
7383  int class_len;  int class_len;
7384    
# Line 6990  else if (*opcode >= OP_TYPESTAR && *opco Line 7414  else if (*opcode >= OP_TYPESTAR && *opco
7414    }    }
7415  else  else
7416    {    {
7417    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
7418    *type = *opcode;    *type = *opcode;
7419    cc++;    cc++;
7420    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 7001  else Line 7425  else
7425      if (end != NULL)      if (end != NULL)
7426        *end = cc + class_len;        *end = cc + class_len;
7427      }      }
7428      else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
7429        {
7430        *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
7431        if (end != NULL)
7432          *end = cc + class_len;
7433        }
7434    else    else
7435      {      {
7436      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
7437      *arg1 = GET2(cc, (class_len + IMM2_SIZE));      *max = GET2(cc, (class_len + IMM2_SIZE));
7438      *arg2 = GET2(cc, class_len);      *min = GET2(cc, class_len);
7439    
7440      if (*arg2 == 0)      if (*min == 0)
7441        {        {
7442        SLJIT_ASSERT(*arg1 != 0);        SLJIT_ASSERT(*max != 0);
7443        *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;        *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO);
7444        }        }
7445      if (*arg1 == *arg2)      if (*max == *min)
7446        *opcode = OP_EXACT;        *opcode = OP_EXACT;
7447    
7448      if (end != NULL)      if (end != NULL)
# Line 7023  else Line 7453  else
7453    
7454  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)
7455    {    {
7456    *arg1 = GET2(cc, 0);    *max = GET2(cc, 0);
7457    cc += IMM2_SIZE;    cc += IMM2_SIZE;
7458    }    }
7459    
# Line 7052  DEFINE_COMPILER; Line 7482  DEFINE_COMPILER;
7482  backtrack_common *backtrack;  backtrack_common *backtrack;
7483  pcre_uchar opcode;  pcre_uchar opcode;
7484  pcre_uchar type;  pcre_uchar type;
7485  int arg1 = -1, arg2 = -1;  int max = -1, min = -1;
7486  pcre_uchar* end;  pcre_uchar* end;
7487  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
7488  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 7065  int tmp_base, tmp_offset; Line 7495  int tmp_base, tmp_offset;
7495    
7496  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
7497    
7498  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end);
7499    
7500  switch(type)  switch(type)
7501    {    {
# Line 7136  switch(opcode) Line 7566  switch(opcode)
7566        {        {
7567        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
7568        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7569        if (opcode == OP_CRRANGE && arg2 > 0)        if (opcode == OP_CRRANGE && min > 0)
7570          CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);          CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
7571        if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))        if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0))
7572          jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);          jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
7573        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
7574        }        }
7575    
# Line 7166  switch(opcode) Line 7596  switch(opcode)
7596      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
7597      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
7598        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
7599      else if (opcode == OP_CRRANGE && arg1 == 0)      else if (opcode == OP_CRRANGE && max == 0)
7600        {        {
7601        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
7602        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
# Line 7176  switch(opcode) Line 7606  switch(opcode)
7606        OP1(SLJIT_MOV, TMP1, 0, base, offset1);        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
7607        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7608        OP1(SLJIT_MOV, base, offset1, TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
7609        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, max + 1, label);
7610        }        }
7611      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
7612      if (opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
7613        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));
7614      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
7615      }      }
7616    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
# Line 7218  switch(opcode) Line 7648  switch(opcode)
7648    break;    break;
7649    
7650    case OP_EXACT:    case OP_EXACT:
7651    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, max);
7652    label = LABEL();    label = LABEL();
7653    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
7654    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 7231  switch(opcode) Line 7661  switch(opcode)
7661    if (opcode == OP_POSPLUS)    if (opcode == OP_POSPLUS)
7662      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
7663    if (opcode == OP_POSUPTO)    if (opcode == OP_POSUPTO)
7664      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max);
7665    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
7666    label = LABEL();    label = LABEL();
7667    compile_char1_matchingpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
# Line 7255  switch(opcode) Line 7685  switch(opcode)
7685    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
7686    break;    break;
7687    
7688      case OP_CRPOSRANGE:
7689      /* Combination of OP_EXACT and OP_POSSTAR or OP_POSUPTO */
7690      OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, min);
7691      label = LABEL();
7692      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
7693      OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
7694      JUMPTO(SLJIT_C_NOT_ZERO, label);
7695    
7696      if (max != 0)
7697        {
7698        SLJIT_ASSERT(max - min > 0);
7699        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, max - min);
7700        }
7701      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
7702      label = LABEL();
7703      compile_char1_matchingpath(common, type, cc, &nomatch);
7704      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
7705      if (max == 0)
7706        JUMPTO(SLJIT_JUMP, label);
7707      else
7708        {
7709        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
7710        JUMPTO(SLJIT_C_NOT_ZERO, label);
7711        }
7712      set_jumps(nomatch, LABEL());
7713      OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
7714      break;
7715    
7716    default:    default:
7717    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
7718    break;    break;
7719    }    }
7720    
7721  decrease_call_count(common);  count_match(common);
7722  return end;  return end;
7723  }  }
7724    
# Line 7532  while (cc < ccend) Line 7990  while (cc < ccend)
7990    
7991      case OP_CLASS:      case OP_CLASS:
7992      case OP_NCLASS:      case OP_NCLASS:
7993      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)
7994        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
7995      else      else
7996        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 7540  while (cc < ccend) Line 7998  while (cc < ccend)
7998    
7999  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
8000      case OP_XCLASS:      case OP_XCLASS:
8001      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)
8002        cc = compile_iterator_matchingpath(common, cc, parent);        cc = compile_iterator_matchingpath(common, cc, parent);
8003      else      else
8004        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 7549  while (cc < ccend) Line 8007  while (cc < ccend)
8007    
8008      case OP_REF:      case OP_REF:
8009      case OP_REFI:      case OP_REFI:
8010      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)
8011          cc = compile_ref_iterator_matchingpath(common, cc, parent);
8012        else
8013          {
8014          compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
8015          cc += 1 + IMM2_SIZE;
8016          }
8017        break;
8018    
8019        case OP_DNREF:
8020        case OP_DNREFI:
8021        if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRPOSRANGE)
8022        cc = compile_ref_iterator_matchingpath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
8023      else      else
8024        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        {
8025          compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
8026          compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
8027          cc += 1 + 2 * IMM2_SIZE;
8028          }
8029      break;      break;
8030    
8031      case OP_RECURSE:      case OP_RECURSE:
# Line 7587  while (cc < ccend) Line 8060  while (cc < ccend)
8060        }        }
8061      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
8062      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
8063        decrease_call_count(common);        count_match(common);
8064      break;      break;
8065    
8066      case OP_ONCE:      case OP_ONCE:
# Line 7705  DEFINE_COMPILER; Line 8178  DEFINE_COMPILER;
8178  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8179  pcre_uchar opcode;  pcre_uchar opcode;
8180  pcre_uchar type;  pcre_uchar type;
8181  int arg1 = -1, arg2 = -1;  int max = -1, min = -1;
8182  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
8183  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
8184  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
# Line 7714  int base = (private_data_ptr == 0) ? SLJ Line 8187  int base = (private_data_ptr == 0) ? SLJ
8187  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;  int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
8188  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);
8189    
8190  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, NULL);  cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, NULL);
8191    
8192  switch(opcode)  switch(opcode)
8193    {    {
# Line 7733  switch(opcode) Line 8206  switch(opcode)
8206    else    else
8207      {      {
8208      if (opcode == OP_UPTO)      if (opcode == OP_UPTO)
8209        arg2 = 0;        min = 0;
8210      if (opcode <= OP_PLUS)      if (opcode <= OP_PLUS)
8211        {        {
8212        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
# Line 7743  switch(opcode) Line 8216  switch(opcode)
8216        {        {
8217        OP1(SLJIT_MOV, TMP1, 0, base, offset1);        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
8218        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);        OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
8219        jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, arg2 + 1);        jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, min + 1);
8220        OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_SUB, base, offset1, TMP1, 0, SLJIT_IMM, 1);
8221        }        }
8222      skip_char_back(common);      skip_char_back(common);
# Line 7788  switch(opcode) Line 8261  switch(opcode)
8261    OP1(SLJIT_MOV, base, offset1, TMP1, 0);    OP1(SLJIT_MOV, base, offset1, TMP1, 0);
8262    
8263    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
8264      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2 + 1, label);      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min + 1, label);
8265    
8266    if (opcode == OP_CRMINRANGE && arg1 == 0)    if (opcode == OP_CRMINRANGE && max == 0)
8267      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(iterator_backtrack)->matchingpath);
8268    else    else
8269      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);
8270    
8271    set_jumps(jumplist, LABEL());    set_jumps(jumplist, LABEL());
8272    if (private_data_ptr == 0)    if (private_data_ptr == 0)
# Line 7828  switch(opcode) Line 8301  switch(opcode)
8301    
8302    case OP_EXACT:    case OP_EXACT:
8303    case OP_POSPLUS:    case OP_POSPLUS:
8304      case OP_CRPOSRANGE:
8305    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8306    break;    break;
8307    
# Line 7846  static SLJIT_INLINE void compile_ref_ite Line 8320  static SLJIT_INLINE void compile_ref_ite
8320  {  {
8321  DEFINE_COMPILER;  DEFINE_COMPILER;
8322  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8323    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
8324  pcre_uchar type;  pcre_uchar type;
8325    
8326  type = cc[1 + IMM2_SIZE];  type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
8327    
8328  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
8329    {    {
8330      /* Maximize case. */
8331    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8332    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8333    free_stack(common, 1);    free_stack(common, 1);
# Line 7861  if ((type & 0x1) == 0) Line 8338  if ((type & 0x1) == 0)
8338  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8339  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);
8340  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
8341  free_stack(common, 2);  free_stack(common, ref ? 2 : 3);
8342  }  }
8343    
8344  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 8225  if (has_alternatives) Line 8702  if (has_alternatives)
8702          return;          return;
8703        }        }
8704    
8705      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is successfully matched. */
8706      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8707      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8708        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 8662  while (current) Line 9139  while (current)
9139    
9140      case OP_REF:      case OP_REF:
9141      case OP_REFI:      case OP_REFI:
9142        case OP_DNREF:
9143        case OP_DNREFI:
9144      compile_ref_iterator_backtrackingpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
9145      break;      break;
9146    
# Line 8955  else Line 9434  else
9434    }    }
9435  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
9436  common->ctypes = (sljit_sw)(tables + ctypes_offset);  common->ctypes = (sljit_sw)(tables + ctypes_offset);
9437  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);  
9438  common->name_count = re->name_count;  common->name_count = re->name_count;
9439  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
9440  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
# Line 8970  common->use_ucp = (re->options & PCRE_UC Line 9448  common->use_ucp = (re->options & PCRE_UC
9448  ccend = bracketend(rootbacktrack.cc);  ccend = bracketend(rootbacktrack.cc);
9449    
9450  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
9451  common->ovector_start = CALL_LIMIT + sizeof(sljit_sw);  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
9452  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
9453  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
9454    return;    return;
# Line 9102  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 9580  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
9580  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));
9581  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));
9582  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));
9583  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));
9584  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));
9585  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));
9586  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0);
9587    
9588  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9589    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 9129  if ((re->options & PCRE_ANCHORED) == 0) Line 9607  if ((re->options & PCRE_ANCHORED) == 0)
9607      else if ((re->flags & PCRE_STARTLINE) != 0)      else if ((re->flags & PCRE_STARTLINE) != 0)
9608        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
9609      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)
9610        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);
9611      }      }
9612    }    }
9613  else  else
# Line 9147  if (common->req_char_ptr != 0) Line 9625  if (common->req_char_ptr != 0)
9625  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
9626  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);
9627  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9628  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);
9629  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9630    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);
9631    
# Line 9367  if (common->reset_match != NULL) Line 9845  if (common->reset_match != NULL)
9845    JUMPTO(SLJIT_JUMP, reset_match_label);    JUMPTO(SLJIT_JUMP, reset_match_label);
9846    }    }
9847  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9848  #ifndef COMPILE_PCRE32  #ifdef COMPILE_PCRE8
9849  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
9850    {    {
9851    set_jumps(common->utfreadchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
9852    do_utfreadchar(common);    do_utfreadchar(common);
9853    }    }
9854  #endif /* !COMPILE_PCRE32 */  if (common->utfreadchar16 != NULL)
9855  #ifdef COMPILE_PCRE8    {
9856      set_jumps(common->utfreadchar16, LABEL());
9857      do_utfreadchar16(common);
9858      }
9859  if (common->utfreadtype8 != NULL)  if (common->utfreadtype8 != NULL)
9860    {    {
9861    set_jumps(common->utfreadtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
# Line 9425  else Line 9906  else
9906      }      }
9907    memset(functions, 0, sizeof(executable_functions));    memset(functions, 0, sizeof(executable_functions));
9908    functions->top_bracket = (re->top_bracket + 1) * 2;    functions->top_bracket = (re->top_bracket + 1) * 2;
9909      functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0;
9910    extra->executable_jit = functions;    extra->executable_jit = functions;
9911    extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;    extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
9912    }    }
# Line 9479  arguments.begin = subject; Line 9961  arguments.begin = subject;
9961  arguments.end = subject + length;  arguments.end = subject + length;
9962  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
9963  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
9964  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);
9965    if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
9966      arguments.limit_match = functions->limit_match;
9967  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
9968  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
9969  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 9570  arguments.begin = subject_ptr; Line 10054  arguments.begin = subject_ptr;
10054  arguments.end = subject_ptr + length;  arguments.end = subject_ptr + length;
10055  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
10056  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
10057  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);
10058    if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
10059      arguments.limit_match = functions->limit_match;
10060  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
10061  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
10062  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 9689  if (extra != NULL && Line 10175  if (extra != NULL &&
10175    }    }
10176  }  }
10177    
10178    #if defined COMPILE_PCRE8
10179    PCRE_EXP_DECL void
10180    pcre_jit_free_unused_memory(void)
10181    #elif defined COMPILE_PCRE16
10182    PCRE_EXP_DECL void
10183    pcre16_jit_free_unused_memory(void)
10184    #elif defined COMPILE_PCRE32
10185    PCRE_EXP_DECL void
10186    pcre32_jit_free_unused_memory(void)
10187    #endif
10188    {
10189    sljit_free_unused_memory_exec();
10190    }
10191    
10192  #else  /* SUPPORT_JIT */  #else  /* SUPPORT_JIT */
10193    
10194  /* 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 9740  pcre32_assign_jit_stack(pcre32_extra *ex Line 10240  pcre32_assign_jit_stack(pcre32_extra *ex
10240  (void)userdata;  (void)userdata;
10241  }  }
10242    
10243    #if defined COMPILE_PCRE8
10244    PCRE_EXP_DECL void
10245    pcre_jit_free_unused_memory(void)
10246    #elif defined COMPILE_PCRE16
10247    PCRE_EXP_DECL void
10248    pcre16_jit_free_unused_memory(void)
10249    #elif defined COMPILE_PCRE32
10250    PCRE_EXP_DECL void
10251    pcre32_jit_free_unused_memory(void)
10252    #endif
10253    {
10254    }
10255    
10256  #endif  #endif
10257    
10258  /* End of pcre_jit_compile.c */  /* End of pcre_jit_compile.c */

Legend:
Removed from v.1308  
changed lines
  Added in v.1422

  ViewVC Help
Powered by ViewVC 1.1.5