/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1275 by zherczeg, Sun Mar 10 05:32:10 2013 UTC revision 1421 by zherczeg, Mon Dec 30 13:25:20 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 202  enum frame_types { Line 203  enum frame_types {
203  };  };
204    
205  enum control_types {  enum control_types {
206    type_commit = 0,    type_mark = 0,
207    type_prune = 1,    type_then_trap = 1
   type_skip = 2  
208  };  };
209    
210  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
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 227  typedef struct backtrack_common { Line 227  typedef struct backtrack_common {
227  typedef struct assert_backtrack {  typedef struct assert_backtrack {
228    backtrack_common common;    backtrack_common common;
229    jump_list *condfailed;    jump_list *condfailed;
230    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
231    int framesize;    int framesize;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int private_data_ptr;    int private_data_ptr;
# Line 248  typedef struct bracket_backtrack { Line 248  typedef struct bracket_backtrack {
248      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
249      jump_list *condfailed;      jump_list *condfailed;
250      assert_backtrack *assert;      assert_backtrack *assert;
251      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
252      int framesize;      int framesize;
253    } u;    } u;
254    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 283  typedef struct recurse_entry { Line 283  typedef struct recurse_entry {
283    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
284    jump_list *calls;    jump_list *calls;
285    /* Points to the starting opcode. */    /* Points to the starting opcode. */
286    int start;    sljit_sw start;
287  } recurse_entry;  } recurse_entry;
288    
289  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
# Line 291  typedef struct recurse_backtrack { Line 291  typedef struct recurse_backtrack {
291    BOOL inlined_pattern;    BOOL inlined_pattern;
292  } recurse_backtrack;  } recurse_backtrack;
293    
294  #define MAX_RANGE_SIZE 6  #define OP_THEN_TRAP OP_TABLE_LENGTH
295    
296    typedef struct then_trap_backtrack {
297      backtrack_common common;
298      /* If then_trap is not NULL, this structure contains the real
299      then_trap for the backtracking path. */
300      struct then_trap_backtrack *then_trap;
301      /* Points to the starting opcode. */
302      sljit_sw start;
303      /* Exit point for the then opcodes of this alternative. */
304      jump_list *quit;
305      /* Frame size of the current alternative. */
306      int framesize;
307    } then_trap_backtrack;
308    
309    #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 299  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. */
321      pcre_uint8 *then_offsets;
322      /* Current position where a THEN must jump. */
323      then_trap_backtrack *then_trap;
324    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
325    int cbra_ptr;    int cbra_ptr;
326    /* Output vector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
# Line 330  typedef struct compiler_common { Line 349  typedef struct compiler_common {
349    sljit_sw lcc;    sljit_sw lcc;
350    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
351    int mode;    int mode;
352    /* \K is in the pattern. */    /* \K is found in the pattern. */
353    BOOL has_set_som;    BOOL has_set_som;
354      /* (*SKIP:arg) is found in the pattern. */
355      BOOL has_skip_arg;
356      /* (*THEN) is found in the pattern. */
357      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 344  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 360  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 382  typedef struct compiler_common { Line 407  typedef struct compiler_common {
407    jump_list *utfreadchar;    jump_list *utfreadchar;
408  #endif  #endif
409  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
410      jump_list *utfreadchar11;
411    jump_list *utfreadtype8;    jump_list *utfreadtype8;
412  #endif  #endif
413  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
# Line 438  typedef struct compare_context { Line 464  typedef struct compare_context {
464  #define STACK_TOP     SLJIT_SCRATCH_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
465  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
466  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
467  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define COUNT_MATCH   SLJIT_SAVED_EREG2
468  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
469    
470  /* Local space layout. */  /* Local space layout. */
# Line 449  typedef struct compare_context { Line 475  typedef struct compare_context {
475  #define POSSESSIVE0      (2 * sizeof(sljit_sw))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
476  #define POSSESSIVE1      (3 * sizeof(sljit_sw))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
477  /* Max limit of recursions. */  /* Max limit of recursions. */
478  #define CALL_LIMIT       (4 * sizeof(sljit_sw))  #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
479  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
480  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
481  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
482  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. */
483  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
484  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
485  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
486  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
487    
488  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 507  cc += 1 + LINK_SIZE; Line 533  cc += 1 + LINK_SIZE;
533  return cc;  return cc;
534  }  }
535    
536    static int ones_in_half_byte[16] = {
537      /* 0 */ 0, 1, 1, 2, /* 4 */ 1, 2, 2, 3,
538      /* 8 */ 1, 2, 2, 3, /* 12 */ 2, 3, 3, 4
539    };
540    
541  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
542   next_opcode   next_opcode
543   get_private_data_length   check_opcode_types
544   set_private_data_ptrs   set_private_data_ptrs
545   get_framesize   get_framesize
546   init_frame   init_frame
547   get_private_data_length_for_copy   get_private_data_copy_length
548   copy_private_data   copy_private_data
549   compile_matchingpath   compile_matchingpath
550   compile_backtrackingpath   compile_backtrackingpath
# Line 559  switch(*cc) Line 590  switch(*cc)
590    case OP_CRMINQUERY:    case OP_CRMINQUERY:
591    case OP_CRRANGE:    case OP_CRRANGE:
592    case OP_CRMINRANGE:    case OP_CRMINRANGE:
593      case OP_CRPOSSTAR:
594      case OP_CRPOSPLUS:
595      case OP_CRPOSQUERY:
596      case OP_CRPOSRANGE:
597    case OP_CLASS:    case OP_CLASS:
598    case OP_NCLASS:    case OP_NCLASS:
599    case OP_REF:    case OP_REF:
600    case OP_REFI:    case OP_REFI:
601      case OP_DNREF:
602      case OP_DNREFI:
603    case OP_RECURSE:    case OP_RECURSE:
604    case OP_CALLOUT:    case OP_CALLOUT:
605    case OP_ALT:    case OP_ALT:
# Line 588  switch(*cc) Line 625  switch(*cc)
625    case OP_SCBRAPOS:    case OP_SCBRAPOS:
626    case OP_SCOND:    case OP_SCOND:
627    case OP_CREF:    case OP_CREF:
628    case OP_NCREF:    case OP_DNCREF:
629    case OP_RREF:    case OP_RREF:
630    case OP_NRREF:    case OP_DNRREF:
631    case OP_DEF:    case OP_DEF:
632    case OP_BRAZERO:    case OP_BRAZERO:
633    case OP_BRAMINZERO:    case OP_BRAMINZERO:
634    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
635    case OP_PRUNE:    case OP_PRUNE:
636    case OP_SKIP:    case OP_SKIP:
637      case OP_THEN:
638    case OP_COMMIT:    case OP_COMMIT:
639    case OP_FAIL:    case OP_FAIL:
640    case OP_ACCEPT:    case OP_ACCEPT:
# Line 696  switch(*cc) Line 734  switch(*cc)
734    
735    case OP_MARK:    case OP_MARK:
736    case OP_PRUNE_ARG:    case OP_PRUNE_ARG:
737      case OP_SKIP_ARG:
738      case OP_THEN_ARG:
739    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
740    
741    default:    default:
742      /* All opcodes are supported now! */
743      SLJIT_ASSERT_STOP();
744    return NULL;    return NULL;
745    }    }
746  }  }
747    
748  #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)  
749  {  {
750  switch(*cc)  int count;
751    {  pcre_uchar *slot;
   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)  
 {  
 int private_data_length = 0;  
 pcre_uchar *alternative;  
 pcre_uchar *name;  
 pcre_uchar *end = NULL;  
 int space, size, i;  
 pcre_uint32 bracketlen;  
752    
753  /* 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. */
754  while (cc < ccend)  while (cc < ccend)
755    {    {
   space = 0;  
   size = 0;  
   bracketlen = 0;  
756    switch(*cc)    switch(*cc)
757      {      {
758      case OP_SET_SOM:      case OP_SET_SOM:
# Line 808  while (cc < ccend) Line 766  while (cc < ccend)
766      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
767      break;      break;
768    
     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;  
   
769      case OP_CBRAPOS:      case OP_CBRAPOS:
770      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     private_data_length += sizeof(sljit_sw);  
771      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
772      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
773      break;      break;
774    
775      case OP_COND:      case OP_COND:
# Line 833  while (cc < ccend) Line 777  while (cc < ccend)
777      /* Only AUTO_CALLOUT can insert this opcode. We do      /* Only AUTO_CALLOUT can insert this opcode. We do
778         not intend to support this case. */         not intend to support this case. */
779      if (cc[1 + LINK_SIZE] == OP_CALLOUT)      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
780        return -1;        return FALSE;
781        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;  
782      break;      break;
783    
784      case OP_CREF:      case OP_CREF:
785      i = GET2(cc, 1);      common->optimized_cbracket[GET2(cc, 1)] = 0;
     common->optimized_cbracket[i] = 0;  
786      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
787      break;      break;
788    
789      case OP_NCREF:      case OP_DNREF:
790      bracketlen = GET2(cc, 1);      case OP_DNREFI:
791      name = (pcre_uchar *)common->name_table;      case OP_DNCREF:
792      alternative = name;      count = GET2(cc, 1 + IMM2_SIZE);
793      for (i = 0; i < common->name_count; i++)      slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
794        while (count-- > 0)
795        {        {
796        if (GET2(name, 0) == bracketlen) break;        common->optimized_cbracket[GET2(slot, 0)] = 0;
797        name += common->name_entry_size;        slot += common->name_entry_size;
798        }        }
799      SLJIT_ASSERT(i != common->name_count);      cc += 1 + 2 * IMM2_SIZE;
   
     for (i = 0; i < common->name_count; i++)  
       {  
       if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)  
         common->optimized_cbracket[GET2(alternative, 0)] = 0;  
       alternative += common->name_entry_size;  
       }  
     bracketlen = 0;  
     cc += 1 + IMM2_SIZE;  
     break;  
   
     case OP_BRA:  
     bracketlen = 1 + LINK_SIZE;  
800      break;      break;
801    
     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);  
     break;  
 #endif  
   
802      case OP_RECURSE:      case OP_RECURSE:
803      /* Set its value only once. */      /* Set its value only once. */
804      if (common->recursive_head_ptr == 0)      if (common->recursive_head_ptr == 0)
# Line 947  while (cc < ccend) Line 818  while (cc < ccend)
818      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
819      break;      break;
820    
821        case OP_THEN_ARG:
822        common->has_then = TRUE;
823        common->control_head_ptr = 1;
824        /* Fall through. */
825    
826      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
827      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
     common->control_head_ptr = 1;  
828      /* Fall through. */      /* Fall through. */
829    
830      case OP_MARK:      case OP_MARK:
# Line 961  while (cc < ccend) Line 836  while (cc < ccend)
836      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
837      break;      break;
838    
839        case OP_THEN:
840        common->has_then = TRUE;
841        common->control_head_ptr = 1;
842        /* Fall through. */
843    
844      case OP_PRUNE:      case OP_PRUNE:
845      case OP_SKIP:      case OP_SKIP:
846      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
847      /* Fall through. */      cc += 1;
848        break;
849    
850      case OP_COMMIT:      case OP_SKIP_ARG:
851      common->control_head_ptr = 1;      common->control_head_ptr = 1;
852      cc += 1;      common->has_skip_arg = TRUE;
853        cc += 1 + 2 + cc[1];
854      break;      break;
855    
856      default:      default:
857      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
858      if (cc == NULL)      if (cc == NULL)
859        return -1;        return FALSE;
860      break;      break;
861      }      }
862      }
863    return TRUE;
864    }
865    
866    if (space > 0 && cc >= end)  static int get_class_iterator_size(pcre_uchar *cc)
867      private_data_length += sizeof(sljit_sw) * space;  {
868    switch(*cc)
869      {
870      case OP_CRSTAR:
871      case OP_CRPLUS:
872      return 2;
873    
874    if (size != 0)    case OP_CRMINSTAR:
875      case OP_CRMINPLUS:
876      case OP_CRQUERY:
877      case OP_CRMINQUERY:
878      return 1;
879    
880      case OP_CRRANGE:
881      case OP_CRMINRANGE:
882      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
883        return 0;
884      return 2;
885    
886      default:
887      return 0;
888      }
889    }
890    
891    static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
892    {
893    pcre_uchar *end = bracketend(begin);
894    pcre_uchar *next;
895    pcre_uchar *next_end;
896    pcre_uchar *max_end;
897    pcre_uchar type;
898    sljit_sw length = end - begin;
899    int min, max, i;
900    
901    /* Detect fixed iterations first. */
902    if (end[-(1 + LINK_SIZE)] != OP_KET)
903      return FALSE;
904    
905    /* Already detected repeat. */
906    if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
907      return TRUE;
908    
909    next = end;
910    min = 1;
911    while (1)
912      {
913      if (*next != *begin)
914        break;
915      next_end = bracketend(next);
916      if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
917        break;
918      next = next_end;
919      min++;
920      }
921    
922    if (min == 2)
923      return FALSE;
924    
925    max = 0;
926    max_end = next;
927    if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
928      {
929      type = *next;
930      while (1)
931      {      {
932      if (size < 0)      if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
933        {        break;
934        cc += -size;      next_end = bracketend(next + 2 + LINK_SIZE);
935  #ifdef SUPPORT_UTF      if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
936        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        break;
937  #endif      next = next_end;
938        }      max++;
     else  
       cc += size;  
939      }      }
940    
941    if (bracketlen != 0)    if (next[0] == type && next[1] == *begin && max >= 1)
942      {      {
943      if (cc >= end)      next_end = bracketend(next + 1);
944        if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
945        {        {
946        end = bracketend(cc);        for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
947        if (end[-1 - LINK_SIZE] == OP_KET)          if (*next_end != OP_KET)
948          end = NULL;            break;
949    
950          if (i == max)
951            {
952            common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
953            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
954            /* +2 the original and the last. */
955            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
956            if (min == 1)
957              return TRUE;
958            min--;
959            max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
960            }
961        }        }
     cc += bracketlen;  
962      }      }
963    }    }
964  return private_data_length;  
965    if (min >= 3)
966      {
967      common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
968      common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
969      common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
970      return TRUE;
971      }
972    
973    return FALSE;
974  }  }
975    
976  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
977        case OP_MINSTAR: \
978        case OP_MINPLUS: \
979        case OP_QUERY: \
980        case OP_MINQUERY: \
981        case OP_MINSTARI: \
982        case OP_MINPLUSI: \
983        case OP_QUERYI: \
984        case OP_MINQUERYI: \
985        case OP_NOTMINSTAR: \
986        case OP_NOTMINPLUS: \
987        case OP_NOTQUERY: \
988        case OP_NOTMINQUERY: \
989        case OP_NOTMINSTARI: \
990        case OP_NOTMINPLUSI: \
991        case OP_NOTQUERYI: \
992        case OP_NOTMINQUERYI:
993    
994    #define CASE_ITERATOR_PRIVATE_DATA_2A \
995        case OP_STAR: \
996        case OP_PLUS: \
997        case OP_STARI: \
998        case OP_PLUSI: \
999        case OP_NOTSTAR: \
1000        case OP_NOTPLUS: \
1001        case OP_NOTSTARI: \
1002        case OP_NOTPLUSI:
1003    
1004    #define CASE_ITERATOR_PRIVATE_DATA_2B \
1005        case OP_UPTO: \
1006        case OP_MINUPTO: \
1007        case OP_UPTOI: \
1008        case OP_MINUPTOI: \
1009        case OP_NOTUPTO: \
1010        case OP_NOTMINUPTO: \
1011        case OP_NOTUPTOI: \
1012        case OP_NOTMINUPTOI:
1013    
1014    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1015        case OP_TYPEMINSTAR: \
1016        case OP_TYPEMINPLUS: \
1017        case OP_TYPEQUERY: \
1018        case OP_TYPEMINQUERY:
1019    
1020    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1021        case OP_TYPESTAR: \
1022        case OP_TYPEPLUS:
1023    
1024    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1025        case OP_TYPEUPTO: \
1026        case OP_TYPEMINUPTO:
1027    
1028    static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1029  {  {
1030  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1031  pcre_uchar *alternative;  pcre_uchar *alternative;
1032  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
1033    int private_data_ptr = *private_data_start;
1034  int space, size, bracketlen;  int space, size, bracketlen;
1035    
1036  while (cc < ccend)  while (cc < ccend)
# Line 1020  while (cc < ccend) Line 1038  while (cc < ccend)
1038    space = 0;    space = 0;
1039    size = 0;    size = 0;
1040    bracketlen = 0;    bracketlen = 0;
1041      if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1042        return;
1043    
1044      if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
1045        if (detect_repeat(common, cc))
1046          {
1047          /* These brackets are converted to repeats, so no global
1048          based single character repeat is allowed. */
1049          if (cc >= end)
1050            end = bracketend(cc);
1051          }
1052    
1053    switch(*cc)    switch(*cc)
1054      {      {
1055        case OP_KET:
1056        if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1057          {
1058          common->private_data_ptrs[cc - common->start] = private_data_ptr;
1059          private_data_ptr += sizeof(sljit_sw);
1060          cc += common->private_data_ptrs[cc + 1 - common->start];
1061          }
1062        cc += 1 + LINK_SIZE;
1063        break;
1064    
1065      case OP_ASSERT:      case OP_ASSERT:
1066      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1067      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1115  while (cc < ccend) Line 1155  while (cc < ccend)
1155      break;      break;
1156      }      }
1157    
1158      /* Character iterators, which are not inside a repeated bracket,
1159         gets a private slot instead of allocating it on the stack. */
1160    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1161      {      {
1162      common->private_data_ptrs[cc - common->start] = private_data_ptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
# Line 1145  while (cc < ccend) Line 1187  while (cc < ccend)
1187      cc += bracketlen;      cc += bracketlen;
1188      }      }
1189    }    }
1190    *private_data_start = private_data_ptr;
1191  }  }
1192    
1193  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1194  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
1195  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1196  int length = 0;  int length = 0;
1197  int possessive = 0;  int possessive = 0;
1198  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1159  BOOL setmark_found = recursive; Line 1201  BOOL setmark_found = recursive;
1201  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1202  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1203    
1204  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1205    SLJIT_ASSERT(common->control_head_ptr != 0);
1206    *needs_control_head = TRUE;
1207    #else
1208    *needs_control_head = FALSE;
1209    #endif
1210    
1211    if (ccend == NULL)
1212    {    {
1213    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1214    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1215    capture_last_found = TRUE;      {
1216        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1217        /* This is correct regardless of common->capture_last_ptr. */
1218        capture_last_found = TRUE;
1219        }
1220      cc = next_opcode(common, cc);
1221    }    }
1222    
 cc = next_opcode(common, cc);  
1223  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1224  while (cc < ccend)  while (cc < ccend)
1225    switch(*cc)    switch(*cc)
# Line 1184  while (cc < ccend) Line 1237  while (cc < ccend)
1237    
1238      case OP_MARK:      case OP_MARK:
1239      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1240        case OP_THEN_ARG:
1241      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1242      stack_restore = TRUE;      stack_restore = TRUE;
1243      if (!setmark_found)      if (!setmark_found)
# Line 1191  while (cc < ccend) Line 1245  while (cc < ccend)
1245        length += 2;        length += 2;
1246        setmark_found = TRUE;        setmark_found = TRUE;
1247        }        }
1248        if (common->control_head_ptr != 0)
1249          *needs_control_head = TRUE;
1250      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1251      break;      break;
1252    
# Line 1310  if (length > 0) Line 1366  if (length > 0)
1366  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1367  }  }
1368    
1369  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1370  {  {
1371  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1372  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1373  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1374  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
# Line 1325  SLJIT_UNUSED_ARG(stacktop); Line 1380  SLJIT_UNUSED_ARG(stacktop);
1380  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1381    
1382  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1383  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1384    cc = next_opcode(common, cc);    {
1385      ccend = bracketend(cc) - (1 + LINK_SIZE);
1386      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1387        cc = next_opcode(common, cc);
1388      }
1389    
1390  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1391  while (cc < ccend)  while (cc < ccend)
1392    switch(*cc)    switch(*cc)
# Line 1347  while (cc < ccend) Line 1407  while (cc < ccend)
1407    
1408      case OP_MARK:      case OP_MARK:
1409      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1410        case OP_THEN_ARG:
1411      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1412      if (!setmark_found)      if (!setmark_found)
1413        {        {
# Line 1427  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1488  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1488  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1489  }  }
1490    
1491  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1492  {  {
1493  int private_data_length = common->control_head_ptr ? 3 : 2;  int private_data_length = needs_control_head ? 3 : 2;
1494  int size;  int size;
1495  pcre_uchar *alternative;  pcre_uchar *alternative;
1496  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1438  while (cc < ccend) Line 1499  while (cc < ccend)
1499    size = 0;    size = 0;
1500    switch(*cc)    switch(*cc)
1501      {      {
1502        case OP_KET:
1503        if (PRIVATE_DATA(cc) != 0)
1504          private_data_length++;
1505        cc += 1 + LINK_SIZE;
1506        break;
1507    
1508      case OP_ASSERT:      case OP_ASSERT:
1509      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1510      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1542  return private_data_length; Line 1609  return private_data_length;
1609  }  }
1610    
1611  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1612    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1613  {  {
1614  DEFINE_COMPILER;  DEFINE_COMPILER;
1615  int srcw[2];  int srcw[2];
# Line 1563  stacktop = STACK(stacktop - 1); Line 1630  stacktop = STACK(stacktop - 1);
1630    
1631  if (!save)  if (!save)
1632    {    {
1633    stackptr += (common->control_head_ptr ? 2 : 1) * sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1634    if (stackptr < stacktop)    if (stackptr < stacktop)
1635      {      {
1636      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1588  do Line 1655  do
1655      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1656      count = 1;      count = 1;
1657      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1658      if (common->control_head_ptr != 0)      if (needs_control_head)
1659        {        {
1660          SLJIT_ASSERT(common->control_head_ptr != 0);
1661        count = 2;        count = 2;
1662        srcw[1] = common->control_head_ptr;        srcw[1] = common->control_head_ptr;
1663        }        }
# Line 1605  do Line 1673  do
1673    
1674      switch(*cc)      switch(*cc)
1675        {        {
1676          case OP_KET:
1677          if (PRIVATE_DATA(cc) != 0)
1678            {
1679            count = 1;
1680            srcw[0] = PRIVATE_DATA(cc);
1681            }
1682          cc += 1 + LINK_SIZE;
1683          break;
1684    
1685        case OP_ASSERT:        case OP_ASSERT:
1686        case OP_ASSERT_NOT:        case OP_ASSERT_NOT:
1687        case OP_ASSERTBACK:        case OP_ASSERTBACK:
# Line 1851  if (save) Line 1928  if (save)
1928  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1929  }  }
1930    
1931    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1932    {
1933    pcre_uchar *end = bracketend(cc);
1934    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1935    
1936    /* Assert captures then. */
1937    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1938      current_offset = NULL;
1939    /* Conditional block does not. */
1940    if (*cc == OP_COND || *cc == OP_SCOND)
1941      has_alternatives = FALSE;
1942    
1943    cc = next_opcode(common, cc);
1944    if (has_alternatives)
1945      current_offset = common->then_offsets + (cc - common->start);
1946    
1947    while (cc < end)
1948      {
1949      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1950        cc = set_then_offsets(common, cc, current_offset);
1951      else
1952        {
1953        if (*cc == OP_ALT && has_alternatives)
1954          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1955        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1956          *current_offset = 1;
1957        cc = next_opcode(common, cc);
1958        }
1959      }
1960    
1961    return end;
1962    }
1963    
1964  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1965  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1966  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1914  while (list_item) Line 2024  while (list_item)
2024  common->stubs = NULL;  common->stubs = NULL;
2025  }  }
2026    
2027  static SLJIT_INLINE void decrease_call_count(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2028  {  {
2029  DEFINE_COMPILER;  DEFINE_COMPILER;
2030    
2031  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);
2032  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
2033  }  }
2034    
# Line 1998  else Line 2108  else
2108  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2109  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2110    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2111  SLJIT_ASSERT(common->control_head_ptr != 0);  if (common->control_head_ptr != 0)
2112  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2113  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2114  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2115  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2116  }  }
2117    
2118  static sljit_sw do_check_control_chain(sljit_sw *current)  static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2119  {  {
2120  sljit_sw return_value = 0;  while (current != NULL)
   
 SLJIT_ASSERT(current != NULL);  
 do  
2121    {    {
2122    switch (current[-2])    switch (current[-2])
2123      {      {
2124      case type_commit:      case type_then_trap:
     /* Commit overwrites all. */  
     return -1;  
   
     case type_prune:  
2125      break;      break;
2126    
2127      case type_skip:      case type_mark:
2128      /* Overwrites prune, but not other skips. */      if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2129      if (return_value == 0)        return current[-4];
       return_value = current[-3];  
2130      break;      break;
2131    
2132      default:      default:
# Line 2033  do Line 2135  do
2135      }      }
2136    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
2137    }    }
2138  while (current != NULL);  return -1;
 return return_value;  
2139  }  }
2140    
2141  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
# Line 2106  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 2207  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2207  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2208    
2209  jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);  jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2210  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);
2211  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2212  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2213  #endif  #endif
# Line 2274  return (bit < 256) ? ((0 << 8) | bit) : Line 2375  return (bit < 256) ? ((0 << 8) | bit) :
2375    
2376  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
2377  {  {
2378  /* Checks whether a partial matching is occured. Does not modify registers. */  /* Checks whether a partial matching is occurred. Does not modify registers. */
2379  DEFINE_COMPILER;  DEFINE_COMPILER;
2380  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2381    
# Line 2371  struct sljit_jump *jump; Line 2472  struct sljit_jump *jump;
2472  #endif  #endif
2473    
2474  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2475    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2476  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2477  if (common->utf)  if (common->utf)
2478    {    {
# Line 2383  if (common->utf) Line 2485  if (common->utf)
2485    JUMPHERE(jump);    JUMPHERE(jump);
2486    }    }
2487  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
2488  }  }
2489    
2490  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 2404  if (common->utf) Line 2505  if (common->utf)
2505  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
2506    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2507  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE[8|16] */
2508      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2509    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2510    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2511    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2411  if (common->utf) Line 2513  if (common->utf)
2513  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2514  }  }
2515    
2516  static void read_char8_type(compiler_common *common)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2517    
2518    static BOOL is_char7_bitset(const pcre_uint8* bitset, BOOL nclass)
2519    {
2520    const pcre_uint8 value = nclass ? 0xff : 0;
2521    const pcre_uint8* end = bitset + 32;
2522    
2523    bitset += 16;
2524    do
2525      {
2526      if (*bitset++ != value)
2527        return FALSE;
2528      }
2529    while (bitset < end);
2530    return TRUE;
2531    }
2532    
2533    static void read_char7_type(compiler_common *common, BOOL full_read)
2534    {
2535    /* Reads the precise character type of a character into TMP1, if the character is
2536    less than 128. Otherwise it returns with zero. */
2537    DEFINE_COMPILER;
2538    struct sljit_jump *jump;
2539    
2540    SLJIT_ASSERT(common->utf);
2541    
2542    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2543    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2544    
2545    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2546    
2547    if (full_read)
2548      {
2549      jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2550      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2551      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2552      JUMPHERE(jump);
2553      }
2554    }
2555    
2556    #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2557    
2558    static void read_char_max(compiler_common *common, pcre_uint32 max, BOOL full_read)
2559    {
2560    /* Reads the precise value of a character into TMP1, if the character is
2561    less than or equal to max. Otherwise it returns with a value greater than max. */
2562    DEFINE_COMPILER;
2563    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2564    struct sljit_jump *jump;
2565    #endif
2566    
2567    SLJIT_UNUSED_ARG(full_read);
2568    SLJIT_UNUSED_ARG(max);
2569    
2570    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2571    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2572    
2573    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2574    if (common->utf)
2575      {
2576      if (max < 128 && !full_read)
2577        return;
2578    
2579      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2580      if (max < 128)
2581        {
2582        OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2583        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2584        }
2585      else if (max < 0x400)
2586        {
2587        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2588        if (!full_read)
2589          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2590        else
2591          OP1(SLJIT_MOV_UB, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2592        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2593        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2594        OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2595        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2596        if (full_read)
2597          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0);
2598        }
2599      else
2600        add_jump(compiler, (max < 0x800) ? &common->utfreadchar11 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2601      JUMPHERE(jump);
2602      }
2603    #endif
2604    
2605    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2606    if (common->utf)
2607      {
2608      if (max < 0xd800 && !full_read)
2609        return;
2610    
2611      if (max >= 0x10000)
2612        {
2613        jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2614        add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2615        JUMPHERE(jump);
2616        return;
2617        }
2618    
2619      /* Skip low surrogate if necessary. */
2620      OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2621      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2622      if (full_read)
2623        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2624      if (max >= 0xd800)
2625        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000);
2626      JUMPHERE(jump);
2627      }
2628    #endif
2629    }
2630    
2631    static void read_char8_type(compiler_common *common, BOOL full_read)
2632  {  {
2633  /* 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. */
2634  DEFINE_COMPILER;  DEFINE_COMPILER;
2635  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2636  struct sljit_jump *jump;  struct sljit_jump *jump;
2637  #endif  #endif
2638    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2639    struct sljit_jump *jump2;
2640    #endif
2641    
2642  #ifdef SUPPORT_UTF  SLJIT_UNUSED_ARG(full_read);
2643    
2644    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2645    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2646    
2647    #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2648  if (common->utf)  if (common->utf)
2649    {    {
   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  
2650    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2651    it is needed in most cases. */    it is needed in most cases. */
2652    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2653    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2654    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    if (!full_read)
2655    JUMPHERE(jump);      {
2656  #elif defined COMPILE_PCRE16      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2657    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2658    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2659    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2660    JUMPHERE(jump);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2661    /* Skip low surrogate if necessary. */      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, TMP1, 0);
2662    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2663    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);      jump2 = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2664    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2665    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      JUMPHERE(jump2);
2666    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);      }
2667  #elif defined COMPILE_PCRE32    else
2668    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);  
2669    JUMPHERE(jump);    JUMPHERE(jump);
 #endif /* COMPILE_PCRE[8|16|32] */  
2670    return;    return;
2671    }    }
2672  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
2673  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
2674  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  
2675  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2676  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2677  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2678  #endif  #endif
2679  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2680  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if !defined COMPILE_PCRE8
2681  JUMPHERE(jump);  JUMPHERE(jump);
2682  #endif  #endif
2683    
2684    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2685    if (common->utf && full_read)
2686      {
2687      /* Skip low surrogate if necessary. */
2688      OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2689      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1);
2690      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2691      JUMPHERE(jump);
2692      }
2693    #endif /* SUPPORT_UTF && COMPILE_PCRE16 */
2694  }  }
2695    
2696  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
# Line 2539  sljit_emit_fast_enter(compiler, RETURN_A Line 2768  sljit_emit_fast_enter(compiler, RETURN_A
2768  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, 0x20);
2769  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2770  /* Two byte sequence. */  /* Two byte sequence. */
2771  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2772  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));
2773  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2774  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2775  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2776  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2777  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2778  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2779  JUMPHERE(jump);  JUMPHERE(jump);
2780    
2781  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, 0x10);
2782  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2783  /* Three byte sequence. */  /* Three byte sequence. */
2784  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2785  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2786  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2787  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2788  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2789  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2790  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2791  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2792  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2793  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2794  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
2795  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2796  JUMPHERE(jump);  JUMPHERE(jump);
2797    
2798  /* Four byte sequence. */  /* Four byte sequence. */
2799  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2800  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2801  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2802  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2803  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2804  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2805  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2806  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2807  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2808  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2809  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2810  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2811  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2812  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2813  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4));
2814    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2815    }
2816    
2817    static void do_utfreadchar11(compiler_common *common)
2818    {
2819    /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2820    of the character (>= 0xc0). Return value in TMP1. */
2821    DEFINE_COMPILER;
2822    struct sljit_jump *jump;
2823    
2824    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2825    
2826    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2827    jump = JUMP(SLJIT_C_NOT_ZERO);
2828    /* Two byte sequence. */
2829    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2830    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2831    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2832    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2833    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2834    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2835    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2836    
2837    JUMPHERE(jump);
2838    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2839    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x800);
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2841  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2842  }  }
2843    
# Line 2601  jump = JUMP(SLJIT_C_NOT_ZERO); Line 2857  jump = JUMP(SLJIT_C_NOT_ZERO);
2857  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2858  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));
2859  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2860    /* The upper 5 bits are known at this point. */
2861    compare = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 0x3);
2862  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2863  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
2864  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);  
2865  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2866  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2867    
2868  JUMPHERE(compare);  JUMPHERE(compare);
2869  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2870  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
2871    
2872  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2873  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);  JUMPHERE(jump);
2874  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2875  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2876    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2877  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2878  }  }
2879    
# Line 2636  sljit_emit_fast_return(compiler, RETURN_ Line 2893  sljit_emit_fast_return(compiler, RETURN_
2893    
2894  JUMPHERE(jump);  JUMPHERE(jump);
2895  /* Combine two 16 bit characters. */  /* Combine two 16 bit characters. */
2896  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2897  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));
2898  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2899  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2900  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2901  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2902  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2903  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2904  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2905  }  }
# Line 2798  if (newlinecheck) Line 3055  if (newlinecheck)
3055  return mainloop;  return mainloop;
3056  }  }
3057    
3058  #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)  
3059  {  {
3060  DEFINE_COMPILER;  /* Recursive function, which scans prefix literals. */
3061  struct sljit_label *start;  int len, repeat, len_save, consumed = 0;
3062  struct sljit_jump *quit;  pcre_uint32 caseless, chr, mask;
3063  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uchar *alternative, *cc_save;
3064  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;  
3065    
3066    repeat = 1;
3067  while (TRUE)  while (TRUE)
3068    {    {
3069      last = TRUE;
3070      any = FALSE;
3071    caseless = 0;    caseless = 0;
3072    must_stop = 1;    switch (*cc)
   switch(*cc)  
3073      {      {
     case OP_CHAR:  
     must_stop = 0;  
     cc++;  
     break;  
   
3074      case OP_CHARI:      case OP_CHARI:
3075      caseless = 1;      caseless = 1;
3076      must_stop = 0;      case OP_CHAR:
3077        last = FALSE;
3078      cc++;      cc++;
3079      break;      break;
3080    
# Line 2853  while (TRUE) Line 3099  while (TRUE)
3099      cc++;      cc++;
3100      break;      break;
3101    
3102        case OP_EXACTI:
3103        caseless = 1;
3104      case OP_EXACT:      case OP_EXACT:
3105        repeat = GET2(cc, 1);
3106        last = FALSE;
3107      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
3108      break;      break;
3109    
# Line 2864  while (TRUE) Line 3114  while (TRUE)
3114      cc++;      cc++;
3115      break;      break;
3116    
3117      case OP_EXACTI:      case OP_KET:
3118      caseless = 1;      cc += 1 + LINK_SIZE;
3119      cc += 1 + IMM2_SIZE;      continue;
3120    
3121        case OP_ALT:
3122        cc += GET(cc, 1);
3123        continue;
3124    
3125        case OP_ONCE:
3126        case OP_ONCE_NC:
3127        case OP_BRA:
3128        case OP_BRAPOS:
3129        case OP_CBRA:
3130        case OP_CBRAPOS:
3131        alternative = cc + GET(cc, 1);
3132        while (*alternative == OP_ALT)
3133          {
3134          max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, max_chars);
3135          if (max_chars == 0)
3136            return consumed;
3137          alternative += GET(alternative, 1);
3138          }
3139    
3140        if (*cc == OP_CBRA || *cc == OP_CBRAPOS)
3141          cc += IMM2_SIZE;
3142        cc += 1 + LINK_SIZE;
3143        continue;
3144    
3145        case OP_CLASS:
3146        case OP_NCLASS:
3147        any = TRUE;
3148        cc += 1 + 32 / sizeof(pcre_uchar);
3149      break;      break;
3150    
3151      default:  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3152      must_stop = 2;      case OP_XCLASS:
3153        any = TRUE;
3154        cc += GET(cc, 1);
3155        break;
3156    #endif
3157    
3158        case OP_NOT_DIGIT:
3159        case OP_DIGIT:
3160        case OP_NOT_WHITESPACE:
3161        case OP_WHITESPACE:
3162        case OP_NOT_WORDCHAR:
3163        case OP_WORDCHAR:
3164        case OP_ANY:
3165        case OP_ALLANY:
3166        any = TRUE;
3167        cc++;
3168        break;
3169    
3170    #ifdef SUPPORT_UCP
3171        case OP_NOTPROP:
3172        case OP_PROP:
3173        any = TRUE;
3174        cc += 1 + 2;
3175      break;      break;
3176    #endif
3177    
3178        case OP_TYPEEXACT:
3179        repeat = GET2(cc, 1);
3180        cc += 1 + IMM2_SIZE;
3181        continue;
3182    
3183        default:
3184        return consumed;
3185      }      }
3186    
3187    if (must_stop == 2)    if (any)
3188        break;      {
3189    #ifdef SUPPORT_UTF
3190        if (common->utf) return consumed;
3191    #endif
3192    #if defined COMPILE_PCRE8
3193        mask = 0xff;
3194    #elif defined COMPILE_PCRE16
3195        mask = 0xffff;
3196    #elif defined COMPILE_PCRE32
3197        mask = 0xffffffff;
3198    #else
3199        SLJIT_ASSERT_STOP();
3200    #endif
3201    
3202        do
3203          {
3204          chars[0] = mask;
3205          chars[1] = mask;
3206    
3207          if (--max_chars == 0)
3208            return consumed;
3209          consumed++;
3210          chars += 2;
3211          }
3212        while (--repeat > 0);
3213    
3214        repeat = 1;
3215        continue;
3216        }
3217    
3218    len = 1;    len = 1;
3219  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3220    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
3221  #endif  #endif
3222    
3223    if (caseless && char_has_othercase(common, cc))    if (caseless != 0 && char_has_othercase(common, cc))
3224      {      {
3225      caseless = char_get_othercase_bit(common, cc);      caseless = char_get_othercase_bit(common, cc);
3226      if (caseless == 0)      if (caseless == 0)
3227        return FALSE;        return consumed;
3228  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3229      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
3230  #else  #else
# Line 2899  while (TRUE) Line 3237  while (TRUE)
3237    else    else
3238      caseless = 0;      caseless = 0;
3239    
3240    while (len > 0 && location < MAX_N_CHARS * 2)    len_save = len;
3241      {    cc_save = cc;
3242      c = *cc;    while (TRUE)
3243      bit = 0;      {
3244      if (len == (caseless & 0xff))      do
3245        {        {
3246        bit = caseless >> 8;        chr = *cc;
3247        c |= bit;  #ifdef COMPILE_PCRE32
3248          if (SLJIT_UNLIKELY(chr == NOTACHAR))
3249            return consumed;
3250    #endif
3251          mask = 0;
3252          if (len == (caseless & 0xff))
3253            {
3254            mask = caseless >> 8;
3255            chr |= mask;
3256            }
3257    
3258          if (chars[0] == NOTACHAR)
3259            {
3260            chars[0] = chr;
3261            chars[1] = mask;
3262            }
3263          else
3264            {
3265            mask |= chars[0] ^ chr;
3266            chr |= mask;
3267            chars[0] = chr;
3268            chars[1] |= mask;
3269            }
3270    
3271          len--;
3272          if (--max_chars == 0)
3273            return consumed;
3274          consumed++;
3275          chars += 2;
3276          cc++;
3277        }        }
3278        while (len > 0);
3279    
3280      chars[location] = c;      if (--repeat == 0)
3281      chars[location + 1] = bit;        break;
3282    
3283      len--;      len = len_save;
3284      location += 2;      cc = cc_save;
3285      cc++;      }
3286    
3287      repeat = 1;
3288      if (last)
3289        return consumed;
3290      }
3291    }
3292    
3293    #define MAX_N_CHARS 16
3294    
3295    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
3296    {
3297    DEFINE_COMPILER;
3298    struct sljit_label *start;
3299    struct sljit_jump *quit;
3300    pcre_uint32 chars[MAX_N_CHARS * 2];
3301    pcre_uint8 ones[MAX_N_CHARS];
3302    pcre_uint32 mask;
3303    int i, max;
3304    int offsets[3];
3305    
3306    for (i = 0; i < MAX_N_CHARS; i++)
3307      {
3308      chars[i << 1] = NOTACHAR;
3309      chars[(i << 1) + 1] = 0;
3310      }
3311    
3312    max = scan_prefix(common, common->start, chars, MAX_N_CHARS);
3313    
3314    if (max <= 1)
3315      return FALSE;
3316    
3317    for (i = 0; i < max; i++)
3318      {
3319      mask = chars[(i << 1) + 1];
3320      ones[i] = ones_in_half_byte[mask & 0xf];
3321      mask >>= 4;
3322      while (mask != 0)
3323        {
3324        ones[i] += ones_in_half_byte[mask & 0xf];
3325        mask >>= 4;
3326      }      }
3327      }
3328    
3329    if (location >= MAX_N_CHARS * 2 || must_stop != 0)  offsets[0] = -1;
3330    /* Scan forward. */
3331    for (i = 0; i < max; i++)
3332      if (ones[i] <= 2) {
3333        offsets[0] = i;
3334      break;      break;
3335    }    }
3336    
3337  /* At least two characters are required. */  if (offsets[0] == -1)
3338  if (location < 2 * 2)    return FALSE;
3339      return FALSE;  
3340    /* Scan backward. */
3341    offsets[1] = -1;
3342    for (i = max - 1; i > offsets[0]; i--)
3343      if (ones[i] <= 2) {
3344        offsets[1] = i;
3345        break;
3346      }
3347    
3348    offsets[2] = -1;
3349    if (offsets[1] >= 0)
3350      {
3351      /* Scan from middle. */
3352      for (i = (offsets[0] + offsets[1]) / 2 + 1; i < offsets[1]; i++)
3353        if (ones[i] <= 2)
3354          {
3355          offsets[2] = i;
3356          break;
3357          }
3358    
3359      if (offsets[2] == -1)
3360        {
3361        for (i = (offsets[0] + offsets[1]) / 2; i > offsets[0]; i--)
3362          if (ones[i] <= 2)
3363            {
3364            offsets[2] = i;
3365            break;
3366            }
3367        }
3368      }
3369    
3370    SLJIT_ASSERT(offsets[1] == -1 || (offsets[0] < offsets[1]));
3371    SLJIT_ASSERT(offsets[2] == -1 || (offsets[0] < offsets[2] && offsets[1] > offsets[2]));
3372    
3373    chars[0] = chars[offsets[0] << 1];
3374    chars[1] = chars[(offsets[0] << 1) + 1];
3375    if (offsets[2] >= 0)
3376      {
3377      chars[2] = chars[offsets[2] << 1];
3378      chars[3] = chars[(offsets[2] << 1) + 1];
3379      }
3380    if (offsets[1] >= 0)
3381      {
3382      chars[4] = chars[offsets[1] << 1];
3383      chars[5] = chars[(offsets[1] << 1) + 1];
3384      }
3385    
3386    max -= 1;
3387  if (firstline)  if (firstline)
3388    {    {
3389    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3390    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3391    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));
3392    }    }
3393  else  else
3394    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));
3395    
3396  start = LABEL();  start = LABEL();
3397  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3398    
3399  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]));
3400  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  if (offsets[1] >= 0)
3401      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(offsets[1]));
3402  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));
3403    
3404  if (chars[1] != 0)  if (chars[1] != 0)
3405    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3406  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3407  if (location > 2 * 2)  if (offsets[2] >= 0)
3408    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));
3409  if (chars[3] != 0)  
3410    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)  
3411    {    {
3412    if (chars[5] != 0)    if (chars[5] != 0)
3413      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[5]);
3414    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[4], start);
3415      }
3416    
3417    if (offsets[2] >= 0)
3418      {
3419      if (chars[3] != 0)
3420        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[3]);
3421      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[2], start);
3422    }    }
3423  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));
3424    
# Line 2961  JUMPHERE(quit); Line 3427  JUMPHERE(quit);
3427  if (firstline)  if (firstline)
3428    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3429  else  else
3430    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));
3431  return TRUE;  return TRUE;
3432  }  }
3433    
# Line 3110  if (firstline) Line 3576  if (firstline)
3576    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3577  }  }
3578    
3579  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);
3580    
3581  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)
3582  {  {
3583  DEFINE_COMPILER;  DEFINE_COMPILER;
3584  struct sljit_label *start;  struct sljit_label *start;
3585  struct sljit_jump *quit;  struct sljit_jump *quit;
3586  struct sljit_jump *found = NULL;  struct sljit_jump *found = NULL;
3587  jump_list *matches = NULL;  jump_list *matches = NULL;
 pcre_uint8 inverted_start_bits[32];  
 int i;  
3588  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3589  struct sljit_jump *jump;  struct sljit_jump *jump;
3590  #endif  #endif
3591    
 for (i = 0; i < 32; ++i)  
   inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);  
   
3592  if (firstline)  if (firstline)
3593    {    {
3594    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 3143  if (common->utf) Line 3604  if (common->utf)
3604    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3605  #endif  #endif
3606    
3607  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))
3608    {    {
3609  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3610    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
# Line 3152  if (!check_class_ranges(common, inverted Line 3613  if (!check_class_ranges(common, inverted
3613  #endif  #endif
3614    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3615    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3616    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)start_bits);
3617    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3618    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);
3619    found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
# Line 3368  if (common->use_ucp) Line 3829  if (common->use_ucp)
3829    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3830    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);
3831    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);
3832    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);
3833    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3834    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;  
3835    }    }
3836  }  else
3837    #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)  
3838    {    {
3839    if (length >= MAX_RANGE_SIZE)  #ifndef COMPILE_PCRE8
3840      return;    /* TMP2 may be destroyed by peek_char. */
3841    ranges[2 + length] = 256;    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3842    length++;    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3843    #elif defined SUPPORT_UTF
3844      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3845      jump = NULL;
3846      if (common->utf)
3847        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3848    #endif
3849      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3850      OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3851      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3852    #ifndef COMPILE_PCRE8
3853      JUMPHERE(jump);
3854    #elif defined SUPPORT_UTF
3855      if (jump != NULL)
3856        JUMPHERE(jump);
3857    #endif /* COMPILE_PCRE8 */
3858    }    }
3859  ranges[0] = length;  set_jumps(skipread_list, LABEL());
3860    
3861    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3862    sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3863  }  }
3864    
3865  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)
3866  {  {
3867  int ranges[2 + MAX_RANGE_SIZE];  DEFINE_COMPILER;
3868    int ranges[MAX_RANGE_SIZE];
3869  pcre_uint8 bit, cbit, all;  pcre_uint8 bit, cbit, all;
3870  int i, byte, length = 0;  int i, byte, length = 0;
3871    
3872  bit = bits[0] & 0x1;  bit = bits[0] & 0x1;
3873  ranges[1] = bit;  /* All bits will be zero or one (since bit is zero or one). */
 /* Can be 0 or 255. */  
3874  all = -bit;  all = -bit;
3875    
3876  for (i = 0; i < 256; )  for (i = 0; i < 256; )
# Line 3519  for (i = 0; i < 256; ) Line 3885  for (i = 0; i < 256; )
3885        {        {
3886        if (length >= MAX_RANGE_SIZE)        if (length >= MAX_RANGE_SIZE)
3887          return FALSE;          return FALSE;
3888        ranges[2 + length] = i;        ranges[length] = i;
3889        length++;        length++;
3890        bit = cbit;        bit = cbit;
3891        all = -cbit;        all = -cbit;
# Line 3532  if (((bit == 0) && nclass) || ((bit == 1 Line 3898  if (((bit == 0) && nclass) || ((bit == 1
3898    {    {
3899    if (length >= MAX_RANGE_SIZE)    if (length >= MAX_RANGE_SIZE)
3900      return FALSE;      return FALSE;
3901    ranges[2 + length] = 256;    ranges[length] = 256;
3902    length++;    length++;
3903    }    }
 ranges[0] = length;  
3904    
3905  return check_ranges(common, ranges, backtracks, FALSE);  if (length < 0 || length > 4)
3906      return FALSE;
3907    
3908    bit = bits[0] & 0x1;
3909    if (invert) bit ^= 0x1;
3910    
3911    /* No character is accepted. */
3912    if (length == 0 && bit == 0)
3913      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3914    
3915    switch(length)
3916      {
3917      case 0:
3918      /* When bit != 0, all characters are accepted. */
3919      return TRUE;
3920    
3921      case 1:
3922      add_jump(compiler, backtracks, CMP(bit == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3923      return TRUE;
3924    
3925      case 2:
3926      if (ranges[0] + 1 != ranges[1])
3927        {
3928        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3929        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3930        }
3931      else
3932        add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3933      return TRUE;
3934    
3935      case 3:
3936      if (bit != 0)
3937        {
3938        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3939        if (ranges[0] + 1 != ranges[1])
3940          {
3941          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3942          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3943          }
3944        else
3945          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3946        return TRUE;
3947        }
3948    
3949      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[0]));
3950      if (ranges[1] + 1 != ranges[2])
3951        {
3952        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1]);
3953        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
3954        }
3955      else
3956        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1]));
3957      return TRUE;
3958    
3959      case 4:
3960      if ((ranges[1] - ranges[0]) == (ranges[3] - ranges[2])
3961          && (ranges[0] | (ranges[2] - ranges[0])) == ranges[2]
3962          && is_powerof2(ranges[2] - ranges[0]))
3963        {
3964        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[0]);
3965        if (ranges[2] + 1 != ranges[3])
3966          {
3967          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3968          add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3969          }
3970        else
3971          add_jump(compiler, backtracks, CMP(bit != 0 ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3972        return TRUE;
3973        }
3974    
3975      if (bit != 0)
3976        {
3977        i = 0;
3978        if (ranges[0] + 1 != ranges[1])
3979          {
3980          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3981          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
3982          i = ranges[0];
3983          }
3984        else
3985          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[0]));
3986    
3987        if (ranges[2] + 1 != ranges[3])
3988          {
3989          OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2] - i);
3990          add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3991          }
3992        else
3993          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2] - i));
3994        return TRUE;
3995        }
3996    
3997      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[0]);
3998      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[0]));
3999      if (ranges[1] + 1 != ranges[2])
4000        {
4001        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]);
4002        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, ranges[2] - ranges[1]));
4003        }
4004      else
4005        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[1] - ranges[0]));
4006      return TRUE;
4007    
4008      default:
4009      SLJIT_ASSERT_STOP();
4010      return FALSE;
4011      }
4012  }  }
4013    
4014  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 3925  static void compile_xclass_matchingpath( Line 4396  static void compile_xclass_matchingpath(
4396  {  {
4397  DEFINE_COMPILER;  DEFINE_COMPILER;
4398  jump_list *found = NULL;  jump_list *found = NULL;
4399  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (cc[0] & XCL_NOT) == 0 ? &found : backtracks;
4400  pcre_int32 c, charoffset;  pcre_int32 c, charoffset;
 const pcre_uint32 *other_cases;  
4401  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4402  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4403  int compares, invertcmp, numberofcmps;  int compares, invertcmp, numberofcmps;
4404    
4405  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4406  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
4407  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
4408  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
4409    const pcre_uint32 *other_cases;
4410  pcre_int32 typeoffset;  pcre_int32 typeoffset;
4411  #endif  #endif
4412    
# Line 3943  pcre_int32 typeoffset; Line 4415  pcre_int32 typeoffset;
4415  detect_partial_match(common, backtracks);  detect_partial_match(common, backtracks);
4416  read_char(common);  read_char(common);
4417    
4418  if ((*cc++ & XCL_MAP) != 0)  cc++;
4419    if ((cc[-1] & XCL_HASPROP) == 0)
4420    {    {
4421    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    if ((cc[-1] & XCL_MAP) != 0)
4422  #ifndef COMPILE_PCRE8      {
4423    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4424  #elif defined SUPPORT_UTF  #ifdef SUPPORT_UCP
4425    if (common->utf)      charsaved = TRUE;
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
4426  #endif  #endif
4427        if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, FALSE, backtracks))
4428          {
4429          jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4430    
4431          OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4432          OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4433          OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4434          OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4435          OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4436          add_jump(compiler, &found, JUMP(SLJIT_C_NOT_ZERO));
4437          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4438    
4439          JUMPHERE(jump);
4440          }
4441        else
4442          add_jump(compiler, &found, CMP(SLJIT_C_LESS_EQUAL, TMP3, 0, SLJIT_IMM, 0xff));
4443    
4444    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
4445        cc += 32 / sizeof(pcre_uchar);
4446        }
4447      else
4448        add_jump(compiler, (cc[-1] & XCL_NOT) == 0 ? backtracks : &found, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, 0xff));
4449      }
4450    else if ((cc[-1] & XCL_MAP) != 0)
4451      {
4452      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
4453    #ifdef SUPPORT_UCP
4454      charsaved = TRUE;
4455    #endif
4456      if (!check_class_ranges(common, (const pcre_uint8 *)cc, FALSE, TRUE, list))
4457      {      {
4458    #ifdef COMPILE_PCRE8
4459        SLJIT_ASSERT(common->utf);
4460    #endif
4461        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4462    
4463      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4464      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4465      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4466      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4467      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);
4468      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
     }  
4469    
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (common->utf)  
4470      JUMPHERE(jump);      JUMPHERE(jump);
4471  #endif      }
4472    
4473    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
 #ifdef SUPPORT_UCP  
   charsaved = TRUE;  
 #endif  
4474    cc += 32 / sizeof(pcre_uchar);    cc += 32 / sizeof(pcre_uchar);
4475    }    }
4476    
# Line 4030  while (*cc != XCL_END) Line 4528  while (*cc != XCL_END)
4528        case PT_SPACE:        case PT_SPACE:
4529        case PT_PXSPACE:        case PT_PXSPACE:
4530        case PT_WORD:        case PT_WORD:
4531          case PT_PXGRAPH:
4532          case PT_PXPRINT:
4533          case PT_PXPUNCT:
4534        needstype = TRUE;        needstype = TRUE;
4535        needschar = TRUE;        needschar = TRUE;
4536        break;        break;
# Line 4217  while (*cc != XCL_END) Line 4718  while (*cc != XCL_END)
4718    
4719        case PT_SPACE:        case PT_SPACE:
4720        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);  
         }  
4721        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4722        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);
4723        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);
4724        if (*cc == PT_SPACE)  
4725          JUMPHERE(jump);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
4726          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4727    
4728          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
4729          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4730    
4731        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4732        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 4318  while (*cc != XCL_END) Line 4818  while (*cc != XCL_END)
4818        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);
4819        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4820        break;        break;
4821    
4822          case PT_PXGRAPH:
4823          /* C and Z groups are the farthest two groups. */
4824          SET_TYPE_OFFSET(ucp_Ll);
4825          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
4826          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
4827    
4828          jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
4829    
4830          /* In case of ucp_Cf, we overwrite the result. */
4831          SET_CHAR_OFFSET(0x2066);
4832          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
4833          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4834    
4835          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
4836          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4837    
4838          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x2066);
4839          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4840    
4841          JUMPHERE(jump);
4842          jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4843          break;
4844    
4845          case PT_PXPRINT:
4846          /* C and Z groups are the farthest two groups. */
4847          SET_TYPE_OFFSET(ucp_Ll);
4848          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Ll);
4849          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);
4850    
4851          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Ll);
4852          OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4853    
4854          jump = CMP(SLJIT_C_NOT_EQUAL, typereg, 0, SLJIT_IMM, ucp_Cf - ucp_Ll);
4855    
4856          /* In case of ucp_Cf, we overwrite the result. */
4857          SET_CHAR_OFFSET(0x2066);
4858          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2069 - 0x2066);
4859          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4860    
4861          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x061c - 0x2066);
4862          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4863    
4864          JUMPHERE(jump);
4865          jump = CMP(SLJIT_C_ZERO ^ invertcmp, TMP2, 0, SLJIT_IMM, 0);
4866          break;
4867    
4868          case PT_PXPUNCT:
4869          SET_TYPE_OFFSET(ucp_Sc);
4870          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_So - ucp_Sc);
4871          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4872    
4873          SET_CHAR_OFFSET(0);
4874          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xff);
4875          OP_FLAGS(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4876    
4877          SET_TYPE_OFFSET(ucp_Pc);
4878          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ps - ucp_Pc);
4879          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4880          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4881          break;
4882        }        }
4883      cc += 2;      cc += 2;
4884      }      }
# Line 4349  struct sljit_label *label; Line 4910  struct sljit_label *label;
4910  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4911  pcre_uchar propdata[5];  pcre_uchar propdata[5];
4912  #endif  #endif
4913  #endif  #endif /* SUPPORT_UTF */
4914    
4915  switch(type)  switch(type)
4916    {    {
# Line 4374  switch(type) Line 4935  switch(type)
4935    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4936    case OP_DIGIT:    case OP_DIGIT:
4937    /* 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);  
4938    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4939    /* Flip the starting bit in the negative case. */  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4940    if (type == OP_NOT_DIGIT)    if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_digit, FALSE))
4941      common->digits[1] ^= 1;      read_char7_type(common, type == OP_NOT_DIGIT);
4942    if (!check_ranges(common, common->digits, backtracks, TRUE))    else
4943      {  #endif
4944      read_char8_type(common);      read_char8_type(common, type == OP_NOT_DIGIT);
4945      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      /* Flip the starting bit in the negative case. */
4946      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);
4947      }    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
   if (type == OP_NOT_DIGIT)  
     common->digits[1] ^= 1;  
4948    return cc;    return cc;
4949    
4950    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4951    case OP_WHITESPACE:    case OP_WHITESPACE:
4952    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4953    read_char8_type(common);  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4954      if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_space, FALSE))
4955        read_char7_type(common, type == OP_NOT_WHITESPACE);
4956      else
4957    #endif
4958        read_char8_type(common, type == OP_NOT_WHITESPACE);
4959    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);
4960    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));
4961    return cc;    return cc;
# Line 4401  switch(type) Line 4963  switch(type)
4963    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4964    case OP_WORDCHAR:    case OP_WORDCHAR:
4965    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4966    read_char8_type(common);  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
4967      if (common->utf && is_char7_bitset((const pcre_uint8*)common->ctypes - cbit_length + cbit_word, FALSE))
4968        read_char7_type(common, type == OP_NOT_WORDCHAR);
4969      else
4970    #endif
4971        read_char8_type(common, type == OP_NOT_WORDCHAR);
4972    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);
4973    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));
4974    return cc;    return cc;
# Line 4464  switch(type) Line 5031  switch(type)
5031  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
5032    case OP_NOTPROP:    case OP_NOTPROP:
5033    case OP_PROP:    case OP_PROP:
5034    propdata[0] = 0;    propdata[0] = XCL_HASPROP;
5035    propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;    propdata[1] = type == OP_NOTPROP ? XCL_NOTPROP : XCL_PROP;
5036    propdata[2] = cc[0];    propdata[2] = cc[0];
5037    propdata[3] = cc[1];    propdata[3] = cc[1];
# Line 4822  switch(type) Line 5389  switch(type)
5389    case OP_CLASS:    case OP_CLASS:
5390    case OP_NCLASS:    case OP_NCLASS:
5391    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
5392    read_char(common);  
5393    if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5394      bit = (common->utf && is_char7_bitset((const pcre_uint8 *)cc, type == OP_NCLASS)) ? 127 : 255;
5395      read_char_max(common, bit, type == OP_NCLASS);
5396    #else
5397      read_char_max(common, 255, type == OP_NCLASS);
5398    #endif
5399    
5400      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, FALSE, backtracks))
5401      return cc + 32 / sizeof(pcre_uchar);      return cc + 32 / sizeof(pcre_uchar);
5402    
5403  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
5404    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. */  
5405    if (common->utf)    if (common->utf)
 #endif /* COMPILE_PCRE8 */  
5406      {      {
5407      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, bit);
5408      if (type == OP_CLASS)      if (type == OP_CLASS)
5409        {        {
5410        add_jump(compiler, backtracks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
5411        jump[0] = NULL;        jump[0] = NULL;
5412        }        }
5413      }      }
5414  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #elif !defined COMPILE_PCRE8
5415      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
5416      if (type == OP_CLASS)
5417        {
5418        add_jump(compiler, backtracks, jump[0]);
5419        jump[0] = NULL;
5420        }
5421    #endif /* SUPPORT_UTF && COMPILE_PCRE8 */
5422    
5423    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
5424    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
5425    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
5426    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5427    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);
5428    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
5429    
5430  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
5431    if (jump[0] != NULL)    if (jump[0] != NULL)
5432      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
5433  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif
5434    
5435    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
5436    
5437  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 4956  if (context.length > 0) Line 5536  if (context.length > 0)
5536  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
5537  }  }
5538    
 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));  
 }  
   
5539  /* Forward definitions. */  /* Forward definitions. */
5540  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
5541  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
# Line 5010  static void compile_backtrackingpath(com Line 5568  static void compile_backtrackingpath(com
5568    
5569  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
5570    
5571  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)
5572    {
5573    /* The OVECTOR offset goes to TMP2. */
5574    DEFINE_COMPILER;
5575    int count = GET2(cc, 1 + IMM2_SIZE);
5576    pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
5577    unsigned int offset;
5578    jump_list *found = NULL;
5579    
5580    SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
5581    
5582    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5583    
5584    count--;
5585    while (count-- > 0)
5586      {
5587      offset = GET2(slot, 0) << 1;
5588      GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5589      add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5590      slot += common->name_entry_size;
5591      }
5592    
5593    offset = GET2(slot, 0) << 1;
5594    GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5595    if (backtracks != NULL && !common->jscript_compat)
5596      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5597    
5598    set_jumps(found, LABEL());
5599    }
5600    
5601    static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
5602  {  {
5603  DEFINE_COMPILER;  DEFINE_COMPILER;
5604  int offset = GET2(cc, 1) << 1;  BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5605    int offset = 0;
5606  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5607  struct sljit_jump *partial;  struct sljit_jump *partial;
5608  struct sljit_jump *nopartial;  struct sljit_jump *nopartial;
5609    
5610  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  if (ref)
5611  /* OVECTOR(1) contains the "string begin - 1" constant. */    {
5612  if (withchecks && !common->jscript_compat)    offset = GET2(cc, 1) << 1;
5613    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));
5614      /* OVECTOR(1) contains the "string begin - 1" constant. */
5615      if (withchecks && !common->jscript_compat)
5616        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5617      }
5618    else
5619      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5620    
5621  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5622  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5623    {    {
5624    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);
5625    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    if (ref)
5626        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5627      else
5628        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5629    
5630    if (withchecks)    if (withchecks)
5631      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5632    
# Line 5052  if (common->utf && *cc == OP_REFI) Line 5651  if (common->utf && *cc == OP_REFI)
5651  else  else
5652  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
5653    {    {
5654    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    if (ref)
5655        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
5656      else
5657        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
5658    
5659    if (withchecks)    if (withchecks)
5660      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
5661    
# Line 5089  if (jump != NULL) Line 5692  if (jump != NULL)
5692    else    else
5693      JUMPHERE(jump);      JUMPHERE(jump);
5694    }    }
 return cc + 1 + IMM2_SIZE;  
5695  }  }
5696    
5697  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)
5698  {  {
5699  DEFINE_COMPILER;  DEFINE_COMPILER;
5700    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5701  backtrack_common *backtrack;  backtrack_common *backtrack;
5702  pcre_uchar type;  pcre_uchar type;
5703    int offset = 0;
5704  struct sljit_label *label;  struct sljit_label *label;
5705  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
5706  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5106  BOOL minimize; Line 5710  BOOL minimize;
5710    
5711  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5712    
5713    if (ref)
5714      offset = GET2(cc, 1) << 1;
5715    else
5716      cc += IMM2_SIZE;
5717  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
5718    
5719    SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
5720  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
5721  switch(type)  switch(type)
5722    {    {
# Line 5144  if (!minimize) Line 5754  if (!minimize)
5754    if (min == 0)    if (min == 0)
5755      {      {
5756      allocate_stack(common, 2);      allocate_stack(common, 2);
5757        if (ref)
5758          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5760      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5761      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
5762      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));
5763      zerolength = compile_ref_checks(common, ccbegin, NULL);      /* Handles both invalid and empty cases. Since the minimum repeat,
5764        is zero the invalid case is basically the same as an empty case. */
5765        if (ref)
5766          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5767        else
5768          {
5769          compile_dnref_search(common, ccbegin, NULL);
5770          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5771          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5772          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5773          }
5774      /* Restore if not zero length. */      /* Restore if not zero length. */
5775      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));
5776      }      }
5777    else    else
5778      {      {
5779      allocate_stack(common, 1);      allocate_stack(common, 1);
5780        if (ref)
5781          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5782      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5783      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);      if (ref)
5784          {
5785          add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5786          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5787          }
5788        else
5789          {
5790          compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5791          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5792          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5793          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5794          }
5795      }      }
5796    
5797    if (min > 1 || max > 1)    if (min > 1 || max > 1)
5798      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5799    
5800    label = LABEL();    label = LABEL();
5801      if (!ref)
5802        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5803    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
5804    
5805    if (min > 1 || max > 1)    if (min > 1 || max > 1)
# Line 5193  if (!minimize) Line 5830  if (!minimize)
5830    JUMPHERE(zerolength);    JUMPHERE(zerolength);
5831    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5832    
5833    decrease_call_count(common);    count_match(common);
5834    return cc;    return cc;
5835    }    }
5836    
5837  allocate_stack(common, 2);  allocate_stack(common, ref ? 2 : 3);
5838    if (ref)
5839      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5840  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5841  if (type != OP_CRMINSTAR)  if (type != OP_CRMINSTAR)
5842    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5843    
5844  if (min == 0)  if (min == 0)
5845    {    {
5846    zerolength = compile_ref_checks(common, ccbegin, NULL);    /* Handles both invalid and empty cases. Since the minimum repeat,
5847      is zero the invalid case is basically the same as an empty case. */
5848      if (ref)
5849        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5850      else
5851        {
5852        compile_dnref_search(common, ccbegin, NULL);
5853        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5854        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5855        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5856        }
5857      /* Length is non-zero, we can match real repeats. */
5858    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5859    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5860    }    }
5861  else  else
5862    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    {
5863      if (ref)
5864        {
5865        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5866        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5867        }
5868      else
5869        {
5870        compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5871        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5872        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5873        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5874        }
5875      }
5876    
5877  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5878  if (max > 0)  if (max > 0)
5879    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));
5880    
5881    if (!ref)
5882      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
5883  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
5884  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5885    
# Line 5232  if (jump != NULL) Line 5897  if (jump != NULL)
5897    JUMPHERE(jump);    JUMPHERE(jump);
5898  JUMPHERE(zerolength);  JUMPHERE(zerolength);
5899    
5900  decrease_call_count(common);  count_match(common);
5901  return cc;  return cc;
5902  }  }
5903    
# Line 5242  DEFINE_COMPILER; Line 5907  DEFINE_COMPILER;
5907  backtrack_common *backtrack;  backtrack_common *backtrack;
5908  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5909  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5910  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5911  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5912    BOOL needs_control_head;
5913    
5914  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5915    
5916  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5917  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5918    {    {
5919    start_cc = common->start + start;    start_cc = common->start + start;
5920    compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);    compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
# Line 5408  static pcre_uchar *compile_assert_matchi Line 6074  static pcre_uchar *compile_assert_matchi
6074  DEFINE_COMPILER;  DEFINE_COMPILER;
6075  int framesize;  int framesize;
6076  int extrasize;  int extrasize;
6077  BOOL needs_control_head = common->control_head_ptr != 0;  BOOL needs_control_head;
6078  int private_data_ptr;  int private_data_ptr;
6079  backtrack_common altbacktrack;  backtrack_common altbacktrack;
6080  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5418  jump_list *tmp = NULL; Line 6084  jump_list *tmp = NULL;
6084  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
6085  jump_list **found;  jump_list **found;
6086  /* Saving previous accept variables. */  /* Saving previous accept variables. */
6087    BOOL save_local_exit = common->local_exit;
6088    BOOL save_positive_assert = common->positive_assert;
6089    then_trap_backtrack *save_then_trap = common->then_trap;
6090  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
6091  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
6092  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
6093    jump_list *save_positive_assert_quit = common->positive_assert_quit;
6094  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
 BOOL save_local_exit = common->local_exit;  
6095  struct sljit_jump *jump;  struct sljit_jump *jump;
6096  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
6097    
6098    /* Assert captures then. */
6099    common->then_trap = NULL;
6100    
6101  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
6102    {    {
6103    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5434  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6106  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6106    }    }
6107  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
6108  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
6109  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6110  backtrack->framesize = framesize;  backtrack->framesize = framesize;
6111  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
6112  opcode = *cc;  opcode = *cc;
# Line 5454  if (bra == OP_BRAMINZERO) Line 6126  if (bra == OP_BRAMINZERO)
6126  if (framesize < 0)  if (framesize < 0)
6127    {    {
6128    extrasize = needs_control_head ? 2 : 1;    extrasize = needs_control_head ? 2 : 1;
6129    if (framesize != no_stack)    if (framesize == no_frame)
6130      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6131    allocate_stack(common, extrasize);    allocate_stack(common, extrasize);
6132    if (needs_control_head)    if (needs_control_head)
# Line 5484  else Line 6156  else
6156      }      }
6157    else    else
6158      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
6159    init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
6160    }    }
6161    
6162  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
6163  common->local_exit = TRUE;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6164  common->quit_label = NULL;    {
6165  common->quit = NULL;    /* Negative assert is stronger than positive assert. */
6166      common->local_exit = TRUE;
6167      common->quit_label = NULL;
6168      common->quit = NULL;
6169      common->positive_assert = FALSE;
6170      }
6171    else
6172      common->positive_assert = TRUE;
6173    common->positive_assert_quit = NULL;
6174    
6175  while (1)  while (1)
6176    {    {
6177    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5505  while (1) Line 6186  while (1)
6186    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
6187    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6188      {      {
6189      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6190      common->quit_label = save_quit_label;        {
6191          common->local_exit = save_local_exit;
6192          common->quit_label = save_quit_label;
6193          common->quit = save_quit;
6194          }
6195        common->positive_assert = save_positive_assert;
6196        common->then_trap = save_then_trap;
6197      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
6198      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
6199      common->accept = save_accept;      common->accept = save_accept;
6200      return NULL;      return NULL;
6201      }      }
# Line 5519  while (1) Line 6206  while (1)
6206    /* Reset stack. */    /* Reset stack. */
6207    if (framesize < 0)    if (framesize < 0)
6208      {      {
6209      if (framesize != no_stack)      if (framesize == no_frame)
6210        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6211      else      else
6212        free_stack(common, extrasize);        free_stack(common, extrasize);
# Line 5573  while (1) Line 6260  while (1)
6260    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
6261    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6262      {      {
6263      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6264      common->quit_label = save_quit_label;        {
6265          common->local_exit = save_local_exit;
6266          common->quit_label = save_quit_label;
6267          common->quit = save_quit;
6268          }
6269        common->positive_assert = save_positive_assert;
6270        common->then_trap = save_then_trap;
6271      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
6272      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
6273      common->accept = save_accept;      common->accept = save_accept;
6274      return NULL;      return NULL;
6275      }      }
# Line 5589  while (1) Line 6282  while (1)
6282    cc += GET(cc, 1);    cc += GET(cc, 1);
6283    }    }
6284    
6285    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6286      {
6287      SLJIT_ASSERT(common->positive_assert_quit == NULL);
6288      /* Makes the check less complicated below. */
6289      common->positive_assert_quit = common->quit;
6290      }
6291    
6292  /* None of them matched. */  /* None of them matched. */
6293  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
6294    {    {
6295    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6296    set_jumps(common->quit, LABEL());    set_jumps(common->positive_assert_quit, LABEL());
6297    SLJIT_ASSERT(framesize != no_stack);    SLJIT_ASSERT(framesize != no_stack);
6298    if (framesize < 0)    if (framesize < 0)
6299      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 5753  else Line 6453  else
6453      }      }
6454    }    }
6455    
6456  common->local_exit = save_local_exit;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
6457  common->quit_label = save_quit_label;    {
6458      common->local_exit = save_local_exit;
6459      common->quit_label = save_quit_label;
6460      common->quit = save_quit;
6461      }
6462    common->positive_assert = save_positive_assert;
6463    common->then_trap = save_then_trap;
6464  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
6465  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
6466  common->accept = save_accept;  common->accept = save_accept;
6467  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
6468  }  }
6469    
6470  static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table)  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)
6471  {  {
6472  int condition = FALSE;  DEFINE_COMPILER;
6473  pcre_uchar *slotA = name_table;  int stacksize;
 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];  
6474    
6475  for (i = 0; i < name_count; i++)  if (framesize < 0)
6476    {    {
6477    if (GET2(slotA, 0) == refno) break;    if (framesize == no_frame)
6478    slotA += name_entry_size;      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6479    }    else
6480        {
6481        stacksize = needs_control_head ? 1 : 0;
6482        if (ket != OP_KET || has_alternatives)
6483          stacksize++;
6484        free_stack(common, stacksize);
6485        }
6486    
6487  if (i < name_count)    if (needs_control_head)
6488    {      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
   /* 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. */  
6489    
6490    slotB = slotA;    /* TMP2 which is set here used by OP_KETRMAX below. */
6491    while (slotB > name_table)    if (ket == OP_KETRMAX)
6492        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6493      else if (ket == OP_KETRMIN)
6494      {      {
6495      slotB -= name_entry_size;      /* Move the STR_PTR to the private_data_ptr. */
6496      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
       {  
       condition = locals[GET2(slotB, 0) << 1] != no_capture;  
       if (condition) break;  
       }  
     else break;  
6497      }      }
6498      }
6499    else
6500      {
6501      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6502      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6503      if (needs_control_head)
6504        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6505    
6506    /* Scan up for duplicates */    if (ket == OP_KETRMAX)
   if (!condition)  
6507      {      {
6508      slotB = slotA;      /* TMP2 which is set here used by OP_KETRMAX below. */
6509      for (i++; i < name_count; i++)      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
       {  
       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;  
       }  
6510      }      }
6511    }    }
6512  return condition;  if (needs_control_head)
6513      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6514  }  }
6515    
6516  static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table)  static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6517  {  {
6518  int condition = FALSE;  DEFINE_COMPILER;
 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;  
6519    
6520  for (i = 0; i < name_count; i++)  if (common->capture_last_ptr != 0)
6521    {    {
6522    if (GET2(slotA, 0) == recno) break;    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6523    slotA += name_entry_size;    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6524      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6525      stacksize++;
6526    }    }
6527    if (common->optimized_cbracket[offset >> 1] == 0)
 if (i < name_count)  
6528    {    {
6529    /* Found a name for the number - there can be only one; duplicate    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6530    names for different numbers are allowed, but not vice versa. First    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6531    scan down for duplicates. */    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6532      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6533    slotB = slotA;    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6534    while (slotB > name_table)    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6535      {    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6536      slotB -= name_entry_size;    stacksize += 2;
     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;  
       }  
     }  
6537    }    }
6538  return condition;  return stacksize;
6539  }  }
6540    
6541  /*  /*
# Line 5932  backtrack_common *backtrack; Line 6599  backtrack_common *backtrack;
6599  pcre_uchar opcode;  pcre_uchar opcode;
6600  int private_data_ptr = 0;  int private_data_ptr = 0;
6601  int offset = 0;  int offset = 0;
6602  int stacksize;  int i, stacksize;
6603    int repeat_ptr = 0, repeat_length = 0;
6604    int repeat_type = 0, repeat_count = 0;
6605  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6606  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6607    pcre_uchar *slot;
6608  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6609  pcre_uchar ket;  pcre_uchar ket;
6610  assert_backtrack *assert;  assert_backtrack *assert;
6611  BOOL has_alternatives;  BOOL has_alternatives;
6612    BOOL needs_control_head = FALSE;
6613  struct sljit_jump *jump;  struct sljit_jump *jump;
6614  struct sljit_jump *skip;  struct sljit_jump *skip;
6615  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmax_label = NULL;
6616  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzero = NULL;
6617    
6618  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6619    
# Line 5955  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6626  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6626    
6627  opcode = *cc;  opcode = *cc;
6628  ccbegin = cc;  ccbegin = cc;
6629  matchingpath = ccbegin + 1 + LINK_SIZE;  matchingpath = bracketend(cc) - 1 - LINK_SIZE;
6630    ket = *matchingpath;
6631    if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
6632      {
6633      repeat_ptr = PRIVATE_DATA(matchingpath);
6634      repeat_length = PRIVATE_DATA(matchingpath + 1);
6635      repeat_type = PRIVATE_DATA(matchingpath + 2);
6636      repeat_count = PRIVATE_DATA(matchingpath + 3);
6637      SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
6638      if (repeat_type == OP_UPTO)
6639        ket = OP_KETRMAX;
6640      if (repeat_type == OP_MINUPTO)
6641        ket = OP_KETRMIN;
6642      }
6643    
6644  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)
6645    {    {
6646    /* Drop this bracket_backtrack. */    /* Drop this bracket_backtrack. */
6647    parent->top = backtrack->prev;    parent->top = backtrack->prev;
6648    return bracketend(cc);    return matchingpath + 1 + LINK_SIZE + repeat_length;
6649    }    }
6650    
6651  ket = *(bracketend(cc) - 1 - LINK_SIZE);  matchingpath = ccbegin + 1 + LINK_SIZE;
6652  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
6653  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)));
6654  cc += GET(cc, 1);  cc += GET(cc, 1);
6655    
6656  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6657  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
6658    {    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);  
     }  
   }  
6659    
6660  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
6661    opcode = OP_SCOND;    opcode = OP_SCOND;
# Line 6014  else if (opcode == OP_ONCE || opcode == Line 6686  else if (opcode == OP_ONCE || opcode ==
6686    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6687    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6688    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6689      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, NULL, FALSE, &needs_control_head);
6690    }    }
6691    
6692  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6693  stacksize = 0;  stacksize = 0;
6694  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6695    stacksize++;    stacksize++;
6696  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6697    stacksize++;    stacksize++;
# Line 6028  if (stacksize > 0) Line 6700  if (stacksize > 0)
6700    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6701    
6702  stacksize = 0;  stacksize = 0;
6703  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6704    {    {
6705    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6706    stacksize++;    stacksize++;
# Line 6044  if (bra == OP_BRAMINZERO) Line 6716  if (bra == OP_BRAMINZERO)
6716    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
6717      {      {
6718      free_stack(common, 1);      free_stack(common, 1);
6719      braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);      braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6720      }      }
6721    else    else
6722      {      {
# Line 6059  if (bra == OP_BRAMINZERO) Line 6731  if (bra == OP_BRAMINZERO)
6731        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6732          {          {
6733          /* 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. */
6734          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);
6735          }          }
6736        else        else
6737          {          {
6738          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
6739          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);
6740          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));
6741          }          }
6742        JUMPHERE(skip);        JUMPHERE(skip);
6743        }        }
# Line 6078  if (bra == OP_BRAMINZERO) Line 6750  if (bra == OP_BRAMINZERO)
6750      }      }
6751    }    }
6752    
6753    if (repeat_type != 0)
6754      {
6755      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
6756      if (repeat_type == OP_EXACT)
6757        rmax_label = LABEL();
6758      }
6759    
6760  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
6761    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6762    
6763  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6764    {    {
6765    rmaxlabel = LABEL();    rmax_label = LABEL();
6766    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
6767      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
6768    }    }
6769    
6770  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6771  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6772    {    {
6773      stacksize = 0;
6774      if (needs_control_head)
6775        {
6776        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6777        stacksize++;
6778        }
6779    
6780    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6781      {      {
6782      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6783      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6784        {        {
6785        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6786        allocate_stack(common, 2);        if (!needs_control_head)
6787        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);  
       OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));  
6788        }        }
6789      else if (ket == OP_KETRMAX || has_alternatives)      else
6790        {        {
6791        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6792        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6793        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6794            stacksize++;
6795        }        }
6796      else  
6797        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6798          allocate_stack(common, stacksize);
6799    
6800        stacksize = 0;
6801        if (needs_control_head)
6802          {
6803          stacksize++;
6804          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6805          }
6806    
6807        if (ket == OP_KETRMIN)
6808          {
6809          if (needs_control_head)
6810            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6811          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6812          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6813            OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, needs_control_head ? (2 * sizeof(sljit_sw)) : sizeof(sljit_sw));
6814          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6815          }
6816        else if (ket == OP_KETRMAX || has_alternatives)
6817          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6818      }      }
6819    else    else
6820      {      {
6821      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6822          stacksize++;
6823    
6824        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6825        allocate_stack(common, stacksize);
6826    
6827        if (needs_control_head)
6828          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6829    
6830        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6831        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6832    
6833        stacksize = needs_control_head ? 1 : 0;
6834        if (ket != OP_KET || has_alternatives)
6835        {        {
6836        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
       OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6837        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6838        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6839        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6840        }        }
6841      else      else
6842        {        {
       allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
       OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));  
6843        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
6844        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
       init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);  
6845        }        }
6846        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6847      }      }
6848    }    }
6849  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6180  if (opcode == OP_COND || opcode == OP_SC Line 6892  if (opcode == OP_COND || opcode == OP_SC
6892        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)));
6893      matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
6894      }      }
6895    else if (*matchingpath == OP_NCREF)    else if (*matchingpath == OP_DNCREF)
6896      {      {
6897      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
     stacksize = GET2(matchingpath, 1);  
     jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  
   
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);  
     OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));  
     GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);  
     OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);  
     sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));  
     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));  
6898    
6899      JUMPHERE(jump);      i = GET2(matchingpath, 1 + IMM2_SIZE);
6900      matchingpath += 1 + IMM2_SIZE;      slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6901        OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
6902        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6903        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6904        slot += common->name_entry_size;
6905        i--;
6906        while (i-- > 0)
6907          {
6908          OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6909          OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
6910          slot += common->name_entry_size;
6911          }
6912        OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
6913        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO));
6914        matchingpath += 1 + 2 * IMM2_SIZE;
6915      }      }
6916    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
6917      {      {
6918      /* Never has other case. */      /* Never has other case. */
6919      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
6920        SLJIT_ASSERT(!has_alternatives);
6921    
6922      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)  
6923        {        {
6924        SLJIT_ASSERT(!has_alternatives);        stacksize = GET2(matchingpath, 1);
6925          if (common->currententry == NULL)
6926            stacksize = 0;
6927          else if (stacksize == RREF_ANY)
6928            stacksize = 1;
6929          else if (common->currententry->start == 0)
6930            stacksize = stacksize == 0;
6931          else
6932            stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6933    
6934        if (stacksize != 0)        if (stacksize != 0)
6935          matchingpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
6936          }
6937        else
6938          {
6939          if (common->currententry == NULL || common->currententry->start == 0)
6940            stacksize = 0;
6941        else        else
6942          {          {
6943            stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
6944            slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6945            i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6946            while (stacksize > 0)
6947              {
6948              if ((int)GET2(slot, 0) == i)
6949                break;
6950              slot += common->name_entry_size;
6951              stacksize--;
6952              }
6953            }
6954    
6955          if (stacksize != 0)
6956            matchingpath += 1 + 2 * IMM2_SIZE;
6957          }
6958    
6959          /* The stacksize == 0 is a common "else" case. */
6960          if (stacksize == 0)
6961            {
6962          if (*cc == OP_ALT)          if (*cc == OP_ALT)
6963            {            {
6964            matchingpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
# Line 6229  if (opcode == OP_COND || opcode == OP_SC Line 6967  if (opcode == OP_COND || opcode == OP_SC
6967          else          else
6968            matchingpath = cc;            matchingpath = cc;
6969          }          }
       }  
     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;  
       }  
6970      }      }
6971    else    else
6972      {      {
# Line 6267  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6987  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6987    return NULL;    return NULL;
6988    
6989  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6990    {    match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
   if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)  
     {  
     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     /* TMP2 which is set here used by OP_KETRMAX below. */  
     if (ket == OP_KETRMAX)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);  
     else if (ket == OP_KETRMIN)  
       {  
       /* Move the STR_PTR to the private_data_ptr. */  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);  
       }  
     }  
   else  
     {  
     stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;  
     OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_sw));  
     if (ket == OP_KETRMAX)  
       {  
       /* TMP2 which is set here used by OP_KETRMAX below. */  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
       }  
     }  
   }  
6991    
6992  stacksize = 0;  stacksize = 0;
6993    if (repeat_type == OP_MINUPTO)
6994      {
6995      /* We need to preserve the counter. TMP2 will be used below. */
6996      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6997      stacksize++;
6998      }
6999  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
7000    stacksize++;    stacksize++;
7001  if (offset != 0)  if (offset != 0)
# Line 6309  if (stacksize > 0) Line 7012  if (stacksize > 0)
7012    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
7013    
7014  stacksize = 0;  stacksize = 0;
7015    if (repeat_type == OP_MINUPTO)
7016      {
7017      /* TMP2 was set above. */
7018      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
7019      stacksize++;
7020      }
7021    
7022  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
7023    {    {
7024    if (ket != OP_KET)    if (ket != OP_KET)
# Line 6319  if (ket != OP_KET || bra != OP_BRA) Line 7029  if (ket != OP_KET || bra != OP_BRA)
7029    }    }
7030    
7031  if (offset != 0)  if (offset != 0)
7032    {    stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
   if (common->capture_last_ptr != 0)  
     {  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);  
     stacksize++;  
     }  
   if (common->optimized_cbracket[offset >> 1] == 0)  
     {  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     stacksize += 2;  
     }  
   }  
7033    
7034  if (has_alternatives)  if (has_alternatives)
7035    {    {
# Line 6357  if (offset != 0 && common->optimized_cbr Line 7048  if (offset != 0 && common->optimized_cbr
7048    
7049  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7050    {    {
7051    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (repeat_type != 0)
7052        {
7053        if (has_alternatives)
7054          BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
7055        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
7056        JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
7057        /* Drop STR_PTR for greedy plus quantifier. */
7058        if (opcode != OP_ONCE)
7059          free_stack(common, 1);
7060        }
7061      else if (opcode == OP_ONCE || opcode >= OP_SBRA)
7062      {      {
7063      if (has_alternatives)      if (has_alternatives)
7064        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
7065      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
7066      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7067        {        {
7068        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);
7069        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
7070        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
7071          free_stack(common, 1);          free_stack(common, 1);
7072        }        }
7073      else      else
7074        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
7075        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
7076      }      }
7077    else    else
7078      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmax_label);
7079    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
7080    }    }
7081    
7082    if (repeat_type == OP_EXACT)
7083      {
7084      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
7085      JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
7086      }
7087    else if (repeat_type == OP_UPTO)
7088      {
7089      /* We need to preserve the counter. */
7090      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
7091      allocate_stack(common, 1);
7092      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7093      }
7094    
7095  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
7096    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
7097    
# Line 6385  if (bra == OP_BRAMINZERO) Line 7099  if (bra == OP_BRAMINZERO)
7099    {    {
7100    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
7101    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
7102    if (braminzerojump != NULL)    if (braminzero != NULL)
7103      {      {
7104      JUMPHERE(braminzerojump);      JUMPHERE(braminzero);
7105      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
7106      backtrack for the zero-length iteration. When      backtrack for the zero-length iteration. When
7107      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
# Line 6403  if (bra == OP_BRAMINZERO) Line 7117  if (bra == OP_BRAMINZERO)
7117    }    }
7118    
7119  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
7120    decrease_call_count(common);    count_match(common);
7121    
7122  /* Skip the other alternatives. */  /* Skip the other alternatives. */
7123  while (*cc == OP_ALT)  while (*cc == OP_ALT)
7124    cc += GET(cc, 1);    cc += GET(cc, 1);
7125  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
7126  return cc;  
7127    /* Temporarily encoding the needs_control_head in framesize. */
7128    if (opcode == OP_ONCE)
7129      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
7130    return cc + repeat_length;
7131  }  }
7132    
7133  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 6419  backtrack_common *backtrack; Line 7137  backtrack_common *backtrack;
7137  pcre_uchar opcode;  pcre_uchar opcode;
7138  int private_data_ptr;  int private_data_ptr;
7139  int cbraprivptr = 0;  int cbraprivptr = 0;
7140    BOOL needs_control_head;
7141  int framesize;  int framesize;
7142  int stacksize;  int stacksize;
7143  int offset = 0;  int offset = 0;
7144  BOOL zero = FALSE;  BOOL zero = FALSE;
7145  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
7146  int stack;  int stack; /* Also contains the offset of control head. */
7147  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
7148  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
7149    
# Line 6462  switch(opcode) Line 7181  switch(opcode)
7181    break;    break;
7182    }    }
7183    
7184  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
7185  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
7186  if (framesize < 0)  if (framesize < 0)
7187    {    {
# Line 6475  if (framesize < 0) Line 7194  if (framesize < 0)
7194    else    else
7195      stacksize = 1;      stacksize = 1;
7196    
7197      if (needs_control_head)
7198        stacksize++;
7199    if (!zero)    if (!zero)
7200      stacksize++;      stacksize++;
7201    
# Line 6483  if (framesize < 0) Line 7204  if (framesize < 0)
7204    if (framesize == no_frame)    if (framesize == no_frame)
7205      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
7206    
7207      stack = 0;
7208    if (offset != 0)    if (offset != 0)
7209      {      {
7210        stack = 2;
7211      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
7212      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
7213      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7214      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
7215        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
7216      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
7217        if (needs_control_head)
7218          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7219      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
7220          {
7221        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
7222          stack = 3;
7223          }
7224      }      }
7225    else    else
7226        {
7227        if (needs_control_head)
7228          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7229      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7230        stack = 1;
7231        }
7232    
7233      if (needs_control_head)
7234        stack++;
7235    if (!zero)    if (!zero)
7236      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), SLJIT_IMM, 1);
7237      if (needs_control_head)
7238        {
7239        stack--;
7240        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
7241        }
7242    }    }
7243  else  else
7244    {    {
7245    stacksize = framesize + 1;    stacksize = framesize + 1;
7246    if (!zero)    if (!zero)
7247      stacksize++;      stacksize++;
7248    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
7249        stacksize++;
7250      if (offset == 0)
7251      stacksize++;      stacksize++;
7252    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
7253    
7254    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
7255    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);
7256    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
7257    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7258      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
7259    
7260    stack = 0;    stack = 0;
7261    if (!zero)    if (!zero)
7262      {      {
7263      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
7264        stack = 1;
7265        }
7266      if (needs_control_head)
7267        {
7268        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
7269      stack++;      stack++;
7270      }      }
7271    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
7272      {      {
7273      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
7274      stack++;      stack++;
7275      }      }
7276    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
7277    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
7278      stack -= 1 + (offset == 0);
7279    }    }
7280    
7281  if (offset != 0)  if (offset != 0)
# Line 6602  while (*cc != OP_KETRPOS) Line 7351  while (*cc != OP_KETRPOS)
7351          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
7352        }        }
7353      }      }
7354    
7355      if (needs_control_head)
7356        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
7357    
7358    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
7359    flush_stubs(common);    flush_stubs(common);
7360    
# Line 6638  while (*cc != OP_KETRPOS) Line 7391  while (*cc != OP_KETRPOS)
7391    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
7392    }    }
7393    
7394    /* We don't have to restore the control head in case of a failed match. */
7395    
7396  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
7397  if (!zero)  if (!zero)
7398    {    {
# Line 6649  if (!zero) Line 7404  if (!zero)
7404    
7405  /* None of them matched. */  /* None of them matched. */
7406  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
7407  decrease_call_count(common);  count_match(common);
7408  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
7409  }  }
7410    
7411  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)
7412  {  {
7413  int class_len;  int class_len;
7414    
# Line 6689  else if (*opcode >= OP_TYPESTAR && *opco Line 7444  else if (*opcode >= OP_TYPESTAR && *opco
7444    }    }
7445  else  else
7446    {    {
7447    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode == OP_CLASS || *opcode == OP_NCLASS || *opcode == OP_XCLASS);
7448    *type = *opcode;    *type = *opcode;
7449    cc++;    cc++;
7450    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 6700  else Line 7455  else
7455      if (end != NULL)      if (end != NULL)
7456        *end = cc + class_len;        *end = cc + class_len;
7457      }      }
7458      else if (*opcode >= OP_CRPOSSTAR && *opcode <= OP_CRPOSQUERY)
7459        {
7460        *opcode -= OP_CRPOSSTAR - OP_POSSTAR;
7461        if (end != NULL)
7462          *end = cc + class_len;
7463        }
7464    else    else
7465      {      {
7466      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE || *opcode == OP_CRPOSRANGE);
7467      *arg1 = GET2(cc, (class_len + IMM2_SIZE));      *max = GET2(cc, (class_len + IMM2_SIZE));
7468      *arg2 = GET2(cc, class_len);      *min = GET2(cc, class_len);
7469    
7470      if (*arg2 == 0)      if (*min == 0)
7471        {        {
7472        SLJIT_ASSERT(*arg1 != 0);        SLJIT_ASSERT(*max != 0);
7473        *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : OP_MINUPTO;        *opcode = (*opcode == OP_CRRANGE) ? OP_UPTO : (*opcode == OP_CRMINRANGE ? OP_MINUPTO : OP_POSUPTO);
7474        }        }
7475      if (*arg1 == *arg2)      if (*max == *min)
7476        *opcode = OP_EXACT;        *opcode = OP_EXACT;
7477    
7478      if (end != NULL)      if (end != NULL)
# Line 6722  else Line 7483  else
7483    
7484  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)
7485    {    {
7486    *arg1 = GET2(cc, 0);    *max = GET2(cc, 0);
7487    cc += IMM2_SIZE;    cc += IMM2_SIZE;
7488    }    }
7489    
# Line 6751  DEFINE_COMPILER; Line 7512  DEFINE_COMPILER;
7512  backtrack_common *backtrack;  backtrack_common *backtrack;
7513  pcre_uchar opcode;  pcre_uchar opcode;
7514  pcre_uchar type;  pcre_uchar type;
7515  int arg1 = -1, arg2 = -1;  int max = -1, min = -1;
7516  pcre_uchar* end;  pcre_uchar* end;
7517  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
7518  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 6764  int tmp_base, tmp_offset; Line 7525  int tmp_base, tmp_offset;
7525    
7526  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
7527    
7528  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &max, &min, &end);
7529    
7530  switch(type)  switch(type)
7531    {    {
# Line 6835  switch(opcode) Line 7596  switch(opcode)
7596        {        {
7597        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
7598        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
7599        if (opcode == OP_CRRANGE && arg2 > 0)        if (opcode == OP_CRRANGE && min > 0)
7600          CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg2, label);          CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, label);
7601        if (opcode == OP_UPTO || (opcode == OP_CRRANGE && arg1 > 0))        if (opcode == OP_UPTO || (opcode == OP_CRRANGE && max > 0))
7602          jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, arg1);          jump = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, max);
7603        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
7604        }        }
7605    
# Line 6865  switch(opcode) Line 7626  switch(opcode)
7626