/[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 1290 by zherczeg, Sat Mar 16 18:45:51 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 313  typedef struct compiler_common { Line 314  typedef struct compiler_common {
314    /* First byte code. */    /* First byte code. */
315    pcre_uchar *start;    pcre_uchar *start;
316    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
317    int *private_data_ptrs;    sljit_si *private_data_ptrs;
318    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
319    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
320    /* Tells whether the starting offset is a target of then. */    /* Tells whether the starting offset is a target of then. */
# Line 356  typedef struct compiler_common { Line 357  typedef struct compiler_common {
357    BOOL has_then;    BOOL has_then;
358    /* Needs to know the start position anytime. */    /* Needs to know the start position anytime. */
359    BOOL needs_start_ptr;    BOOL needs_start_ptr;
360    /* Currently in recurse or assert. */    /* Currently in recurse or negative assert. */
361    BOOL local_exit;    BOOL local_exit;
362      /* Currently in a positive assert. */
363      BOOL positive_assert;
364    /* Newline control. */    /* Newline control. */
365    int nltype;    int nltype;
366    int newline;    int newline;
# Line 366  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 382  typedef struct compiler_common { Line 384  typedef struct compiler_common {
384    recurse_entry *currententry;    recurse_entry *currententry;
385    jump_list *partialmatch;    jump_list *partialmatch;
386    jump_list *quit;    jump_list *quit;
387      jump_list *positive_assert_quit;
388    jump_list *forced_quit;    jump_list *forced_quit;
389    jump_list *accept;    jump_list *accept;
390    jump_list *calllimit;    jump_list *calllimit;
# Line 400  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 460  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 471  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 529  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   get_private_data_length   check_opcode_types
542   set_private_data_ptrs   set_private_data_ptrs
543   get_framesize   get_framesize
544   init_frame   init_frame
# Line 581  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 610  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 730  switch(*cc) Line 743  switch(*cc)
743    }    }
744  }  }
745    
746  #define CASE_ITERATOR_PRIVATE_DATA_1 \  static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
     case OP_MINSTAR: \  
     case OP_MINPLUS: \  
     case OP_QUERY: \  
     case OP_MINQUERY: \  
     case OP_MINSTARI: \  
     case OP_MINPLUSI: \  
     case OP_QUERYI: \  
     case OP_MINQUERYI: \  
     case OP_NOTMINSTAR: \  
     case OP_NOTMINPLUS: \  
     case OP_NOTQUERY: \  
     case OP_NOTMINQUERY: \  
     case OP_NOTMINSTARI: \  
     case OP_NOTMINPLUSI: \  
     case OP_NOTQUERYI: \  
     case OP_NOTMINQUERYI:  
   
 #define CASE_ITERATOR_PRIVATE_DATA_2A \  
     case OP_STAR: \  
     case OP_PLUS: \  
     case OP_STARI: \  
     case OP_PLUSI: \  
     case OP_NOTSTAR: \  
     case OP_NOTPLUS: \  
     case OP_NOTSTARI: \  
     case OP_NOTPLUSI:  
   
 #define CASE_ITERATOR_PRIVATE_DATA_2B \  
     case OP_UPTO: \  
     case OP_MINUPTO: \  
     case OP_UPTOI: \  
     case OP_MINUPTOI: \  
     case OP_NOTUPTO: \  
     case OP_NOTMINUPTO: \  
     case OP_NOTUPTOI: \  
     case OP_NOTMINUPTOI:  
   
 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \  
     case OP_TYPEMINSTAR: \  
     case OP_TYPEMINPLUS: \  
     case OP_TYPEQUERY: \  
     case OP_TYPEMINQUERY:  
   
 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \  
     case OP_TYPESTAR: \  
     case OP_TYPEPLUS:  
   
 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \  
     case OP_TYPEUPTO: \  
     case OP_TYPEMINUPTO:  
   
 static int get_class_iterator_size(pcre_uchar *cc)  
 {  
 switch(*cc)  
   {  
   case OP_CRSTAR:  
   case OP_CRPLUS:  
   return 2;  
   
   case OP_CRMINSTAR:  
   case OP_CRMINPLUS:  
   case OP_CRQUERY:  
   case OP_CRMINQUERY:  
   return 1;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))  
     return 0;  
   return 2;  
   
   default:  
   return 0;  
   }  
 }  
   
 static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  
747  {  {
748  int private_data_length = 0;  int count;
749  pcre_uchar *alternative;  pcre_uchar *slot;
 pcre_uchar *name;  
 pcre_uchar *end = NULL;  
 int space, size, i;  
 pcre_uint32 bracketlen;  
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)
753    {    {
   space = 0;  
   size = 0;  
   bracketlen = 0;  
754    switch(*cc)    switch(*cc)
755      {      {
756      case OP_SET_SOM:      case OP_SET_SOM:
# Line 835  while (cc < ccend) Line 764  while (cc < ccend)
764      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
765      break;      break;
766    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     case OP_ONCE_NC:  
     case OP_BRAPOS:  
     case OP_SBRA:  
     case OP_SBRAPOS:  
     private_data_length += sizeof(sljit_sw);  
     bracketlen = 1 + LINK_SIZE;  
     break;  
   
767      case OP_CBRAPOS:      case OP_CBRAPOS:
768      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     private_data_length += sizeof(sljit_sw);  
769      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
770      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
771      break;      break;
772    
773      case OP_COND:      case OP_COND:
# Line 860  while (cc < ccend) Line 775  while (cc < ccend)
775      /* Only AUTO_CALLOUT can insert this opcode. We do      /* Only AUTO_CALLOUT can insert this opcode. We do
776         not intend to support this case. */         not intend to support this case. */
777      if (cc[1 + LINK_SIZE] == OP_CALLOUT)      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
778        return -1;        return FALSE;
779        cc += 1 + LINK_SIZE;
     if (*cc == OP_COND)  
       {  
       /* Might be a hidden SCOND. */  
       alternative = cc + GET(cc, 1);  
       if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)  
         private_data_length += sizeof(sljit_sw);  
       }  
     else  
       private_data_length += sizeof(sljit_sw);  
     bracketlen = 1 + LINK_SIZE;  
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      bracketlen = GET2(cc, 1);      case OP_DNREFI:
789      name = (pcre_uchar *)common->name_table;      case OP_DNCREF:
790      alternative = 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)
       if (GET2(name, 0) == bracketlen) break;  
       name += common->name_entry_size;  
       }  
     SLJIT_ASSERT(i != common->name_count);  
   
     for (i = 0; i < common->name_count; i++)  
793        {        {
794        if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)        common->optimized_cbracket[GET2(slot, 0)] = 0;
795          common->optimized_cbracket[GET2(alternative, 0)] = 0;        slot += common->name_entry_size;
       alternative += common->name_entry_size;  
796        }        }
797      bracketlen = 0;      cc += 1 + 2 * IMM2_SIZE;
     cc += 1 + IMM2_SIZE;  
     break;  
   
     case OP_BRA:  
     bracketlen = 1 + LINK_SIZE;  
     break;  
   
     case OP_CBRA:  
     case OP_SCBRA:  
     bracketlen = 1 + LINK_SIZE + IMM2_SIZE;  
     break;  
   
     CASE_ITERATOR_PRIVATE_DATA_1  
     space = 1;  
     size = -2;  
     break;  
   
     CASE_ITERATOR_PRIVATE_DATA_2A  
     space = 2;  
     size = -2;  
     break;  
   
     CASE_ITERATOR_PRIVATE_DATA_2B  
     space = 2;  
     size = -(2 + IMM2_SIZE);  
     break;  
   
     CASE_ITERATOR_TYPE_PRIVATE_DATA_1  
     space = 1;  
     size = 1;  
     break;  
   
     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A  
     if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)  
       space = 2;  
     size = 1;  
     break;  
   
     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B  
     if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)  
       space = 2;  
     size = 1 + IMM2_SIZE;  
     break;  
   
     case OP_CLASS:  
     case OP_NCLASS:  
     size += 1 + 32 / sizeof(pcre_uchar);  
     space = get_class_iterator_size(cc + size);  
     break;  
   
 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  
     case OP_XCLASS:  
     size = GET(cc, 1);  
     space = get_class_iterator_size(cc + size);  
798      break;      break;
 #endif  
799    
800      case OP_RECURSE:      case OP_RECURSE:
801      /* Set its value only once. */      /* Set its value only once. */
# Line 1012  while (cc < ccend) Line 854  while (cc < ccend)
854      default:      default:
855      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
856      if (cc == NULL)      if (cc == NULL)
857        return -1;        return FALSE;
858      break;      break;
859      }      }
860      }
861    return TRUE;
862    }
863    
864    if (space > 0 && cc >= end)  static int get_class_iterator_size(pcre_uchar *cc)
865      private_data_length += sizeof(sljit_sw) * space;  {
866    switch(*cc)
867      {
868      case OP_CRSTAR:
869      case OP_CRPLUS:
870      return 2;
871    
872    if (size != 0)    case OP_CRMINSTAR:
873      case OP_CRMINPLUS:
874      case OP_CRQUERY:
875      case OP_CRMINQUERY:
876      return 1;
877    
878      case OP_CRRANGE:
879      case OP_CRMINRANGE:
880      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
881        return 0;
882      return 2;
883    
884      default:
885      return 0;
886      }
887    }
888    
889    static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
890    {
891    pcre_uchar *end = bracketend(begin);
892    pcre_uchar *next;
893    pcre_uchar *next_end;
894    pcre_uchar *max_end;
895    pcre_uchar type;
896    sljit_sw length = end - begin;
897    int min, max, i;
898    
899    /* Detect fixed iterations first. */
900    if (end[-(1 + LINK_SIZE)] != OP_KET)
901      return FALSE;
902    
903    /* Already detected repeat. */
904    if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
905      return TRUE;
906    
907    next = end;
908    min = 1;
909    while (1)
910      {
911      if (*next != *begin)
912        break;
913      next_end = bracketend(next);
914      if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
915        break;
916      next = next_end;
917      min++;
918      }
919    
920    if (min == 2)
921      return FALSE;
922    
923    max = 0;
924    max_end = next;
925    if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
926      {
927      type = *next;
928      while (1)
929      {      {
930      if (size < 0)      if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
931        {        break;
932        cc += -size;      next_end = bracketend(next + 2 + LINK_SIZE);
933  #ifdef SUPPORT_UTF      if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
934        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        break;
935  #endif      next = next_end;
936        }      max++;
     else  
       cc += size;  
937      }      }
938    
939    if (bracketlen != 0)    if (next[0] == type && next[1] == *begin && max >= 1)
940      {      {
941      if (cc >= end)      next_end = bracketend(next + 1);
942        if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
943        {        {
944        end = bracketend(cc);        for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
945        if (end[-1 - LINK_SIZE] == OP_KET)          if (*next_end != OP_KET)
946          end = NULL;            break;
947    
948          if (i == max)
949            {
950            common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
951            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
952            /* +2 the original and the last. */
953            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
954            if (min == 1)
955              return TRUE;
956            min--;
957            max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
958            }
959        }        }
     cc += bracketlen;  
960      }      }
961    }    }
962  return private_data_length;  
963    if (min >= 3)
964      {
965      common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
966      common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
967      common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
968      return TRUE;
969      }
970    
971    return FALSE;
972  }  }
973    
974  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
975        case OP_MINSTAR: \
976        case OP_MINPLUS: \
977        case OP_QUERY: \
978        case OP_MINQUERY: \
979        case OP_MINSTARI: \
980        case OP_MINPLUSI: \
981        case OP_QUERYI: \
982        case OP_MINQUERYI: \
983        case OP_NOTMINSTAR: \
984        case OP_NOTMINPLUS: \
985        case OP_NOTQUERY: \
986        case OP_NOTMINQUERY: \
987        case OP_NOTMINSTARI: \
988        case OP_NOTMINPLUSI: \
989        case OP_NOTQUERYI: \
990        case OP_NOTMINQUERYI:
991    
992    #define CASE_ITERATOR_PRIVATE_DATA_2A \
993        case OP_STAR: \
994        case OP_PLUS: \
995        case OP_STARI: \
996        case OP_PLUSI: \
997        case OP_NOTSTAR: \
998        case OP_NOTPLUS: \
999        case OP_NOTSTARI: \
1000        case OP_NOTPLUSI:
1001    
1002    #define CASE_ITERATOR_PRIVATE_DATA_2B \
1003        case OP_UPTO: \
1004        case OP_MINUPTO: \
1005        case OP_UPTOI: \
1006        case OP_MINUPTOI: \
1007        case OP_NOTUPTO: \
1008        case OP_NOTMINUPTO: \
1009        case OP_NOTUPTOI: \
1010        case OP_NOTMINUPTOI:
1011    
1012    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1013        case OP_TYPEMINSTAR: \
1014        case OP_TYPEMINPLUS: \
1015        case OP_TYPEQUERY: \
1016        case OP_TYPEMINQUERY:
1017    
1018    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1019        case OP_TYPESTAR: \
1020        case OP_TYPEPLUS:
1021    
1022    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1023        case OP_TYPEUPTO: \
1024        case OP_TYPEMINUPTO:
1025    
1026    static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1027  {  {
1028  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1029  pcre_uchar *alternative;  pcre_uchar *alternative;
1030  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
1031    int private_data_ptr = *private_data_start;
1032  int space, size, bracketlen;  int space, size, bracketlen;
1033    
1034  while (cc < ccend)  while (cc < ccend)
# Line 1058  while (cc < ccend) Line 1036  while (cc < ccend)
1036    space = 0;    space = 0;
1037    size = 0;    size = 0;
1038    bracketlen = 0;    bracketlen = 0;
1039      if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1040        return;
1041    
1042      if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
1043        if (detect_repeat(common, cc))
1044          {
1045          /* These brackets are converted to repeats, so no global
1046          based single character repeat is allowed. */
1047          if (cc >= end)
1048            end = bracketend(cc);
1049          }
1050    
1051    switch(*cc)    switch(*cc)
1052      {      {
1053        case OP_KET:
1054        if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1055          {
1056          common->private_data_ptrs[cc - common->start] = private_data_ptr;
1057          private_data_ptr += sizeof(sljit_sw);
1058          cc += common->private_data_ptrs[cc + 1 - common->start];
1059          }
1060        cc += 1 + LINK_SIZE;
1061        break;
1062    
1063      case OP_ASSERT:      case OP_ASSERT:
1064      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1065      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1153  while (cc < ccend) Line 1153  while (cc < ccend)
1153      break;      break;
1154      }      }
1155    
1156      /* Character iterators, which are not inside a repeated bracket,
1157         gets a private slot instead of allocating it on the stack. */
1158    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1159      {      {
1160      common->private_data_ptrs[cc - common->start] = private_data_ptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
# Line 1183  while (cc < ccend) Line 1185  while (cc < ccend)
1185      cc += bracketlen;      cc += bracketlen;
1186      }      }
1187    }    }
1188    *private_data_start = private_data_ptr;
1189  }  }
1190    
1191  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
# Line 1494  while (cc < ccend) Line 1497  while (cc < ccend)
1497    size = 0;    size = 0;
1498    switch(*cc)    switch(*cc)
1499      {      {
1500        case OP_KET:
1501        if (PRIVATE_DATA(cc) != 0)
1502          private_data_length++;
1503        cc += 1 + LINK_SIZE;
1504        break;
1505    
1506      case OP_ASSERT:      case OP_ASSERT:
1507      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1508      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1662  do Line 1671  do
1671    
1672      switch(*cc)      switch(*cc)
1673        {        {
1674          case OP_KET:
1675          if (PRIVATE_DATA(cc) != 0)
1676            {
1677            count = 1;
1678            srcw[0] = PRIVATE_DATA(cc);
1679            }
1680          cc += 1 + LINK_SIZE;
1681          break;
1682    
1683        case OP_ASSERT:        case OP_ASSERT:
1684        case OP_ASSERT_NOT:        case OP_ASSERT_NOT:
1685        case OP_ASSERTBACK:        case OP_ASSERTBACK:
# Line 2004  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 2118  while (current != NULL) Line 2136  while (current != NULL)
2136  return -1;  return -1;
2137  }  }
2138    
 static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)  
 {  
 do  
   {  
   SLJIT_ASSERT(current != NULL);  
   switch (current[-2])  
     {  
     case type_then_trap:  
     if (current[-3] == start)  
       return (sljit_sw)current;  
     break;  
   
     case type_mark:  
     break;  
   
     default:  
     SLJIT_ASSERT_STOP();  
     break;  
     }  
   current = (sljit_sw*)current[-1];  
   }  
 while (TRUE);  
 }  
   
2139  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2140  {  {
2141  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2379  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 2466  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 2476  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 2635  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. */
2793  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2794  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
2795  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2796    
2797    /* Four byte sequence. */
2798    JUMPHERE(jump);
2799    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2800    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, 6);  
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  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  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);
2821  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2822  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));  
2823    /* 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);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2829    
2830  /* Four byte sequence. */  JUMPHERE(jump);
2831  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2832  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800);
2833  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  
 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(3));  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));  
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 2706  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 2903  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 2958  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 2969  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;
3090    
3091        case OP_ALT:
3092        cc += GET(cc, 1);
3093        continue;
3094    
3095        case OP_ONCE:
3096        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        if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3111          cc += IMM2_SIZE;
3112        cc += 1 + LINK_SIZE;
3113        continue;
3114    
3115        case OP_CLASS:
3116        case OP_NCLASS:
3117        any = TRUE;
3118        cc += 1 + 32 / sizeof(pcre_uchar);
3119      break;      break;
3120    
3121      default:  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3122      must_stop = 2;      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;      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 (must_stop == 2)    if (any)
3158        break;      {
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;    len = 1;
3189  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3190    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3191  #endif  #endif
3192    
3193    if (caseless && char_has_othercase(common, cc))    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 3004  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        if (--repeat == 0)
3251          break;
3252    
3253      chars[location] = c;      len = len_save;
3254      chars[location + 1] = bit;      cc = cc_save;
3255        }
3256    
3257      len--;    repeat = 1;
3258      location += 2;    if (last)
3259      cc++;      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 3066  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 3215  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 3248  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 3257  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 3474  if (common->use_ucp) Line 3800  if (common->use_ucp)
3800    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);
3801    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3802    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3803    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3804    JUMPHERE(jump);    JUMPHERE(jump);
   }  
 else  
 #endif  
   {  
 #ifndef COMPILE_PCRE8  
   /* TMP2 may be destroyed by peek_char. */  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #elif defined SUPPORT_UTF  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
   jump = NULL;  
   if (common->utf)  
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #endif  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);  
   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);  
   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (jump != NULL)  
     JUMPHERE(jump);  
 #endif /* COMPILE_PCRE8 */  
   }  
 set_jumps(skipread_list, LABEL());  
   
 OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  
 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
 }  
   
 /*  
   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)  
 {  
 DEFINE_COMPILER;  
 struct sljit_jump *jump;  
   
 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;  
3805    }    }
3806  }  else
3807    #endif
 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)  
3808    {    {
3809    if (length >= MAX_RANGE_SIZE)  #ifndef COMPILE_PCRE8
3810      return;    /* TMP2 may be destroyed by peek_char. */
3811    ranges[2 + length] = 256;    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3812    length++;    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3813    #elif defined SUPPORT_UTF
3814      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3815      jump = NULL;
3816      if (common->utf)
3817        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3818    #endif
3819      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3820      OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3821      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3822    #ifndef COMPILE_PCRE8
3823      JUMPHERE(jump);
3824    #elif defined SUPPORT_UTF
3825      if (jump != NULL)
3826        JUMPHERE(jump);
3827    #endif /* COMPILE_PCRE8 */
3828    }    }
3829  ranges[0] = length;  set_jumps(skipread_list, LABEL());
3830    
3831    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3832    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, jump_list **backtracks)  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks)
3836  {  {
3837  int ranges[2 + MAX_RANGE_SIZE];  DEFINE_COMPILER;
3838    int ranges[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 3624  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 3637  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 4030  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 4048  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    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))        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        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 4135  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 4322  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 4423  while (*cc != XCL_END) Line 4788  while (*cc != XCL_END)
4788        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4789        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4790        break;        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);
4833    
4834          JUMPHERE(jump);
4835          jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4836          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);
4844          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
4845          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);
4851          break;
4852        }        }
4853      cc += 2;      cc += 2;
4854      }      }
# Line 4454  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 4479  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 4506  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 4569  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 4895  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 4927  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 5061  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 5115  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;  DEFINE_COMPILER;
5545  int offset = GET2(cc, 1) << 1;  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;
5574    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 5157  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 5194  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 5211  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 5249  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 5298  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 5337  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 5525  jump_list **target = (conditional) ? &ba Line 6055  jump_list **target = (conditional) ? &ba
6055  jump_list **found;  jump_list **found;
6056  /* Saving previous accept variables. */  /* Saving previous accept variables. */
6057  BOOL save_local_exit = common->local_exit;  BOOL save_local_exit = common->local_exit;
6058    BOOL save_positive_assert = common->positive_assert;
6059  then_trap_backtrack *save_then_trap = common->then_trap;  then_trap_backtrack *save_then_trap = common->then_trap;
6060  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
6061  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
6062  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
6063    jump_list *save_positive_assert_quit = common->positive_assert_quit;
6064  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
6065  struct sljit_jump *jump;  struct sljit_jump *jump;
6066  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 5598  else Line 6130  else
6130    }    }
6131    
6132  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
6133  common->local_exit = TRUE;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6134  common->quit_label = NULL;    {
6135  common->quit = NULL;    /* Negative assert is stronger than positive assert. */
6136      common->local_exit = TRUE;
6137      common->quit_label = NULL;
6138      common->quit = NULL;
6139      common->positive_assert = FALSE;
6140      }
6141    else
6142      common->positive_assert = TRUE;
6143    common->positive_assert_quit = NULL;
6144    
6145  while (1)  while (1)
6146    {    {
6147    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5615  while (1) Line 6156  while (1)
6156    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
6157    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6158      {      {
6159      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6160          {
6161          common->local_exit = save_local_exit;
6162          common->quit_label = save_quit_label;
6163          common->quit = save_quit;
6164          }
6165        common->positive_assert = save_positive_assert;
6166      common->then_trap = save_then_trap;      common->then_trap = save_then_trap;
     common->quit_label = save_quit_label;  
6167      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
6168      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
6169      common->accept = save_accept;      common->accept = save_accept;
6170      return NULL;      return NULL;
6171      }      }
# Line 5684  while (1) Line 6230  while (1)
6230    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
6231    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6232      {      {
6233      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6234          {
6235          common->local_exit = save_local_exit;
6236          common->quit_label = save_quit_label;
6237          common->quit = save_quit;
6238          }
6239        common->positive_assert = save_positive_assert;
6240      common->then_trap = save_then_trap;      common->then_trap = save_then_trap;
     common->quit_label = save_quit_label;  
6241      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
6242      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
6243      common->accept = save_accept;      common->accept = save_accept;
6244      return NULL;      return NULL;
6245      }      }
# Line 5701  while (1) Line 6252  while (1)
6252    cc += GET(cc, 1);    cc += GET(cc, 1);
6253    }    }
6254    
6255    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6256      {
6257      SLJIT_ASSERT(common->positive_assert_quit == NULL);
6258      /* Makes the check less complicated below. */
6259      common->positive_assert_quit = common->quit;
6260      }
6261    
6262  /* None of them matched. */  /* None of them matched. */
6263  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
6264    {    {
6265    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6266    set_jumps(common->quit, LABEL());    set_jumps(common->positive_assert_quit, LABEL());
6267    SLJIT_ASSERT(framesize != no_stack);    SLJIT_ASSERT(framesize != no_stack);
6268    if (framesize < 0)    if (framesize < 0)
6269      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
# Line 5865  else Line 6423  else
6423      }      }
6424    }    }
6425    
6426  common->local_exit = save_local_exit;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6427      {
6428      common->local_exit = save_local_exit;
6429      common->quit_label = save_quit_label;
6430      common->quit = save_quit;
6431      }
6432    common->positive_assert = save_positive_assert;
6433  common->then_trap = save_then_trap;  common->then_trap = save_then_trap;
 common->quit_label = save_quit_label;  
6434  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
6435  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
6436  common->accept = save_accept;  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 6116  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;
6574    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 6126  BOOL has_alternatives; Line 6582  BOOL has_alternatives;
6582  BOOL needs_control_head = FALSE;  BOOL needs_control_head = FALSE;
6583  struct sljit_jump *jump;  struct sljit_jump *jump;
6584  struct sljit_jump *skip;  struct sljit_jump *skip;
6585  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmax_label = NULL;
6586  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzero = NULL;
6587    
6588  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6589    
# Line 6140  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6596  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6596    
6597  opcode = *cc;  opcode = *cc;
6598  ccbegin = cc;  ccbegin = cc;
6599  matchingpath = ccbegin + 1 + LINK_SIZE;  matchingpath = bracketend(cc) - 1 - LINK_SIZE;
6600    ket = *matchingpath;
6601    if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
6602      {
6603      repeat_ptr = PRIVATE_DATA(matchingpath);
6604      repeat_length = PRIVATE_DATA(matchingpath + 1);
6605      repeat_type = PRIVATE_DATA(matchingpath + 2);
6606      repeat_count = PRIVATE_DATA(matchingpath + 3);
6607      SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
6608      if (repeat_type == OP_UPTO)
6609        ket = OP_KETRMAX;
6610      if (repeat_type == OP_MINUPTO)
6611        ket = OP_KETRMIN;
6612      }
6613    
6614  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
6615    {    {
6616    /* Drop this bracket_backtrack. */    /* Drop this bracket_backtrack. */
6617    parent->top = backtrack->prev;    parent->top = backtrack->prev;
6618    return bracketend(cc);    return matchingpath + 1 + LINK_SIZE + repeat_length;
6619    }    }
6620    
6621  ket = *(bracketend(cc) - 1 - LINK_SIZE);  matchingpath = ccbegin + 1 + LINK_SIZE;
6622  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
6623  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
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 6229  if (bra == OP_BRAMINZERO) Line 6686  if (bra == OP_BRAMINZERO)
6686    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
6687      {      {
6688      free_stack(common, 1);      free_stack(common, 1);
6689      braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);      braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6690      }      }
6691    else    else
6692      {      {
# Line 6244  if (bra == OP_BRAMINZERO) Line 6701  if (bra == OP_BRAMINZERO)
6701        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6702          {          {
6703          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
6704          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);          braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6705          }          }
6706        else        else
6707          {          {
6708          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
6709          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6710          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));          braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
6711          }          }
6712        JUMPHERE(skip);        JUMPHERE(skip);
6713        }        }
# Line 6263  if (bra == OP_BRAMINZERO) Line 6720  if (bra == OP_BRAMINZERO)
6720      }      }
6721    }    }
6722    
6723    if (repeat_type != 0)
6724      {
6725      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
6726      if (repeat_type == OP_EXACT)
6727        rmax_label = LABEL();
6728      }
6729    
6730  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
6731    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6732    
6733  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6734    {    {
6735    rmaxlabel = LABEL();    rmax_label = LABEL();
6736    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
6737      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
6738    }    }
6739    
6740  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
# Line 6398  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));  
6868    
6869      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      i = GET2(matchingpath, 1 + IMM2_SIZE);
6870      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6871      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
6872      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6873      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6874      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);      slot += common->name_entry_size;
6875      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      i--;
6876      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      while (i-- > 0)
6877      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));        {
6878          OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6879      JUMPHERE(jump);        OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
6880      matchingpath += 1 + IMM2_SIZE;        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 6447  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 6488  if (opcode == OP_ONCE) Line 6960  if (opcode == OP_ONCE)
6960    match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);    match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
6961    
6962  stacksize = 0;  stacksize = 0;
6963    if (repeat_type == OP_MINUPTO)
6964      {
6965      /* We need to preserve the counter. TMP2 will be used below. */
6966      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6967      stacksize++;
6968      }
6969  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6970    stacksize++;    stacksize++;
6971  if (offset != 0)  if (offset != 0)
# Line 6504  if (stacksize > 0) Line 6982  if (stacksize > 0)
6982    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6983    
6984  stacksize = 0;  stacksize = 0;
6985    if (repeat_type == OP_MINUPTO)
6986      {
6987      /* TMP2 was set above. */
6988      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
6989      stacksize++;
6990      }
6991    
6992  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6993    {    {
6994    if (ket != OP_KET)    if (ket != OP_KET)
# Line 6533  if (offset != 0 && common->optimized_cbr Line 7018  if (offset != 0 && common->optimized_cbr
7018    
7019  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7020    {    {
7021    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (repeat_type != 0)
7022        {
7023        if (has_alternatives)
7024          BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
7025        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
7026        JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
7027        /* Drop STR_PTR for greedy plus quantifier. */
7028        if (opcode != OP_ONCE)
7029          free_stack(common, 1);
7030        }
7031      else if (opcode == OP_ONCE || opcode >= OP_SBRA)
7032      {      {
7033      if (has_alternatives)      if (has_alternatives)
7034        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
7035      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
7036      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7037        {        {
7038        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmax_label);
7039        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
7040        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
7041          free_stack(common, 1);          free_stack(common, 1);
7042        }        }
7043      else      else
7044        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
7045        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
7046      }      }
7047    else    else
7048      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmax_label);
7049    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
7050    }    }
7051    
7052    if (repeat_type == OP_EXACT)
7053      {
7054      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
7055      JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
7056      }
7057    else if (repeat_type == OP_UPTO)
7058      {
7059      /* We need to preserve the counter. */
7060      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
7061      allocate_stack(common, 1);
7062      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7063      }
7064    
7065  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
7066    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
7067    
# Line 6561  if (bra == OP_BRAMINZERO) Line 7069  if (bra == OP_BRAMINZERO)
7069    {    {
7070    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
7071    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
7072    if (braminzerojump != NULL)    if (braminzero != NULL)
7073      {      {
7074      JUMPHERE(braminzerojump);      JUMPHERE(braminzero);
7075      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
7076      backtrack for the zero-length iteration. When      backtrack for the zero-length iteration. When
7077      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
# Line 6579  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 6589  cc += 1 + LINK_SIZE; Line 7097  cc += 1 + LINK_SIZE;
7097  /* Temporarily encoding the needs_control_head in framesize. */  /* Temporarily encoding the needs_control_head in framesize. */
7098  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
7099    BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);    BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
7100  return cc;  return cc + repeat_length;
7101  }  }
7102    
7103  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
# Line 6866  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 6906  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 6917  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 6939  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 6968  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 6981  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 7052  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 7082  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 7092  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 7134  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 7147  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 7171  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 7448  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 7456  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 7465  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 7503  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 7621  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 7630  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 7649  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 7659  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 7704  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 7744  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 7762  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 7777  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 7876  if (bra == OP_BRAZERO) Line 8437  if (bra == OP_BRAZERO)
8437  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8438  {  {
8439  DEFINE_COMPILER;  DEFINE_COMPILER;
8440  int opcode;  int opcode, stacksize, count;
8441  int offset = 0;  int offset = 0;
8442  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
8443  int stacksize;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
 int count;  
8444  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
8445  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
8446  pcre_uchar *ccprev;  pcre_uchar *ccprev;
# Line 7894  BOOL needs_control_head = FALSE; Line 8454  BOOL needs_control_head = FALSE;
8454  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
8455  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
8456  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
8457  struct sljit_label *rminlabel = NULL;  struct sljit_label *rmin_label = NULL;
8458    struct sljit_label *exact_label = NULL;
8459    
8460  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
8461    {    {
# Line 7903  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 8464  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
8464    }    }
8465    
8466  opcode = *cc;  opcode = *cc;
8467    ccbegin = bracketend(cc) - 1 - LINK_SIZE;
8468    ket = *ccbegin;
8469    if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
8470      {
8471      repeat_ptr = PRIVATE_DATA(ccbegin);
8472      repeat_type = PRIVATE_DATA(ccbegin + 2);
8473      repeat_count = PRIVATE_DATA(ccbegin + 3);
8474      SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
8475      if (repeat_type == OP_UPTO)
8476        ket = OP_KETRMAX;
8477      if (repeat_type == OP_MINUPTO)
8478        ket = OP_KETRMIN;
8479      }
8480  ccbegin = cc;  ccbegin = cc;
 ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  
8481  cc += GET(cc, 1);  cc += GET(cc, 1);
8482  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
8483  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
# Line 7923  if (opcode == OP_ONCE) Line 8496  if (opcode == OP_ONCE)
8496    CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;    CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
8497    }    }
8498    
8499    if (ket != OP_KET && repeat_type != 0)
8500      {
8501      /* TMP1 is used in OP_KETRMIN below. */
8502      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8503      free_stack(common, 1);
8504      if (repeat_type == OP_UPTO)
8505        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
8506      else
8507        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8508      }
8509    
8510  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
8511    {    {
8512    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7937  else if (ket == OP_KETRMIN) Line 8521  else if (ket == OP_KETRMIN)
8521    if (bra != OP_BRAMINZERO)    if (bra != OP_BRAMINZERO)
8522      {      {
8523      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8524      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (repeat_type != 0)
8525          {
8526          /* TMP1 was set a few lines above. */
8527          CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8528          /* Drop STR_PTR for non-greedy plus quantifier. */
8529          if (opcode != OP_ONCE)
8530            free_stack(common, 1);
8531          }
8532        else if (opcode >= OP_SBRA || opcode == OP_ONCE)
8533        {        {
8534        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
8535        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 7947  else if (ket == OP_KETRMIN) Line 8539  else if (ket == OP_KETRMIN)
8539          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8540          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8541          }          }
8542          /* Drop STR_PTR for non-greedy plus quantifier. */
8543        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
8544          free_stack(common, 1);          free_stack(common, 1);
8545        }        }
8546      else      else
8547        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8548      }      }
8549    rminlabel = LABEL();    rmin_label = LABEL();
8550      if (repeat_type != 0)
8551        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8552    }    }
8553  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
8554    {    {
# Line 7961  else if (bra == OP_BRAZERO) Line 8556  else if (bra == OP_BRAZERO)
8556    free_stack(common, 1);    free_stack(common, 1);
8557    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
8558    }    }
8559    else if (repeat_type == OP_EXACT)
8560      {
8561      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8562      exact_label = LABEL();
8563      }
8564    
8565  if (offset != 0)  if (offset != 0)
8566    {    {
# Line 8102  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);
8709    
8710      stacksize = 0;      stacksize = 0;
8711        if (repeat_type == OP_MINUPTO)
8712          {
8713          /* We need to preserve the counter. TMP2 will be used below. */
8714          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
8715          stacksize++;
8716          }
8717      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8718        stacksize++;        stacksize++;
8719      if (offset != 0)      if (offset != 0)
# Line 8121  if (has_alternatives) Line 8727  if (has_alternatives)
8727        stacksize++;        stacksize++;
8728    
8729      if (stacksize > 0)      if (stacksize > 0)
8730          allocate_stack(common, stacksize);
8731    
8732        stacksize = 0;
8733        if (repeat_type == OP_MINUPTO)
8734        {        {
8735        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        /* TMP2 was set above. */
8736          allocate_stack(common, stacksize);        OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
8737        else        stacksize++;
         {  
         /* We know we have place at least for one item on the top of the stack. */  
         SLJIT_ASSERT(stacksize == 1);  
         OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));  
         }  
8738        }        }
8739    
     stacksize = 0;  
8740      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8741        {        {
8742        if (ket != OP_KET)        if (ket != OP_KET)
# Line 8243  else if (opcode == OP_ONCE) Line 8847  else if (opcode == OP_ONCE)
8847      }      }
8848    }    }
8849    
8850  if (ket == OP_KETRMAX)  if (repeat_type == OP_EXACT)
8851      {
8852      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8853      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8854      CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
8855      }
8856    else if (ket == OP_KETRMAX)
8857    {    {
8858    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8859    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
8860      free_stack(common, 1);      free_stack(common, 1);
8861    
8862    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8863    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
8864      {      {
# Line 8266  else if (ket == OP_KETRMIN) Line 8877  else if (ket == OP_KETRMIN)
8877    affect badly the free_stack(2) above. */    affect badly the free_stack(2) above. */
8878    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
8879      free_stack(common, 1);      free_stack(common, 1);
8880    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
8881    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
8882      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
8883    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
# Line 8347  static SLJIT_INLINE void compile_control Line 8958  static SLJIT_INLINE void compile_control
8958  {  {
8959  DEFINE_COMPILER;  DEFINE_COMPILER;
8960  pcre_uchar opcode = *current->cc;  pcre_uchar opcode = *current->cc;
8961    struct sljit_label *loop;
8962    struct sljit_jump *jump;
8963    
8964  if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)  if (opcode == OP_THEN || opcode == OP_THEN_ARG)
8965    {    {
8966    SLJIT_ASSERT(common->control_head_ptr != 0);    if (common->then_trap != NULL)
8967    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);      {
8968    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);      SLJIT_ASSERT(common->control_head_ptr != 0);
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, common->then_trap->start);  
   sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_then_trap));  
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
8969    
8970    OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8971    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8972    if (common->quit_label == NULL)      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8973      add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));      jump = JUMP(SLJIT_JUMP);
   else  
     CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->quit_label);  
8974    
8975    OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);      loop = LABEL();
8976    add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8977    return;      JUMPHERE(jump);
8978        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8979        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8980        add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8981        return;
8982        }
8983      else if (common->positive_assert)
8984        {
8985        add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
8986        return;
8987        }
8988    }    }
8989    
8990  if (common->local_exit)  if (common->local_exit)
# Line 8521  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 8814  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 8829  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 8844  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA Line 9463  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA
9463  common->capture_last_ptr = common->ovector_start;  common->capture_last_ptr = common->ovector_start;
9464  common->ovector_start += sizeof(sljit_sw);  common->ovector_start += sizeof(sljit_sw);
9465  #endif  #endif
9466  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  if (!check_opcode_types(common, rootbacktrack.cc, ccend))
 if (private_data_size < 0)  
9467    {    {
9468    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9469    return;    return;
# Line 8907  if (common->capture_last_ptr != 0) Line 9525  if (common->capture_last_ptr != 0)
9525    
9526  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
9527  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
9528  private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);  
9529  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));
9530    if (!common->private_data_ptrs)
9531    {    {
9532    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9533    return;    return;
9534    }    }
9535    memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
9536    
9537  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
9538  if (!common->private_data_ptrs)  set_private_data_ptrs(common, &private_data_size, ccend);
9539    if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
9540    {    {
9541      SLJIT_FREE(common->private_data_ptrs);
9542    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9543    return;    return;
9544    }    }
 memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  
 set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  
9545    
9546  if (common->has_then)  if (common->has_then)
9547    {    {
# Line 8960  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 8987  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 9005  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 9225  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 9283  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 9337  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 9428  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 9547  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 9598  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.1290  
changed lines
  Added in v.1422

  ViewVC Help
Powered by ViewVC 1.1.5