/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

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

revision 1275 by zherczeg, Sun Mar 10 05:32:10 2013 UTC revision 1316 by zherczeg, Sun Apr 28 08:54:42 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);
# 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 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 6  #define MAX_RANGE_SIZE 6
310    
311  typedef struct compiler_common {  typedef struct compiler_common {
# 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 360  typedef struct compiler_common { Line 385  typedef struct compiler_common {
385    recurse_entry *currententry;    recurse_entry *currententry;
386    jump_list *partialmatch;    jump_list *partialmatch;
387    jump_list *quit;    jump_list *quit;
388      jump_list *positive_assert_quit;
389    jump_list *forced_quit;    jump_list *forced_quit;
390    jump_list *accept;    jump_list *accept;
391    jump_list *calllimit;    jump_list *calllimit;
# 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
# Line 509  return cc; Line 535  return cc;
535    
536  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
537   next_opcode   next_opcode
538   get_private_data_length   check_opcode_types
539   set_private_data_ptrs   set_private_data_ptrs
540   get_framesize   get_framesize
541   init_frame   init_frame
542   get_private_data_length_for_copy   get_private_data_copy_length
543   copy_private_data   copy_private_data
544   compile_matchingpath   compile_matchingpath
545   compile_backtrackingpath   compile_backtrackingpath
# Line 597  switch(*cc) Line 623  switch(*cc)
623    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
624    case OP_PRUNE:    case OP_PRUNE:
625    case OP_SKIP:    case OP_SKIP:
626      case OP_THEN:
627    case OP_COMMIT:    case OP_COMMIT:
628    case OP_FAIL:    case OP_FAIL:
629    case OP_ACCEPT:    case OP_ACCEPT:
# Line 696  switch(*cc) Line 723  switch(*cc)
723    
724    case OP_MARK:    case OP_MARK:
725    case OP_PRUNE_ARG:    case OP_PRUNE_ARG:
726      case OP_SKIP_ARG:
727      case OP_THEN_ARG:
728    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
729    
730    default:    default:
731      /* All opcodes are supported now! */
732      SLJIT_ASSERT_STOP();
733    return NULL;    return NULL;
734    }    }
735  }  }
736    
737  #define CASE_ITERATOR_PRIVATE_DATA_1 \  static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
     case OP_MINSTAR: \  
     case OP_MINPLUS: \  
     case OP_QUERY: \  
     case OP_MINQUERY: \  
     case OP_MINSTARI: \  
     case OP_MINPLUSI: \  
     case OP_QUERYI: \  
     case OP_MINQUERYI: \  
     case OP_NOTMINSTAR: \  
     case OP_NOTMINPLUS: \  
     case OP_NOTQUERY: \  
     case OP_NOTMINQUERY: \  
     case OP_NOTMINSTARI: \  
     case OP_NOTMINPLUSI: \  
     case OP_NOTQUERYI: \  
     case OP_NOTMINQUERYI:  
   
 #define CASE_ITERATOR_PRIVATE_DATA_2A \  
     case OP_STAR: \  
     case OP_PLUS: \  
     case OP_STARI: \  
     case OP_PLUSI: \  
     case OP_NOTSTAR: \  
     case OP_NOTPLUS: \  
     case OP_NOTSTARI: \  
     case OP_NOTPLUSI:  
   
 #define CASE_ITERATOR_PRIVATE_DATA_2B \  
     case OP_UPTO: \  
     case OP_MINUPTO: \  
     case OP_UPTOI: \  
     case OP_MINUPTOI: \  
     case OP_NOTUPTO: \  
     case OP_NOTMINUPTO: \  
     case OP_NOTUPTOI: \  
     case OP_NOTMINUPTOI:  
   
 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \  
     case OP_TYPEMINSTAR: \  
     case OP_TYPEMINPLUS: \  
     case OP_TYPEQUERY: \  
     case OP_TYPEMINQUERY:  
   
 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \  
     case OP_TYPESTAR: \  
     case OP_TYPEPLUS:  
   
 #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \  
     case OP_TYPEUPTO: \  
     case OP_TYPEMINUPTO:  
   
 static int get_class_iterator_size(pcre_uchar *cc)  
 {  
 switch(*cc)  
   {  
   case OP_CRSTAR:  
   case OP_CRPLUS:  
   return 2;  
   
   case OP_CRMINSTAR:  
   case OP_CRMINPLUS:  
   case OP_CRQUERY:  
   case OP_CRMINQUERY:  
   return 1;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))  
     return 0;  
   return 2;  
   
   default:  
   return 0;  
   }  
 }  
   
 static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  
738  {  {
 int private_data_length = 0;  
 pcre_uchar *alternative;  
739  pcre_uchar *name;  pcre_uchar *name;
740  pcre_uchar *end = NULL;  pcre_uchar *name2;
741  int space, size, i;  unsigned int cbra_index;
742  pcre_uint32 bracketlen;  int i;
743    
744  /* 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. */
745  while (cc < ccend)  while (cc < ccend)
746    {    {
   space = 0;  
   size = 0;  
   bracketlen = 0;  
747    switch(*cc)    switch(*cc)
748      {      {
749      case OP_SET_SOM:      case OP_SET_SOM:
# Line 808  while (cc < ccend) Line 757  while (cc < ccend)
757      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
758      break;      break;
759    
     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;  
   
760      case OP_CBRAPOS:      case OP_CBRAPOS:
761      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     private_data_length += sizeof(sljit_sw);  
762      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
763      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
764      break;      break;
765    
766      case OP_COND:      case OP_COND:
# Line 833  while (cc < ccend) Line 768  while (cc < ccend)
768      /* Only AUTO_CALLOUT can insert this opcode. We do      /* Only AUTO_CALLOUT can insert this opcode. We do
769         not intend to support this case. */         not intend to support this case. */
770      if (cc[1 + LINK_SIZE] == OP_CALLOUT)      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
771        return -1;        return FALSE;
772        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;  
773      break;      break;
774    
775      case OP_CREF:      case OP_CREF:
# Line 854  while (cc < ccend) Line 779  while (cc < ccend)
779      break;      break;
780    
781      case OP_NCREF:      case OP_NCREF:
782      bracketlen = GET2(cc, 1);      cbra_index = GET2(cc, 1);
783      name = (pcre_uchar *)common->name_table;      name = (pcre_uchar *)common->name_table;
784      alternative = name;      name2 = name;
785      for (i = 0; i < common->name_count; i++)      for (i = 0; i < common->name_count; i++)
786        {        {
787        if (GET2(name, 0) == bracketlen) break;        if (GET2(name, 0) == cbra_index) break;
788        name += common->name_entry_size;        name += common->name_entry_size;
789        }        }
790      SLJIT_ASSERT(i != common->name_count);      SLJIT_ASSERT(i != common->name_count);
791    
792      for (i = 0; i < common->name_count; i++)      for (i = 0; i < common->name_count; i++)
793        {        {
794        if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)        if (STRCMP_UC_UC(name2 + IMM2_SIZE, name + IMM2_SIZE) == 0)
795          common->optimized_cbracket[GET2(alternative, 0)] = 0;          common->optimized_cbracket[GET2(name2, 0)] = 0;
796        alternative += common->name_entry_size;        name2 += common->name_entry_size;
797        }        }
     bracketlen = 0;  
798      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
799      break;      break;
800    
     case OP_BRA:  
     bracketlen = 1 + LINK_SIZE;  
     break;  
   
     case OP_CBRA:  
     case OP_SCBRA:  
     bracketlen = 1 + LINK_SIZE + IMM2_SIZE;  
     break;  
   
     CASE_ITERATOR_PRIVATE_DATA_1  
     space = 1;  
     size = -2;  
     break;  
   
     CASE_ITERATOR_PRIVATE_DATA_2A  
     space = 2;  
     size = -2;  
     break;  
   
     CASE_ITERATOR_PRIVATE_DATA_2B  
     space = 2;  
     size = -(2 + IMM2_SIZE);  
     break;  
   
     CASE_ITERATOR_TYPE_PRIVATE_DATA_1  
     space = 1;  
     size = 1;  
     break;  
   
     CASE_ITERATOR_TYPE_PRIVATE_DATA_2A  
     if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)  
       space = 2;  
     size = 1;  
     break;  
   
     CASE_ITERATOR_TYPE_PRIVATE_DATA_2B  
     if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)  
       space = 2;  
     size = 1 + IMM2_SIZE;  
     break;  
   
     case OP_CLASS:  
     case OP_NCLASS:  
     size += 1 + 32 / sizeof(pcre_uchar);  
     space = get_class_iterator_size(cc + size);  
     break;  
   
 #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  
     case OP_XCLASS:  
     size = GET(cc, 1);  
     space = get_class_iterator_size(cc + size);  
     break;  
 #endif  
   
801      case OP_RECURSE:      case OP_RECURSE:
802      /* Set its value only once. */      /* Set its value only once. */
803      if (common->recursive_head_ptr == 0)      if (common->recursive_head_ptr == 0)
# Line 947  while (cc < ccend) Line 817  while (cc < ccend)
817      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
818      break;      break;
819    
820        case OP_THEN_ARG:
821        common->has_then = TRUE;
822        common->control_head_ptr = 1;
823        /* Fall through. */
824    
825      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
826      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
     common->control_head_ptr = 1;  
827      /* Fall through. */      /* Fall through. */
828    
829      case OP_MARK:      case OP_MARK:
# Line 961  while (cc < ccend) Line 835  while (cc < ccend)
835      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
836      break;      break;
837    
838        case OP_THEN:
839        common->has_then = TRUE;
840        common->control_head_ptr = 1;
841        /* Fall through. */
842    
843      case OP_PRUNE:      case OP_PRUNE:
844      case OP_SKIP:      case OP_SKIP:
845      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
846      /* Fall through. */      cc += 1;
847        break;
848    
849      case OP_COMMIT:      case OP_SKIP_ARG:
850      common->control_head_ptr = 1;      common->control_head_ptr = 1;
851      cc += 1;      common->has_skip_arg = TRUE;
852        cc += 1 + 2 + cc[1];
853      break;      break;
854    
855      default:      default:
856      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
857      if (cc == NULL)      if (cc == NULL)
858        return -1;        return FALSE;
859        break;
860        }
861      }
862    return TRUE;
863    }
864    
865    static int get_class_iterator_size(pcre_uchar *cc)
866    {
867    switch(*cc)
868      {
869      case OP_CRSTAR:
870      case OP_CRPLUS:
871      return 2;
872    
873      case OP_CRMINSTAR:
874      case OP_CRMINPLUS:
875      case OP_CRQUERY:
876      case OP_CRMINQUERY:
877      return 1;
878    
879      case OP_CRRANGE:
880      case OP_CRMINRANGE:
881      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
882        return 0;
883      return 2;
884    
885      default:
886      return 0;
887      }
888    }
889    
890    static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
891    {
892    pcre_uchar *end = bracketend(begin);
893    pcre_uchar *next;
894    pcre_uchar *next_end;
895    pcre_uchar *max_end;
896    pcre_uchar type;
897    sljit_sw length = end - begin;
898    int min, max, i;
899    
900    /* Detect fixed iterations first. */
901    if (end[-(1 + LINK_SIZE)] != OP_KET)
902      return FALSE;
903    
904    /* Already detected repeat. */
905    if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
906      return TRUE;
907    
908    next = end;
909    min = 1;
910    while (1)
911      {
912      if (*next != *begin)
913      break;      break;
914      next_end = bracketend(next);
915      if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
916        break;
917      next = next_end;
918      min++;
919      }
920    
921    if (min == 2)
922      return FALSE;
923    
924    max = 0;
925    max_end = next;
926    if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
927      {
928      type = *next;
929      while (1)
930        {
931        if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
932          break;
933        next_end = bracketend(next + 2 + LINK_SIZE);
934        if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
935          break;
936        next = next_end;
937        max++;
938      }      }
939    
940    if (space > 0 && cc >= end)    if (next[0] == type && next[1] == *begin && max >= 1)
941      private_data_length += sizeof(sljit_sw) * space;      {
942        next_end = bracketend(next + 1);
943        if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
944          {
945          for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
946            if (*next_end != OP_KET)
947              break;
948    
949          if (i == max)
950            {
951            common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
952            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
953            /* +2 the original and the last. */
954            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
955            if (min == 1)
956              return TRUE;
957            min--;
958            max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
959            }
960          }
961        }
962      }
963    
964    if (min >= 3)
965      {
966      common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
967      common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
968      common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
969      return TRUE;
970      }
971    
972    return FALSE;
973    }
974    
975    #define CASE_ITERATOR_PRIVATE_DATA_1 \
976        case OP_MINSTAR: \
977        case OP_MINPLUS: \
978        case OP_QUERY: \
979        case OP_MINQUERY: \
980        case OP_MINSTARI: \
981        case OP_MINPLUSI: \
982        case OP_QUERYI: \
983        case OP_MINQUERYI: \
984        case OP_NOTMINSTAR: \
985        case OP_NOTMINPLUS: \
986        case OP_NOTQUERY: \
987        case OP_NOTMINQUERY: \
988        case OP_NOTMINSTARI: \
989        case OP_NOTMINPLUSI: \
990        case OP_NOTQUERYI: \
991        case OP_NOTMINQUERYI:
992    
993    #define CASE_ITERATOR_PRIVATE_DATA_2A \
994        case OP_STAR: \
995        case OP_PLUS: \
996        case OP_STARI: \
997        case OP_PLUSI: \
998        case OP_NOTSTAR: \
999        case OP_NOTPLUS: \
1000        case OP_NOTSTARI: \
1001        case OP_NOTPLUSI:
1002    
1003    #define CASE_ITERATOR_PRIVATE_DATA_2B \
1004        case OP_UPTO: \
1005        case OP_MINUPTO: \
1006        case OP_UPTOI: \
1007        case OP_MINUPTOI: \
1008        case OP_NOTUPTO: \
1009        case OP_NOTMINUPTO: \
1010        case OP_NOTUPTOI: \
1011        case OP_NOTMINUPTOI:
1012    
1013    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1014        case OP_TYPEMINSTAR: \
1015        case OP_TYPEMINPLUS: \
1016        case OP_TYPEQUERY: \
1017        case OP_TYPEMINQUERY:
1018    
1019    if (size != 0)  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1020      {      case OP_TYPESTAR: \
1021      if (size < 0)      case OP_TYPEPLUS:
       {  
       cc += -size;  
 #ifdef SUPPORT_UTF  
       if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
       }  
     else  
       cc += size;  
     }  
1022    
1023    if (bracketlen != 0)  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1024      {      case OP_TYPEUPTO: \
1025      if (cc >= end)      case OP_TYPEMINUPTO:
       {  
       end = bracketend(cc);  
       if (end[-1 - LINK_SIZE] == OP_KET)  
         end = NULL;  
       }  
     cc += bracketlen;  
     }  
   }  
 return private_data_length;  
 }  
1026    
1027  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1028  {  {
1029  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1030  pcre_uchar *alternative;  pcre_uchar *alternative;
1031  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
1032    int private_data_ptr = *private_data_start;
1033  int space, size, bracketlen;  int space, size, bracketlen;
1034    
1035  while (cc < ccend)  while (cc < ccend)
# Line 1020  while (cc < ccend) Line 1037  while (cc < ccend)
1037    space = 0;    space = 0;
1038    size = 0;    size = 0;
1039    bracketlen = 0;    bracketlen = 0;
1040      if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1041        return;
1042    
1043      if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
1044        if (detect_repeat(common, cc))
1045          {
1046          /* These brackets are converted to repeats, so no global
1047          based single character repeat is allowed. */
1048          if (cc >= end)
1049            end = bracketend(cc);
1050          }
1051    
1052    switch(*cc)    switch(*cc)
1053      {      {
1054        case OP_KET:
1055        if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1056          {
1057          common->private_data_ptrs[cc - common->start] = private_data_ptr;
1058          private_data_ptr += sizeof(sljit_sw);
1059          cc += common->private_data_ptrs[cc + 1 - common->start];
1060          }
1061        cc += 1 + LINK_SIZE;
1062        break;
1063    
1064      case OP_ASSERT:      case OP_ASSERT:
1065      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1066      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1115  while (cc < ccend) Line 1154  while (cc < ccend)
1154      break;      break;
1155      }      }
1156    
1157      /* Character iterators, which are not inside a repeated bracket,
1158         gets a private slot instead of allocating it on the stack. */
1159    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1160      {      {
1161      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 1186  while (cc < ccend)
1186      cc += bracketlen;      cc += bracketlen;
1187      }      }
1188    }    }
1189    *private_data_start = private_data_ptr;
1190  }  }
1191    
1192  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1193  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)
1194  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1195  int length = 0;  int length = 0;
1196  int possessive = 0;  int possessive = 0;
1197  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1159  BOOL setmark_found = recursive; Line 1200  BOOL setmark_found = recursive;
1200  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1201  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1202    
1203  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1204    SLJIT_ASSERT(common->control_head_ptr != 0);
1205    *needs_control_head = TRUE;
1206    #else
1207    *needs_control_head = FALSE;
1208    #endif
1209    
1210    if (ccend == NULL)
1211    {    {
1212    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1213    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1214    capture_last_found = TRUE;      {
1215        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1216        /* This is correct regardless of common->capture_last_ptr. */
1217        capture_last_found = TRUE;
1218        }
1219      cc = next_opcode(common, cc);
1220    }    }
1221    
 cc = next_opcode(common, cc);  
1222  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1223  while (cc < ccend)  while (cc < ccend)
1224    switch(*cc)    switch(*cc)
# Line 1184  while (cc < ccend) Line 1236  while (cc < ccend)
1236    
1237      case OP_MARK:      case OP_MARK:
1238      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1239        case OP_THEN_ARG:
1240      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1241      stack_restore = TRUE;      stack_restore = TRUE;
1242      if (!setmark_found)      if (!setmark_found)
# Line 1191  while (cc < ccend) Line 1244  while (cc < ccend)
1244        length += 2;        length += 2;
1245        setmark_found = TRUE;        setmark_found = TRUE;
1246        }        }
1247        if (common->control_head_ptr != 0)
1248          *needs_control_head = TRUE;
1249      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1250      break;      break;
1251    
# Line 1310  if (length > 0) Line 1365  if (length > 0)
1365  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1366  }  }
1367    
1368  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)
1369  {  {
1370  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1371  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1372  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1373  /* 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 1379  SLJIT_UNUSED_ARG(stacktop);
1379  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1380    
1381  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1382  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1383    cc = next_opcode(common, cc);    {
1384      ccend = bracketend(cc) - (1 + LINK_SIZE);
1385      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1386        cc = next_opcode(common, cc);
1387      }
1388    
1389  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1390  while (cc < ccend)  while (cc < ccend)
1391    switch(*cc)    switch(*cc)
# Line 1347  while (cc < ccend) Line 1406  while (cc < ccend)
1406    
1407      case OP_MARK:      case OP_MARK:
1408      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1409        case OP_THEN_ARG:
1410      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1411      if (!setmark_found)      if (!setmark_found)
1412        {        {
# Line 1427  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1487  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1487  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1488  }  }
1489    
1490  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)
1491  {  {
1492  int private_data_length = common->control_head_ptr ? 3 : 2;  int private_data_length = needs_control_head ? 3 : 2;
1493  int size;  int size;
1494  pcre_uchar *alternative;  pcre_uchar *alternative;
1495  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1438  while (cc < ccend) Line 1498  while (cc < ccend)
1498    size = 0;    size = 0;
1499    switch(*cc)    switch(*cc)
1500      {      {
1501        case OP_KET:
1502        if (PRIVATE_DATA(cc) != 0)
1503          private_data_length++;
1504        cc += 1 + LINK_SIZE;
1505        break;
1506    
1507      case OP_ASSERT:      case OP_ASSERT:
1508      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1509      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1542  return private_data_length; Line 1608  return private_data_length;
1608  }  }
1609    
1610  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,
1611    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1612  {  {
1613  DEFINE_COMPILER;  DEFINE_COMPILER;
1614  int srcw[2];  int srcw[2];
# Line 1563  stacktop = STACK(stacktop - 1); Line 1629  stacktop = STACK(stacktop - 1);
1629    
1630  if (!save)  if (!save)
1631    {    {
1632    stackptr += (common->control_head_ptr ? 2 : 1) * sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1633    if (stackptr < stacktop)    if (stackptr < stacktop)
1634      {      {
1635      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1588  do Line 1654  do
1654      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1655      count = 1;      count = 1;
1656      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1657      if (common->control_head_ptr != 0)      if (needs_control_head)
1658        {        {
1659          SLJIT_ASSERT(common->control_head_ptr != 0);
1660        count = 2;        count = 2;
1661        srcw[1] = common->control_head_ptr;        srcw[1] = common->control_head_ptr;
1662        }        }
# Line 1605  do Line 1672  do
1672    
1673      switch(*cc)      switch(*cc)
1674        {        {
1675          case OP_KET:
1676          if (PRIVATE_DATA(cc) != 0)
1677            {
1678            count = 1;
1679            srcw[0] = PRIVATE_DATA(cc);
1680            }
1681          cc += 1 + LINK_SIZE;
1682          break;
1683    
1684        case OP_ASSERT:        case OP_ASSERT:
1685        case OP_ASSERT_NOT:        case OP_ASSERT_NOT:
1686        case OP_ASSERTBACK:        case OP_ASSERTBACK:
# Line 1851  if (save) Line 1927  if (save)
1927  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1928  }  }
1929    
1930    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1931    {
1932    pcre_uchar *end = bracketend(cc);
1933    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1934    
1935    /* Assert captures then. */
1936    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1937      current_offset = NULL;
1938    /* Conditional block does not. */
1939    if (*cc == OP_COND || *cc == OP_SCOND)
1940      has_alternatives = FALSE;
1941    
1942    cc = next_opcode(common, cc);
1943    if (has_alternatives)
1944      current_offset = common->then_offsets + (cc - common->start);
1945    
1946    while (cc < end)
1947      {
1948      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1949        cc = set_then_offsets(common, cc, current_offset);
1950      else
1951        {
1952        if (*cc == OP_ALT && has_alternatives)
1953          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1954        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1955          *current_offset = 1;
1956        cc = next_opcode(common, cc);
1957        }
1958      }
1959    
1960    return end;
1961    }
1962    
1963  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1964  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1965  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1914  while (list_item) Line 2023  while (list_item)
2023  common->stubs = NULL;  common->stubs = NULL;
2024  }  }
2025    
2026  static SLJIT_INLINE void decrease_call_count(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2027  {  {
2028  DEFINE_COMPILER;  DEFINE_COMPILER;
2029    
2030  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);
2031  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
2032  }  }
2033    
# Line 1998  else Line 2107  else
2107  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2108  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2109    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);
2110  SLJIT_ASSERT(common->control_head_ptr != 0);  if (common->control_head_ptr != 0)
2111  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);
2112  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));
2113  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);
2114  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));
2115  }  }
2116    
2117  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)
2118  {  {
2119  sljit_sw return_value = 0;  while (current != NULL)
   
 SLJIT_ASSERT(current != NULL);  
 do  
2120    {    {
2121    switch (current[-2])    switch (current[-2])
2122      {      {
2123      case type_commit:      case type_then_trap:
     /* Commit overwrites all. */  
     return -1;  
   
     case type_prune:  
2124      break;      break;
2125    
2126      case type_skip:      case type_mark:
2127      /* Overwrites prune, but not other skips. */      if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2128      if (return_value == 0)        return current[-4];
       return_value = current[-3];  
2129      break;      break;
2130    
2131      default:      default:
# Line 2033  do Line 2134  do
2134      }      }
2135    current = (sljit_sw*)current[-1];    current = (sljit_sw*)current[-1];
2136    }    }
2137  while (current != NULL);  return -1;
 return return_value;  
2138  }  }
2139    
2140  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 2206  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2206  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));
2207    
2208  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);
2209  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);
2210  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2211  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);
2212  #endif  #endif
# Line 5193  if (!minimize) Line 5293  if (!minimize)
5293    JUMPHERE(zerolength);    JUMPHERE(zerolength);
5294    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5295    
5296    decrease_call_count(common);    count_match(common);
5297    return cc;    return cc;
5298    }    }
5299    
# Line 5232  if (jump != NULL) Line 5332  if (jump != NULL)
5332    JUMPHERE(jump);    JUMPHERE(jump);
5333  JUMPHERE(zerolength);  JUMPHERE(zerolength);
5334    
5335  decrease_call_count(common);  count_match(common);
5336  return cc;  return cc;
5337  }  }
5338    
# Line 5242  DEFINE_COMPILER; Line 5342  DEFINE_COMPILER;
5342  backtrack_common *backtrack;  backtrack_common *backtrack;
5343  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5344  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5345  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5346  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5347    BOOL needs_control_head;
5348    
5349  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5350    
5351  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5352  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5353    {    {
5354    start_cc = common->start + start;    start_cc = common->start + start;
5355    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 5509  static pcre_uchar *compile_assert_matchi
5509  DEFINE_COMPILER;  DEFINE_COMPILER;
5510  int framesize;  int framesize;
5511  int extrasize;  int extrasize;
5512  BOOL needs_control_head = common->control_head_ptr != 0;  BOOL needs_control_head;
5513  int private_data_ptr;  int private_data_ptr;
5514  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5515  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5418  jump_list *tmp = NULL; Line 5519  jump_list *tmp = NULL;
5519  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5520  jump_list **found;  jump_list **found;
5521  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5522    BOOL save_local_exit = common->local_exit;
5523    BOOL save_positive_assert = common->positive_assert;
5524    then_trap_backtrack *save_then_trap = common->then_trap;
5525  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5526  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5527  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5528    jump_list *save_positive_assert_quit = common->positive_assert_quit;
5529  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
 BOOL save_local_exit = common->local_exit;  
5530  struct sljit_jump *jump;  struct sljit_jump *jump;
5531  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5532    
5533    /* Assert captures then. */
5534    common->then_trap = NULL;
5535    
5536  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5537    {    {
5538    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5434  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5541  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5541    }    }
5542  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5543  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5544  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5545  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5546  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5547  opcode = *cc;  opcode = *cc;
# Line 5454  if (bra == OP_BRAMINZERO) Line 5561  if (bra == OP_BRAMINZERO)
5561  if (framesize < 0)  if (framesize < 0)
5562    {    {
5563    extrasize = needs_control_head ? 2 : 1;    extrasize = needs_control_head ? 2 : 1;
5564    if (framesize != no_stack)    if (framesize == no_frame)
5565      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);
5566    allocate_stack(common, extrasize);    allocate_stack(common, extrasize);
5567    if (needs_control_head)    if (needs_control_head)
# Line 5484  else Line 5591  else
5591      }      }
5592    else    else
5593      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5594    init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);    init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5595    }    }
5596    
5597  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5598  common->local_exit = TRUE;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5599  common->quit_label = NULL;    {
5600  common->quit = NULL;    /* Negative assert is stronger than positive assert. */
5601      common->local_exit = TRUE;
5602      common->quit_label = NULL;
5603      common->quit = NULL;
5604      common->positive_assert = FALSE;
5605      }
5606    else
5607      common->positive_assert = TRUE;
5608    common->positive_assert_quit = NULL;
5609    
5610  while (1)  while (1)
5611    {    {
5612    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5505  while (1) Line 5621  while (1)
5621    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5622    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5623      {      {
5624      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5625      common->quit_label = save_quit_label;        {
5626          common->local_exit = save_local_exit;
5627          common->quit_label = save_quit_label;
5628          common->quit = save_quit;
5629          }
5630        common->positive_assert = save_positive_assert;
5631        common->then_trap = save_then_trap;
5632      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5633      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5634      common->accept = save_accept;      common->accept = save_accept;
5635      return NULL;      return NULL;
5636      }      }
# Line 5519  while (1) Line 5641  while (1)
5641    /* Reset stack. */    /* Reset stack. */
5642    if (framesize < 0)    if (framesize < 0)
5643      {      {
5644      if (framesize != no_stack)      if (framesize == no_frame)
5645        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);
5646      else      else
5647        free_stack(common, extrasize);        free_stack(common, extrasize);
# Line 5573  while (1) Line 5695  while (1)
5695    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5696    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5697      {      {
5698      common->local_exit = save_local_exit;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5699      common->quit_label = save_quit_label;        {
5700          common->local_exit = save_local_exit;
5701          common->quit_label = save_quit_label;
5702          common->quit = save_quit;
5703          }
5704        common->positive_assert = save_positive_assert;
5705        common->then_trap = save_then_trap;
5706      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5707      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5708      common->accept = save_accept;      common->accept = save_accept;
5709      return NULL;      return NULL;
5710      }      }
# Line 5589  while (1) Line 5717  while (1)
5717    cc += GET(cc, 1);    cc += GET(cc, 1);
5718    }    }
5719    
5720    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5721      {
5722      SLJIT_ASSERT(common->positive_assert_quit == NULL);
5723      /* Makes the check less complicated below. */
5724      common->positive_assert_quit = common->quit;
5725      }
5726    
5727  /* None of them matched. */  /* None of them matched. */
5728  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
5729    {    {
5730    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5731    set_jumps(common->quit, LABEL());    set_jumps(common->positive_assert_quit, LABEL());
5732    SLJIT_ASSERT(framesize != no_stack);    SLJIT_ASSERT(framesize != no_stack);
5733    if (framesize < 0)    if (framesize < 0)
5734      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 5888  else
5888      }      }
5889    }    }
5890    
5891  common->local_exit = save_local_exit;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5892  common->quit_label = save_quit_label;    {
5893      common->local_exit = save_local_exit;
5894      common->quit_label = save_quit_label;
5895      common->quit = save_quit;
5896      }
5897    common->positive_assert = save_positive_assert;
5898    common->then_trap = save_then_trap;
5899  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5900  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
5901  common->accept = save_accept;  common->accept = save_accept;
5902  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5903  }  }
# Line 5871  if (i < name_count) Line 6012  if (i < name_count)
6012  return condition;  return condition;
6013  }  }
6014    
6015    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)
6016    {
6017    DEFINE_COMPILER;
6018    int stacksize;
6019    
6020    if (framesize < 0)
6021      {
6022      if (framesize == no_frame)
6023        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6024      else
6025        {
6026        stacksize = needs_control_head ? 1 : 0;
6027        if (ket != OP_KET || has_alternatives)
6028          stacksize++;
6029        free_stack(common, stacksize);
6030        }
6031    
6032      if (needs_control_head)
6033        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6034    
6035      /* TMP2 which is set here used by OP_KETRMAX below. */
6036      if (ket == OP_KETRMAX)
6037        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6038      else if (ket == OP_KETRMIN)
6039        {
6040        /* Move the STR_PTR to the private_data_ptr. */
6041        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6042        }
6043      }
6044    else
6045      {
6046      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6047      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6048      if (needs_control_head)
6049        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6050    
6051      if (ket == OP_KETRMAX)
6052        {
6053        /* TMP2 which is set here used by OP_KETRMAX below. */
6054        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6055        }
6056      }
6057    if (needs_control_head)
6058      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6059    }
6060    
6061    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6062    {
6063    DEFINE_COMPILER;
6064    
6065    if (common->capture_last_ptr != 0)
6066      {
6067      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6068      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6069      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6070      stacksize++;
6071      }
6072    if (common->optimized_cbracket[offset >> 1] == 0)
6073      {
6074      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6075      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6076      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6077      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6078      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6079      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6080      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6081      stacksize += 2;
6082      }
6083    return stacksize;
6084    }
6085    
6086  /*  /*
6087    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6088    
# Line 5933  pcre_uchar opcode; Line 6145  pcre_uchar opcode;
6145  int private_data_ptr = 0;  int private_data_ptr = 0;
6146  int offset = 0;  int offset = 0;
6147  int stacksize;  int stacksize;
6148    int repeat_ptr = 0, repeat_length = 0;
6149    int repeat_type = 0, repeat_count = 0;
6150  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6151  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6152  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6153  pcre_uchar ket;  pcre_uchar ket;
6154  assert_backtrack *assert;  assert_backtrack *assert;
6155  BOOL has_alternatives;  BOOL has_alternatives;
6156    BOOL needs_control_head = FALSE;
6157  struct sljit_jump *jump;  struct sljit_jump *jump;
6158  struct sljit_jump *skip;  struct sljit_jump *skip;
6159  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmax_label = NULL;
6160  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzero = NULL;
6161    
6162  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6163    
# Line 5955  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6170  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6170    
6171  opcode = *cc;  opcode = *cc;
6172  ccbegin = cc;  ccbegin = cc;
6173  matchingpath = ccbegin + 1 + LINK_SIZE;  matchingpath = bracketend(cc) - 1 - LINK_SIZE;
6174    ket = *matchingpath;
6175    if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
6176      {
6177      repeat_ptr = PRIVATE_DATA(matchingpath);
6178      repeat_length = PRIVATE_DATA(matchingpath + 1);
6179      repeat_type = PRIVATE_DATA(matchingpath + 2);
6180      repeat_count = PRIVATE_DATA(matchingpath + 3);
6181      SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
6182      if (repeat_type == OP_UPTO)
6183        ket = OP_KETRMAX;
6184      if (repeat_type == OP_MINUPTO)
6185        ket = OP_KETRMIN;
6186      }
6187    
6188  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)
6189    {    {
6190    /* Drop this bracket_backtrack. */    /* Drop this bracket_backtrack. */
6191    parent->top = backtrack->prev;    parent->top = backtrack->prev;
6192    return bracketend(cc);    return matchingpath + 1 + LINK_SIZE + repeat_length;
6193    }    }
6194    
6195  ket = *(bracketend(cc) - 1 - LINK_SIZE);  matchingpath = ccbegin + 1 + LINK_SIZE;
6196  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
6197  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)));
6198  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 6014  else if (opcode == OP_ONCE || opcode == Line 6242  else if (opcode == OP_ONCE || opcode ==
6242    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6243    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6244    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6245      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);
6246    }    }
6247    
6248  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6249  stacksize = 0;  stacksize = 0;
6250  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6251    stacksize++;    stacksize++;
6252  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6253    stacksize++;    stacksize++;
# Line 6028  if (stacksize > 0) Line 6256  if (stacksize > 0)
6256    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6257    
6258  stacksize = 0;  stacksize = 0;
6259  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6260    {    {
6261    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6262    stacksize++;    stacksize++;
# Line 6044  if (bra == OP_BRAMINZERO) Line 6272  if (bra == OP_BRAMINZERO)
6272    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
6273      {      {
6274      free_stack(common, 1);      free_stack(common, 1);
6275      braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);      braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6276      }      }
6277    else    else
6278      {      {
# Line 6059  if (bra == OP_BRAMINZERO) Line 6287  if (bra == OP_BRAMINZERO)
6287        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6288          {          {
6289          /* 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. */
6290          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);
6291          }          }
6292        else        else
6293          {          {
6294          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
6295          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);
6296          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));
6297          }          }
6298        JUMPHERE(skip);        JUMPHERE(skip);
6299        }        }
# Line 6078  if (bra == OP_BRAMINZERO) Line 6306  if (bra == OP_BRAMINZERO)
6306      }      }
6307    }    }
6308    
6309    if (repeat_type != 0)
6310      {
6311      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
6312      if (repeat_type == OP_EXACT)
6313        rmax_label = LABEL();
6314      }
6315    
6316  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
6317    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6318    
6319  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6320    {    {
6321    rmaxlabel = LABEL();    rmax_label = LABEL();
6322    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
6323      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
6324    }    }
6325    
6326  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6327  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6328    {    {
6329      stacksize = 0;
6330      if (needs_control_head)
6331        {
6332        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6333        stacksize++;
6334        }
6335    
6336    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6337      {      {
6338      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6339      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6340        {        {
6341        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6342        allocate_stack(common, 2);        if (!needs_control_head)
6343        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));  
6344        }        }
6345      else if (ket == OP_KETRMAX || has_alternatives)      else
6346        {        {
6347        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6348        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6349        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6350            stacksize++;
6351        }        }
6352      else  
6353        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6354          allocate_stack(common, stacksize);
6355    
6356        stacksize = 0;
6357        if (needs_control_head)
6358          {
6359          stacksize++;
6360          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6361          }
6362    
6363        if (ket == OP_KETRMIN)
6364          {
6365          if (needs_control_head)
6366            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6367          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6368          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6369            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));
6370          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6371          }
6372        else if (ket == OP_KETRMAX || has_alternatives)
6373          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6374      }      }
6375    else    else
6376      {      {
6377      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6378          stacksize++;
6379    
6380        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6381        allocate_stack(common, stacksize);
6382    
6383        if (needs_control_head)
6384          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6385    
6386        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6387        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6388    
6389        stacksize = needs_control_head ? 1 : 0;
6390        if (ket != OP_KET || has_alternatives)
6391        {        {
6392        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);  
6393        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);
6394        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6395        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6396        }        }
6397      else      else
6398        {        {
       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));  
6399        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);
6400        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);  
6401        }        }
6402        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6403      }      }
6404    }    }
6405  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6267  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6535  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6535    return NULL;    return NULL;
6536    
6537  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6538    {    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));  
       }  
     }  
   }  
6539    
6540  stacksize = 0;  stacksize = 0;
6541    if (repeat_type == OP_MINUPTO)
6542      {
6543      /* We need to preserve the counter. TMP2 will be used below. */
6544      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6545      stacksize++;
6546      }
6547  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6548    stacksize++;    stacksize++;
6549  if (offset != 0)  if (offset != 0)
# Line 6309  if (stacksize > 0) Line 6560  if (stacksize > 0)
6560    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6561    
6562  stacksize = 0;  stacksize = 0;
6563    if (repeat_type == OP_MINUPTO)
6564      {
6565      /* TMP2 was set above. */
6566      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
6567      stacksize++;
6568      }
6569    
6570  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6571    {    {
6572    if (ket != OP_KET)    if (ket != OP_KET)
# Line 6319  if (ket != OP_KET || bra != OP_BRA) Line 6577  if (ket != OP_KET || bra != OP_BRA)
6577    }    }
6578    
6579  if (offset != 0)  if (offset != 0)
6580    {    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;  
     }  
   }  
6581    
6582  if (has_alternatives)  if (has_alternatives)
6583    {    {
# Line 6357  if (offset != 0 && common->optimized_cbr Line 6596  if (offset != 0 && common->optimized_cbr
6596    
6597  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6598    {    {
6599    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (repeat_type != 0)
6600        {
6601        if (has_alternatives)
6602          BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6603        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6604        JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
6605        /* Drop STR_PTR for greedy plus quantifier. */
6606        if (opcode != OP_ONCE)
6607          free_stack(common, 1);
6608        }
6609      else if (opcode == OP_ONCE || opcode >= OP_SBRA)
6610      {      {
6611      if (has_alternatives)      if (has_alternatives)
6612        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6613      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
6614      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
6615        {        {
6616        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);
6617        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
6618        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
6619          free_stack(common, 1);          free_stack(common, 1);
6620        }        }
6621      else      else
6622        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
6623        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
6624      }      }
6625    else    else
6626      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmax_label);
6627    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6628    }    }
6629    
6630    if (repeat_type == OP_EXACT)
6631      {
6632      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6633      JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
6634      }
6635    else if (repeat_type == OP_UPTO)
6636      {
6637      /* We need to preserve the counter. */
6638      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6639      allocate_stack(common, 1);
6640      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6641      }
6642    
6643  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6644    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
6645    
# Line 6385  if (bra == OP_BRAMINZERO) Line 6647  if (bra == OP_BRAMINZERO)
6647    {    {
6648    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
6649    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
6650    if (braminzerojump != NULL)    if (braminzero != NULL)
6651      {      {
6652      JUMPHERE(braminzerojump);      JUMPHERE(braminzero);
6653      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
6654      backtrack for the zero-length iteration. When      backtrack for the zero-length iteration. When
6655      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 6665  if (bra == OP_BRAMINZERO)
6665    }    }
6666    
6667  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
6668    decrease_call_count(common);    count_match(common);
6669    
6670  /* Skip the other alternatives. */  /* Skip the other alternatives. */
6671  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6672    cc += GET(cc, 1);    cc += GET(cc, 1);
6673  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6674  return cc;  
6675    /* Temporarily encoding the needs_control_head in framesize. */
6676    if (opcode == OP_ONCE)
6677      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6678    return cc + repeat_length;
6679  }  }
6680    
6681  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 6685  backtrack_common *backtrack;
6685  pcre_uchar opcode;  pcre_uchar opcode;
6686  int private_data_ptr;  int private_data_ptr;
6687  int cbraprivptr = 0;  int cbraprivptr = 0;
6688    BOOL needs_control_head;
6689  int framesize;  int framesize;
6690  int stacksize;  int stacksize;
6691  int offset = 0;  int offset = 0;
6692  BOOL zero = FALSE;  BOOL zero = FALSE;
6693  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6694  int stack;  int stack; /* Also contains the offset of control head. */
6695  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6696  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6697    
# Line 6462  switch(opcode) Line 6729  switch(opcode)
6729    break;    break;
6730    }    }
6731    
6732  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6733  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6734  if (framesize < 0)  if (framesize < 0)
6735    {    {
# Line 6475  if (framesize < 0) Line 6742  if (framesize < 0)
6742    else    else
6743      stacksize = 1;      stacksize = 1;
6744    
6745      if (needs_control_head)
6746        stacksize++;
6747    if (!zero)    if (!zero)
6748      stacksize++;      stacksize++;
6749    
# Line 6483  if (framesize < 0) Line 6752  if (framesize < 0)
6752    if (framesize == no_frame)    if (framesize == no_frame)
6753      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);
6754    
6755      stack = 0;
6756    if (offset != 0)    if (offset != 0)
6757      {      {
6758        stack = 2;
6759      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6760      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));
6761      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6762      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6763        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);
6764      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6765        if (needs_control_head)
6766          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6767      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6768          {
6769        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6770          stack = 3;
6771          }
6772      }      }
6773    else    else
6774        {
6775        if (needs_control_head)
6776          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6777      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6778        stack = 1;
6779        }
6780    
6781      if (needs_control_head)
6782        stack++;
6783    if (!zero)    if (!zero)
6784      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);
6785      if (needs_control_head)
6786        {
6787        stack--;
6788        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6789        }
6790    }    }
6791  else  else
6792    {    {
6793    stacksize = framesize + 1;    stacksize = framesize + 1;
6794    if (!zero)    if (!zero)
6795      stacksize++;      stacksize++;
6796    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6797        stacksize++;
6798      if (offset == 0)
6799      stacksize++;      stacksize++;
6800    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6801    
6802    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6803    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);
6804    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6805    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);
6806      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6807    
6808    stack = 0;    stack = 0;
6809    if (!zero)    if (!zero)
6810      {      {
6811      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6812        stack = 1;
6813        }
6814      if (needs_control_head)
6815        {
6816        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6817      stack++;      stack++;
6818      }      }
6819    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6820      {      {
6821      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6822      stack++;      stack++;
6823      }      }
6824    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6825    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6826      stack -= 1 + (offset == 0);
6827    }    }
6828    
6829  if (offset != 0)  if (offset != 0)
# Line 6602  while (*cc != OP_KETRPOS) Line 6899  while (*cc != OP_KETRPOS)
6899          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6900        }        }
6901      }      }
6902    
6903      if (needs_control_head)
6904        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6905    
6906    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6907    flush_stubs(common);    flush_stubs(common);
6908    
# Line 6638  while (*cc != OP_KETRPOS) Line 6939  while (*cc != OP_KETRPOS)
6939    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6940    }    }
6941    
6942    /* We don't have to restore the control head in case of a failed match. */
6943    
6944  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6945  if (!zero)  if (!zero)
6946    {    {
# Line 6649  if (!zero) Line 6952  if (!zero)
6952    
6953  /* None of them matched. */  /* None of them matched. */
6954  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
6955  decrease_call_count(common);  count_match(common);
6956  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
6957  }  }
6958    
# Line 6959  switch(opcode) Line 7262  switch(opcode)
7262    break;    break;
7263    }    }
7264    
7265  decrease_call_count(common);  count_match(common);
7266  return end;  return end;
7267  }  }
7268    
# Line 7026  if (!optimized_cbracket) Line 7329  if (!optimized_cbracket)
7329  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7330  }  }
7331    
7332    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7333    {
7334    DEFINE_COMPILER;
7335    backtrack_common *backtrack;
7336    pcre_uchar opcode = *cc;
7337    pcre_uchar *ccend = cc + 1;
7338    
7339    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7340      ccend += 2 + cc[1];
7341    
7342    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7343    
7344    if (opcode == OP_SKIP)
7345      {
7346      allocate_stack(common, 1);
7347      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7348      return ccend;
7349      }
7350    
7351    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7352      {
7353      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7354      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7355      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7356      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7357      }
7358    
7359    return ccend;
7360    }
7361    
7362    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7363    
7364    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7365    {
7366    DEFINE_COMPILER;
7367    backtrack_common *backtrack;
7368    BOOL needs_control_head;
7369    int size;
7370    
7371    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7372    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7373    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7374    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7375    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7376    
7377    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7378    size = 3 + (size < 0 ? 0 : size);
7379    
7380    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7381    allocate_stack(common, size);
7382    if (size > 3)
7383      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7384    else
7385      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7386    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7387    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7388    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7389    
7390    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7391    if (size >= 0)
7392      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7393    }
7394    
7395  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)  static void compile_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7396  {  {
7397  DEFINE_COMPILER;  DEFINE_COMPILER;
7398  backtrack_common *backtrack;  backtrack_common *backtrack;
7399    BOOL has_then_trap = FALSE;
7400    then_trap_backtrack *save_then_trap = NULL;
7401    
7402    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7403    
7404    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7405      {
7406      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7407      has_then_trap = TRUE;
7408      save_then_trap = common->then_trap;
7409      /* Tail item on backtrack. */
7410      compile_then_trap_matchingpath(common, cc, ccend, parent);
7411      }
7412    
7413  while (cc < ccend)  while (cc < ccend)
7414    {    {
# Line 7210  while (cc < ccend) Line 7589  while (cc < ccend)
7589        }        }
7590      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
7591      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
7592        decrease_call_count(common);        count_match(common);
7593      break;      break;
7594    
7595      case OP_ONCE:      case OP_ONCE:
# Line 7246  while (cc < ccend) Line 7625  while (cc < ccend)
7625      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7626      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7627      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
7628      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7629      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7630      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
7631      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7632      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7633      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7634        if (common->has_skip_arg)
7635          {
7636          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7637          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7638          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7639          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7640          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7641          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7642          }
7643      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7644      break;      break;
7645    
     case OP_PRUNE_ARG:  
     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);  
     /* Fall through. */  
   
7646      case OP_PRUNE:      case OP_PRUNE:
7647      case OP_COMMIT:      case OP_PRUNE_ARG:
     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);  
     SLJIT_ASSERT(common->control_head_ptr != 0);  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);  
     allocate_stack(common, 2);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
     cc += (*cc == OP_PRUNE_ARG) ? (1 + 2 + cc[1]) : 1;  
     break;  
   
7648      case OP_SKIP:      case OP_SKIP:
7649      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      case OP_SKIP_ARG:
7650      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);      case OP_THEN:
7651      allocate_stack(common, 3);      case OP_THEN_ARG:
7652      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);      case OP_COMMIT:
7653      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_skip);      cc = compile_control_verb_matchingpath(common, cc, parent);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);  
     cc += 1;  
7654      break;      break;
7655    
7656      case OP_FAIL:      case OP_FAIL:
# Line 7306  while (cc < ccend) Line 7674  while (cc < ccend)
7674    if (cc == NULL)    if (cc == NULL)
7675      return;      return;
7676    }    }
7677    
7678    if (has_then_trap)
7679      {
7680      /* Head item on backtrack. */
7681      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7682      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7683      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7684      common->then_trap = save_then_trap;
7685      }
7686  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7687  }  }
7688    
# Line 7467  switch(opcode) Line 7844  switch(opcode)
7844    }    }
7845  }  }
7846    
7847  static void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_ref_iterator_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7848  {  {
7849  DEFINE_COMPILER;  DEFINE_COMPILER;
7850  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7489  set_jumps(current->topbacktracks, LABEL( Line 7866  set_jumps(current->topbacktracks, LABEL(
7866  free_stack(common, 2);  free_stack(common, 2);
7867  }  }
7868    
7869  static void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_recurse_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7870  {  {
7871  DEFINE_COMPILER;  DEFINE_COMPILER;
7872    
# Line 7585  if (bra == OP_BRAZERO) Line 7962  if (bra == OP_BRAZERO)
7962  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7963  {  {
7964  DEFINE_COMPILER;  DEFINE_COMPILER;
7965  int opcode;  int opcode, stacksize, count;
7966  int offset = 0;  int offset = 0;
7967  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7968  int stacksize;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
 int count;  
7969  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
7970  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
7971  pcre_uchar *ccprev;  pcre_uchar *ccprev;
# Line 7599  pcre_uchar bra = OP_BRA; Line 7975  pcre_uchar bra = OP_BRA;
7975  pcre_uchar ket;  pcre_uchar ket;
7976  assert_backtrack *assert;  assert_backtrack *assert;
7977  BOOL has_alternatives;  BOOL has_alternatives;
7978    BOOL needs_control_head = FALSE;
7979  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7980  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7981  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
7982  struct sljit_label *rminlabel = NULL;  struct sljit_label *rmin_label = NULL;
7983    struct sljit_label *exact_label = NULL;
7984    
7985  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
7986    {    {
# Line 7611  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 7989  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
7989    }    }
7990    
7991  opcode = *cc;  opcode = *cc;
7992    ccbegin = bracketend(cc) - 1 - LINK_SIZE;
7993    ket = *ccbegin;
7994    if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
7995      {
7996      repeat_ptr = PRIVATE_DATA(ccbegin);
7997      repeat_type = PRIVATE_DATA(ccbegin + 2);
7998      repeat_count = PRIVATE_DATA(ccbegin + 3);
7999      SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
8000      if (repeat_type == OP_UPTO)
8001        ket = OP_KETRMAX;
8002      if (repeat_type == OP_MINUPTO)
8003        ket = OP_KETRMIN;
8004      }
8005  ccbegin = cc;  ccbegin = cc;
 ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  
8006  cc += GET(cc, 1);  cc += GET(cc, 1);
8007  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
8008  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
# Line 7624  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 8014  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
8014  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
8015    opcode = OP_ONCE;    opcode = OP_ONCE;
8016    
8017    /* Decoding the needs_control_head in framesize. */
8018    if (opcode == OP_ONCE)
8019      {
8020      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
8021      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
8022      }
8023    
8024    if (ket != OP_KET && repeat_type != 0)
8025      {
8026      /* TMP1 is used in OP_KETRMIN below. */
8027      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8028      free_stack(common, 1);
8029      if (repeat_type == OP_UPTO)
8030        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
8031      else
8032        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8033      }
8034    
8035  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
8036    {    {
8037    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7638  else if (ket == OP_KETRMIN) Line 8046  else if (ket == OP_KETRMIN)
8046    if (bra != OP_BRAMINZERO)    if (bra != OP_BRAMINZERO)
8047      {      {
8048      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8049      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (repeat_type != 0)
8050          {
8051          /* TMP1 was set a few lines above. */
8052          CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8053          /* Drop STR_PTR for non-greedy plus quantifier. */
8054          if (opcode != OP_ONCE)
8055            free_stack(common, 1);
8056          }
8057        else if (opcode >= OP_SBRA || opcode == OP_ONCE)
8058        {        {
8059        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
8060        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 7648  else if (ket == OP_KETRMIN) Line 8064  else if (ket == OP_KETRMIN)
8064          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);
8065          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);          CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (CURRENT_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw), CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8066          }          }
8067          /* Drop STR_PTR for non-greedy plus quantifier. */
8068        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
8069          free_stack(common, 1);          free_stack(common, 1);
8070        }        }
8071      else      else
8072        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8073      }      }
8074    rminlabel = LABEL();    rmin_label = LABEL();
8075      if (repeat_type != 0)
8076        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8077    }    }
8078  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
8079    {    {
# Line 7662  else if (bra == OP_BRAZERO) Line 8081  else if (bra == OP_BRAZERO)
8081    free_stack(common, 1);    free_stack(common, 1);
8082    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
8083    }    }
8084    else if (repeat_type == OP_EXACT)
8085      {
8086      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8087      exact_label = LABEL();
8088      }
8089    
8090  if (offset != 0)  if (offset != 0)
8091    {    {
# Line 7781  if (has_alternatives) Line 8205  if (has_alternatives)
8205      current->top = NULL;      current->top = NULL;
8206      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8207      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8208        /* Conditional blocks always have an additional alternative, even if it is empty. */
8209      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8210        {        {
8211        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8212        cc += GET(cc, 1);        cc += GET(cc, 1);
8213        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8214          {          {
8215          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8216            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8217              if (private_data_ptr != 0)
8218                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8219              else
8220                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8221              }
8222          else          else
8223            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(needs_control_head ? 1 : 0));
8224          }          }
8225        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8226        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7800  if (has_alternatives) Line 8230  if (has_alternatives)
8230      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8231      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8232      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8233        {        match_once_common(common, ket, CURRENT_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head);
       if (CURRENT_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  
         {  
         OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (CURRENT_AS(bracket_backtrack)->u.framesize + 2) * 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));  
           }  
         }  
       }  
8234    
8235      stacksize = 0;      stacksize = 0;
8236        if (repeat_type == OP_MINUPTO)
8237          {
8238          /* We need to preserve the counter. TMP2 will be used below. */
8239          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
8240          stacksize++;
8241          }
8242      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8243        stacksize++;        stacksize++;
8244      if (offset != 0)      if (offset != 0)
# Line 7837  if (has_alternatives) Line 8251  if (has_alternatives)
8251      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8252        stacksize++;        stacksize++;
8253    
8254      if (stacksize > 0) {      if (stacksize > 0)
8255        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        allocate_stack(common, stacksize);
         allocate_stack(common, stacksize);  
       else  
         {  
         /* We know we have place at least for one item on the top of the stack. */  
         SLJIT_ASSERT(stacksize == 1);  
         OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));  
         }  
     }  
8256    
8257      stacksize = 0;      stacksize = 0;
8258        if (repeat_type == OP_MINUPTO)
8259          {
8260          /* TMP2 was set above. */
8261          OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
8262          stacksize++;
8263          }
8264    
8265      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8266        {        {
8267        if (ket != OP_KET)        if (ket != OP_KET)
# Line 7859  if (has_alternatives) Line 8272  if (has_alternatives)
8272        }        }
8273    
8274      if (offset != 0)      if (offset != 0)
8275        {        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
       if (common->capture_last_ptr != 0)  
         {  
         OP1(SLJIT_MOV, TMP1, 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), TMP1, 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;  
         }  
       }  
8276    
8277      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8278        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
# Line 7951  else if (opcode == OP_SBRA || opcode == Line 8345  else if (opcode == OP_SBRA || opcode ==
8345  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8346    {    {
8347    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8348      stacksize = needs_control_head ? 1 : 0;
8349    
8350    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8351      {      {
8352      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8353      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize += CURRENT_AS(bracket_backtrack)->u.framesize + ((ket != OP_KET || *cc == OP_ALT) ? 2 : 1);
     free_stack(common, CURRENT_AS(bracket_backtrack)->u.framesize + stacksize);  
8354      }      }
8355    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8356      {      {
8357      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8358      free_stack(common, 1);      stacksize++;
8359      }      }
8360      free_stack(common, stacksize);
8361    
8362    JUMPHERE(once);    JUMPHERE(once);
8363    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7976  else if (opcode == OP_ONCE) Line 8372  else if (opcode == OP_ONCE)
8372      }      }
8373    }    }
8374    
8375  if (ket == OP_KETRMAX)  if (repeat_type == OP_EXACT)
8376      {
8377      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8378      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8379      CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
8380      }
8381    else if (ket == OP_KETRMAX)
8382    {    {
8383    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8384    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
8385      free_stack(common, 1);      free_stack(common, 1);
8386    
8387    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8388    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
8389      {      {
# Line 7999  else if (ket == OP_KETRMIN) Line 8402  else if (ket == OP_KETRMIN)
8402    affect badly the free_stack(2) above. */    affect badly the free_stack(2) above. */
8403    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
8404      free_stack(common, 1);      free_stack(common, 1);
8405    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
8406    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
8407      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
8408    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
# Line 8013  else if (bra == OP_BRAZERO) Line 8416  else if (bra == OP_BRAZERO)
8416    }    }
8417  }  }
8418    
8419  static void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_bracketpos_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8420  {  {
8421  DEFINE_COMPILER;  DEFINE_COMPILER;
8422  int offset;  int offset;
# Line 8052  if (current->topbacktracks) Line 8455  if (current->topbacktracks)
8455  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(bracketpos_backtrack)->private_data_ptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(bracketpos_backtrack)->framesize * sizeof(sljit_sw));
8456  }  }
8457    
8458  static void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static SLJIT_INLINE void compile_braminzero_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8459  {  {
8460  assert_backtrack backtrack;  assert_backtrack backtrack;
8461    
# Line 8076  else Line 8479  else
8479  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8480  }  }
8481    
8482    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8483    {
8484    DEFINE_COMPILER;
8485    pcre_uchar opcode = *current->cc;
8486    struct sljit_label *loop;
8487    struct sljit_jump *jump;
8488    
8489    if (opcode == OP_THEN || opcode == OP_THEN_ARG)
8490      {
8491      if (common->then_trap != NULL)
8492        {
8493        SLJIT_ASSERT(common->control_head_ptr != 0);
8494    
8495        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8496        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8497        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8498        jump = JUMP(SLJIT_JUMP);
8499    
8500        loop = LABEL();
8501        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8502        JUMPHERE(jump);
8503        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8504        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8505        add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8506        return;
8507        }
8508      else if (common->positive_assert)
8509        {
8510        add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
8511        return;
8512        }
8513      }
8514    
8515    if (common->local_exit)
8516      {
8517      if (common->quit_label == NULL)
8518        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8519      else
8520        JUMPTO(SLJIT_JUMP, common->quit_label);
8521      return;
8522      }
8523    
8524    if (opcode == OP_SKIP_ARG)
8525      {
8526      SLJIT_ASSERT(common->control_head_ptr != 0);
8527      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8528      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8529      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8530      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8531      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8532    
8533      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8534      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8535      return;
8536      }
8537    
8538    if (opcode == OP_SKIP)
8539      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8540    else
8541      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8542    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8543    }
8544    
8545    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8546    {
8547    DEFINE_COMPILER;
8548    struct sljit_jump *jump;
8549    int size;
8550    
8551    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8552      {
8553      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8554      return;
8555      }
8556    
8557    size = CURRENT_AS(then_trap_backtrack)->framesize;
8558    size = 3 + (size < 0 ? 0 : size);
8559    
8560    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8561    free_stack(common, size);
8562    jump = JUMP(SLJIT_JUMP);
8563    
8564    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8565    /* STACK_TOP is set by THEN. */
8566    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8567      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8568    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8569    free_stack(common, 3);
8570    
8571    JUMPHERE(jump);
8572    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8573    }
8574    
8575  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8576  {  {
8577  DEFINE_COMPILER;  DEFINE_COMPILER;
8578    then_trap_backtrack *save_then_trap = common->then_trap;
8579    
8580  while (current)  while (current)
8581    {    {
# Line 8212  while (current) Line 8709  while (current)
8709      break;      break;
8710    
8711      case OP_MARK:      case OP_MARK:
8712      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0));
8713      free_stack(common, 1);      if (common->has_skip_arg)
8714          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8715        free_stack(common, common->has_skip_arg ? 5 : 1);
8716      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
8717        if (common->has_skip_arg)
8718          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8719      break;      break;
8720    
8721        case OP_THEN:
8722        case OP_THEN_ARG:
8723      case OP_PRUNE:      case OP_PRUNE:
8724      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8725      case OP_SKIP:      case OP_SKIP:
8726      if (!common->local_exit)      case OP_SKIP_ARG:
8727        {      compile_control_verb_backtrackingpath(common, current);
       SLJIT_ASSERT(common->control_head_ptr != 0);  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);  
       sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));  
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
   
       OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);  
       add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));  
   
       OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  
       }  
   
     /* Commit or in recurse or accept. */  
     if (common->quit_label == NULL)  
       add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));  
     else  
       JUMPTO(SLJIT_JUMP, common->quit_label);  
8728      break;      break;
8729    
8730      case OP_COMMIT:      case OP_COMMIT:
# Line 8257  while (current) Line 8743  while (current)
8743      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8744      break;      break;
8745    
8746        case OP_THEN_TRAP:
8747        /* A virtual opcode for then traps. */
8748        compile_then_trap_backtrackingpath(common, current);
8749        break;
8750    
8751      default:      default:
8752      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8753      break;      break;
8754      }      }
8755    current = current->prev;    current = current->prev;
8756    }    }
8757    common->then_trap = save_then_trap;
8758  }  }
8759    
8760  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8271  DEFINE_COMPILER; Line 8763  DEFINE_COMPILER;
8763  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8764  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
8765  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8766  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8767  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8768    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8769  int alternativesize;  int alternativesize;
8770  BOOL needs_frame;  BOOL needs_frame;
8771  backtrack_common altbacktrack;  backtrack_common altbacktrack;
8772  struct sljit_jump *jump;  struct sljit_jump *jump;
8773    
8774    /* Recurse captures then. */
8775    common->then_trap = NULL;
8776    
8777  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);  SLJIT_ASSERT(*cc == OP_BRA || *cc == OP_CBRA || *cc == OP_CBRAPOS || *cc == OP_SCBRA || *cc == OP_SCBRAPOS);
8778  needs_frame = framesize >= 0;  needs_frame = framesize >= 0;
8779  if (!needs_frame)  if (!needs_frame)
# Line 8291  set_jumps(common->currententry->calls, c Line 8787  set_jumps(common->currententry->calls, c
8787  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8788  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8789  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(private_data_size + framesize + alternativesize - 1), TMP2, 0);
8790  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, TRUE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8791  if (common->control_head_ptr != 0)  if (needs_control_head)
8792    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);
8793  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8794  if (needs_frame)  if (needs_frame)
8795    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8796    
8797  if (alternativesize > 0)  if (alternativesize > 0)
8798    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 8366  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1); Line 8862  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8862  JUMPHERE(jump);  JUMPHERE(jump);
8863  if (common->quit != NULL)  if (common->quit != NULL)
8864    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
8865  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8866  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8867  if (common->control_head_ptr != 0)  if (needs_control_head)
8868    {    {
8869    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8870    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
# Line 8476  common->use_ucp = (re->options & PCRE_UC Line 8972  common->use_ucp = (re->options & PCRE_UC
8972  ccend = bracketend(rootbacktrack.cc);  ccend = bracketend(rootbacktrack.cc);
8973    
8974  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
8975  common->ovector_start = CALL_LIMIT + sizeof(sljit_sw);  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
8976  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8977  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8978    return;    return;
# Line 8491  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA Line 8987  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA
8987  common->capture_last_ptr = common->ovector_start;  common->capture_last_ptr = common->ovector_start;
8988  common->ovector_start += sizeof(sljit_sw);  common->ovector_start += sizeof(sljit_sw);
8989  #endif  #endif
8990  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  if (!check_opcode_types(common, rootbacktrack.cc, ccend))
 if (private_data_size < 0)  
8991    {    {
8992    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8993    return;    return;
# Line 8554  if (common->capture_last_ptr != 0) Line 9049  if (common->capture_last_ptr != 0)
9049    
9050  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
9051  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
9052  private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);  
9053  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));
9054    if (!common->private_data_ptrs)
9055    {    {
9056    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9057    return;    return;
9058    }    }
9059  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
9060  if (!common->private_data_ptrs)  
9061    private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
9062    set_private_data_ptrs(common, &private_data_size, ccend);
9063    if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
9064    {    {
9065      SLJIT_FREE(common->private_data_ptrs);
9066    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9067    return;    return;
9068    }    }
9069  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  
9070  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  if (common->has_then)
9071      {
9072      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
9073      if (!common->then_offsets)
9074        {
9075        SLJIT_FREE(common->optimized_cbracket);
9076        SLJIT_FREE(common->private_data_ptrs);
9077        return;
9078        }
9079      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
9080      set_then_offsets(common, rootbacktrack.cc, NULL);
9081      }
9082    
9083  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
9084  if (!compiler)  if (!compiler)
9085    {    {
9086    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9087    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9088      if (common->has_then)
9089        SLJIT_FREE(common->then_offsets);
9090    return;    return;
9091    }    }
9092  common->compiler = compiler;  common->compiler = compiler;
# Line 8591  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 9104  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
9104  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9105  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
9106  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
9107  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit));  OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
9108  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
9109  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
9110  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, TMP1, 0);
9111    
9112  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9113    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
# Line 8636  if (common->req_char_ptr != 0) Line 9149  if (common->req_char_ptr != 0)
9149  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
9150  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
9151  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9152  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH);
9153  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9154    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
9155    
# Line 8665  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9178  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9178    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9179    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9180    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9181      if (common->has_then)
9182        SLJIT_FREE(common->then_offsets);
9183    return;    return;
9184    }    }
9185    
# Line 8700  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9215  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9215    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9216    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9217    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9218      if (common->has_then)
9219        SLJIT_FREE(common->then_offsets);
9220    return;    return;
9221    }    }
9222    
# Line 8767  while (common->currententry != NULL) Line 9284  while (common->currententry != NULL)
9284      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9285      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9286      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9287        if (common->has_then)
9288          SLJIT_FREE(common->then_offsets);
9289      return;      return;
9290      }      }
9291    flush_stubs(common);    flush_stubs(common);
# Line 8875  if (common->getucd != NULL) Line 9394  if (common->getucd != NULL)
9394    
9395  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9396  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9397    if (common->has_then)
9398      SLJIT_FREE(common->then_offsets);
9399    
9400  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9401  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9402  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8905  else Line 9427  else
9427      }      }
9428    memset(functions, 0, sizeof(executable_functions));    memset(functions, 0, sizeof(executable_functions));
9429    functions->top_bracket = (re->top_bracket + 1) * 2;    functions->top_bracket = (re->top_bracket + 1) * 2;
9430      functions->limit_match = (re->flags & PCRE_MLSET) != 0 ? re->limit_match : 0;
9431    extra->executable_jit = functions;    extra->executable_jit = functions;
9432    extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;    extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
9433    }    }
# Line 8959  arguments.begin = subject; Line 9482  arguments.begin = subject;
9482  arguments.end = subject + length;  arguments.end = subject + length;
9483  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
9484  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
9485  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
9486    if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
9487      arguments.limit_match = functions->limit_match;
9488  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
9489  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
9490  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
# Line 9050  arguments.begin = subject_ptr; Line 9575  arguments.begin = subject_ptr;
9575  arguments.end = subject_ptr + length;  arguments.end = subject_ptr + length;
9576  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
9577  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
9578  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.limit_match = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : (pcre_uint32)(extra_data->match_limit);
9579    if (functions->limit_match != 0 && functions->limit_match < arguments.limit_match)
9580      arguments.limit_match = functions->limit_match;
9581  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
9582  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
9583  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;

Legend:
Removed from v.1275  
changed lines
  Added in v.1316

  ViewVC Help
Powered by ViewVC 1.1.5