/[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 1272 by zherczeg, Thu Mar 7 11:30:01 2013 UTC revision 1308 by zherczeg, Tue Apr 2 06:58:55 2013 UTC
# Line 71  system files. */ Line 71  system files. */
71     2 - Enable capture_last_ptr (includes option 1). */     2 - Enable capture_last_ptr (includes option 1). */
72  /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */  /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
78  Fast, but limited size. */  Fast, but limited size. */
79  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 193  typedef struct stub_list { Line 196  typedef struct stub_list {
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199  enum frame_types { no_frame = -1, no_stack = -2 };  enum frame_types {
200      no_frame = -1,
201      no_stack = -2
202    };
203    
204    enum control_types {
205      type_mark = 0,
206      type_then_trap = 1
207    };
208    
209  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
210    
# Line 215  typedef struct backtrack_common { Line 226  typedef struct backtrack_common {
226  typedef struct assert_backtrack {  typedef struct assert_backtrack {
227    backtrack_common common;    backtrack_common common;
228    jump_list *condfailed;    jump_list *condfailed;
229    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
230    int framesize;    int framesize;
231    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
232    int private_data_ptr;    int private_data_ptr;
# Line 236  typedef struct bracket_backtrack { Line 247  typedef struct bracket_backtrack {
247      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
248      jump_list *condfailed;      jump_list *condfailed;
249      assert_backtrack *assert;      assert_backtrack *assert;
250      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
251      int framesize;      int framesize;
252    } u;    } u;
253    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 271  typedef struct recurse_entry { Line 282  typedef struct recurse_entry {
282    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
283    jump_list *calls;    jump_list *calls;
284    /* Points to the starting opcode. */    /* Points to the starting opcode. */
285    int start;    sljit_sw start;
286  } recurse_entry;  } recurse_entry;
287    
288  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
# Line 279  typedef struct recurse_backtrack { Line 290  typedef struct recurse_backtrack {
290    BOOL inlined_pattern;    BOOL inlined_pattern;
291  } recurse_backtrack;  } recurse_backtrack;
292    
293    #define OP_THEN_TRAP OP_TABLE_LENGTH
294    
295    typedef struct then_trap_backtrack {
296      backtrack_common common;
297      /* If then_trap is not NULL, this structure contains the real
298      then_trap for the backtracking path. */
299      struct then_trap_backtrack *then_trap;
300      /* Points to the starting opcode. */
301      sljit_sw start;
302      /* Exit point for the then opcodes of this alternative. */
303      jump_list *quit;
304      /* Frame size of the current alternative. */
305      int framesize;
306    } then_trap_backtrack;
307    
308  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
309    
310  typedef struct compiler_common {  typedef struct compiler_common {
# Line 287  typedef struct compiler_common { Line 313  typedef struct compiler_common {
313    /* First byte code. */    /* First byte code. */
314    pcre_uchar *start;    pcre_uchar *start;
315    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
316    int *private_data_ptrs;    sljit_si *private_data_ptrs;
317    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
318    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
319      /* Tells whether the starting offset is a target of then. */
320      pcre_uint8 *then_offsets;
321      /* Current position where a THEN must jump. */
322      then_trap_backtrack *then_trap;
323    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
324    int cbra_ptr;    int cbra_ptr;
325    /* Output vector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
# Line 306  typedef struct compiler_common { Line 336  typedef struct compiler_common {
336    int first_line_end;    int first_line_end;
337    /* Points to the marked string. */    /* Points to the marked string. */
338    int mark_ptr;    int mark_ptr;
339      /* Recursive control verb management chain. */
340      int control_head_ptr;
341    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
342    int capture_last_ptr;    int capture_last_ptr;
343    /* Points to the starting position of the current match. */    /* Points to the starting position of the current match. */
# Line 316  typedef struct compiler_common { Line 348  typedef struct compiler_common {
348    sljit_sw lcc;    sljit_sw lcc;
349    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
350    int mode;    int mode;
351    /* \K is in the pattern. */    /* \K is found in the pattern. */
352    BOOL has_set_som;    BOOL has_set_som;
353      /* (*SKIP:arg) is found in the pattern. */
354      BOOL has_skip_arg;
355      /* (*THEN) is found in the pattern. */
356      BOOL has_then;
357    /* Needs to know the start position anytime. */    /* Needs to know the start position anytime. */
358    BOOL needs_start_ptr;    BOOL needs_start_ptr;
359    /* Currently in compile_recurse. */    /* Currently in recurse or negative assert. */
360    BOOL in_recurse;    BOOL local_exit;
361      /* Currently in a positive assert. */
362      BOOL positive_assert;
363    /* Newline control. */    /* Newline control. */
364    int nltype;    int nltype;
365    int newline;    int newline;
# Line 346  typedef struct compiler_common { Line 384  typedef struct compiler_common {
384    recurse_entry *currententry;    recurse_entry *currententry;
385    jump_list *partialmatch;    jump_list *partialmatch;
386    jump_list *quit;    jump_list *quit;
387      jump_list *positive_assert_quit;
388    jump_list *forced_quit;    jump_list *forced_quit;
389    jump_list *accept;    jump_list *accept;
390    jump_list *calllimit;    jump_list *calllimit;
# Line 495  return cc; Line 534  return cc;
534    
535  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
536   next_opcode   next_opcode
537   get_private_data_length   check_opcode_types
538   set_private_data_ptrs   set_private_data_ptrs
539   get_framesize   get_framesize
540   init_frame   init_frame
541   get_private_data_length_for_copy   get_private_data_copy_length
542   copy_private_data   copy_private_data
543   compile_matchingpath   compile_matchingpath
544   compile_backtrackingpath   compile_backtrackingpath
# Line 582  switch(*cc) Line 621  switch(*cc)
621    case OP_BRAMINZERO:    case OP_BRAMINZERO:
622    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
623    case OP_PRUNE:    case OP_PRUNE:
624      case OP_SKIP:
625      case OP_THEN:
626    case OP_COMMIT:    case OP_COMMIT:
627    case OP_FAIL:    case OP_FAIL:
628    case OP_ACCEPT:    case OP_ACCEPT:
# Line 681  switch(*cc) Line 722  switch(*cc)
722    
723    case OP_MARK:    case OP_MARK:
724    case OP_PRUNE_ARG:    case OP_PRUNE_ARG:
725      case OP_SKIP_ARG:
726      case OP_THEN_ARG:
727    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
728    
729    default:    default:
730      /* All opcodes are supported now! */
731      SLJIT_ASSERT_STOP();
732    return NULL;    return NULL;
733    }    }
734  }  }
735    
736  #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)  
737  {  {
 int private_data_length = 0;  
 pcre_uchar *alternative;  
738  pcre_uchar *name;  pcre_uchar *name;
739  pcre_uchar *end = NULL;  pcre_uchar *name2;
740  int space, size, i;  int i, cbra_index;
 pcre_uint32 bracketlen;  
741    
742  /* 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. */
743  while (cc < ccend)  while (cc < ccend)
744    {    {
   space = 0;  
   size = 0;  
   bracketlen = 0;  
745    switch(*cc)    switch(*cc)
746      {      {
747      case OP_SET_SOM:      case OP_SET_SOM:
# Line 793  while (cc < ccend) Line 755  while (cc < ccend)
755      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
756      break;      break;
757    
     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;  
   
758      case OP_CBRAPOS:      case OP_CBRAPOS:
759      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     private_data_length += sizeof(sljit_sw);  
760      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
761      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
762      break;      break;
763    
764      case OP_COND:      case OP_COND:
# Line 818  while (cc < ccend) Line 766  while (cc < ccend)
766      /* Only AUTO_CALLOUT can insert this opcode. We do      /* Only AUTO_CALLOUT can insert this opcode. We do
767         not intend to support this case. */         not intend to support this case. */
768      if (cc[1 + LINK_SIZE] == OP_CALLOUT)      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
769        return -1;        return FALSE;
770        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;  
771      break;      break;
772    
773      case OP_CREF:      case OP_CREF:
# Line 839  while (cc < ccend) Line 777  while (cc < ccend)
777      break;      break;
778    
779      case OP_NCREF:      case OP_NCREF:
780      bracketlen = GET2(cc, 1);      cbra_index = GET2(cc, 1);
781      name = (pcre_uchar *)common->name_table;      name = (pcre_uchar *)common->name_table;
782      alternative = name;      name2 = name;
783      for (i = 0; i < common->name_count; i++)      for (i = 0; i < common->name_count; i++)
784        {        {
785        if (GET2(name, 0) == bracketlen) break;        if (GET2(name, 0) == cbra_index) break;
786        name += common->name_entry_size;        name += common->name_entry_size;
787        }        }
788      SLJIT_ASSERT(i != common->name_count);      SLJIT_ASSERT(i != common->name_count);
789    
790      for (i = 0; i < common->name_count; i++)      for (i = 0; i < common->name_count; i++)
791        {        {
792        if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)        if (STRCMP_UC_UC(name2 + IMM2_SIZE, name + IMM2_SIZE) == 0)
793          common->optimized_cbracket[GET2(alternative, 0)] = 0;          common->optimized_cbracket[GET2(name2, 0)] = 0;
794        alternative += common->name_entry_size;        name2 += common->name_entry_size;
795        }        }
     bracketlen = 0;  
796      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
797      break;      break;
798    
     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  
   
799      case OP_RECURSE:      case OP_RECURSE:
800      /* Set its value only once. */      /* Set its value only once. */
801      if (common->recursive_head_ptr == 0)      if (common->recursive_head_ptr == 0)
# Line 932  while (cc < ccend) Line 815  while (cc < ccend)
815      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
816      break;      break;
817    
818        case OP_THEN_ARG:
819        common->has_then = TRUE;
820        common->control_head_ptr = 1;
821        /* Fall through. */
822    
823      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
824      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
825      /* Fall through. */      /* Fall through. */
# Line 945  while (cc < ccend) Line 833  while (cc < ccend)
833      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
834      break;      break;
835    
836        case OP_THEN:
837        common->has_then = TRUE;
838        common->control_head_ptr = 1;
839        /* Fall through. */
840    
841      case OP_PRUNE:      case OP_PRUNE:
842        case OP_SKIP:
843      common->needs_start_ptr = TRUE;      common->needs_start_ptr = TRUE;
844      cc += 1;      cc += 1;
845      break;      break;
846    
847        case OP_SKIP_ARG:
848        common->control_head_ptr = 1;
849        common->has_skip_arg = TRUE;
850        cc += 1 + 2 + cc[1];
851        break;
852    
853      default:      default:
854      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
855      if (cc == NULL)      if (cc == NULL)
856        return -1;        return FALSE;
857      break;      break;
858      }      }
859      }
860    return TRUE;
861    }
862    
863    if (space > 0 && cc >= end)  static int get_class_iterator_size(pcre_uchar *cc)
864      private_data_length += sizeof(sljit_sw) * space;  {
865    switch(*cc)
866      {
867      case OP_CRSTAR:
868      case OP_CRPLUS:
869      return 2;
870    
871    if (size != 0)    case OP_CRMINSTAR:
872      case OP_CRMINPLUS:
873      case OP_CRQUERY:
874      case OP_CRMINQUERY:
875      return 1;
876    
877      case OP_CRRANGE:
878      case OP_CRMINRANGE:
879      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
880        return 0;
881      return 2;
882    
883      default:
884      return 0;
885      }
886    }
887    
888    static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
889    {
890    pcre_uchar *end = bracketend(begin);
891    pcre_uchar *next;
892    pcre_uchar *next_end;
893    pcre_uchar *max_end;
894    pcre_uchar type;
895    sljit_uw length = end - begin;
896    int min, max, i;
897    
898    /* Detect fixed iterations first. */
899    if (end[-(1 + LINK_SIZE)] != OP_KET)
900      return FALSE;
901    
902    /* Already detected repeat. */
903    if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
904      return TRUE;
905    
906    next = end;
907    min = 1;
908    while (1)
909      {
910      if (*next != *begin)
911        break;
912      next_end = bracketend(next);
913      if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
914        break;
915      next = next_end;
916      min++;
917      }
918    
919    if (min == 2)
920      return FALSE;
921    
922    max = 0;
923    max_end = next;
924    if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
925      {
926      type = *next;
927      while (1)
928      {      {
929      if (size < 0)      if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
930        {        break;
931        cc += -size;      next_end = bracketend(next + 2 + LINK_SIZE);
932  #ifdef SUPPORT_UTF      if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
933        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        break;
934  #endif      next = next_end;
935        }      max++;
     else  
       cc += size;  
936      }      }
937    
938    if (bracketlen != 0)    if (next[0] == type && next[1] == *begin && max >= 1)
939      {      {
940      if (cc >= end)      next_end = bracketend(next + 1);
941        if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
942        {        {
943        end = bracketend(cc);        for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
944        if (end[-1 - LINK_SIZE] == OP_KET)          if (*next_end != OP_KET)
945          end = NULL;            break;
946    
947          if (i == max)
948            {
949            common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
950            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
951            /* +2 the original and the last. */
952            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
953            if (min == 1)
954              return TRUE;
955            min--;
956            max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
957            }
958        }        }
     cc += bracketlen;  
959      }      }
960    }    }
961  return private_data_length;  
962    if (min >= 3)
963      {
964      common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
965      common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
966      common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
967      return TRUE;
968      }
969    
970    return FALSE;
971  }  }
972    
973  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
974        case OP_MINSTAR: \
975        case OP_MINPLUS: \
976        case OP_QUERY: \
977        case OP_MINQUERY: \
978        case OP_MINSTARI: \
979        case OP_MINPLUSI: \
980        case OP_QUERYI: \
981        case OP_MINQUERYI: \
982        case OP_NOTMINSTAR: \
983        case OP_NOTMINPLUS: \
984        case OP_NOTQUERY: \
985        case OP_NOTMINQUERY: \
986        case OP_NOTMINSTARI: \
987        case OP_NOTMINPLUSI: \
988        case OP_NOTQUERYI: \
989        case OP_NOTMINQUERYI:
990    
991    #define CASE_ITERATOR_PRIVATE_DATA_2A \
992        case OP_STAR: \
993        case OP_PLUS: \
994        case OP_STARI: \
995        case OP_PLUSI: \
996        case OP_NOTSTAR: \
997        case OP_NOTPLUS: \
998        case OP_NOTSTARI: \
999        case OP_NOTPLUSI:
1000    
1001    #define CASE_ITERATOR_PRIVATE_DATA_2B \
1002        case OP_UPTO: \
1003        case OP_MINUPTO: \
1004        case OP_UPTOI: \
1005        case OP_MINUPTOI: \
1006        case OP_NOTUPTO: \
1007        case OP_NOTMINUPTO: \
1008        case OP_NOTUPTOI: \
1009        case OP_NOTMINUPTOI:
1010    
1011    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1012        case OP_TYPEMINSTAR: \
1013        case OP_TYPEMINPLUS: \
1014        case OP_TYPEQUERY: \
1015        case OP_TYPEMINQUERY:
1016    
1017    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1018        case OP_TYPESTAR: \
1019        case OP_TYPEPLUS:
1020    
1021    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1022        case OP_TYPEUPTO: \
1023        case OP_TYPEMINUPTO:
1024    
1025    static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1026  {  {
1027  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1028  pcre_uchar *alternative;  pcre_uchar *alternative;
1029  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
1030    int private_data_ptr = *private_data_start;
1031  int space, size, bracketlen;  int space, size, bracketlen;
1032    
1033  while (cc < ccend)  while (cc < ccend)
# Line 999  while (cc < ccend) Line 1035  while (cc < ccend)
1035    space = 0;    space = 0;
1036    size = 0;    size = 0;
1037    bracketlen = 0;    bracketlen = 0;
1038      if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1039        return;
1040    
1041      if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
1042        if (detect_repeat(common, cc))
1043          {
1044          /* These brackets are converted to repeats, so no global
1045          based single character repeat is allowed. */
1046          if (cc >= end)
1047            end = bracketend(cc);
1048          }
1049    
1050    switch(*cc)    switch(*cc)
1051      {      {
1052        case OP_KET:
1053        if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1054          {
1055          common->private_data_ptrs[cc - common->start] = private_data_ptr;
1056          private_data_ptr += sizeof(sljit_sw);
1057          cc += common->private_data_ptrs[cc + 1 - common->start];
1058          }
1059        cc += 1 + LINK_SIZE;
1060        break;
1061    
1062      case OP_ASSERT:      case OP_ASSERT:
1063      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1064      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1094  while (cc < ccend) Line 1152  while (cc < ccend)
1152      break;      break;
1153      }      }
1154    
1155      /* Character iterators, which are not inside a repeated bracket,
1156         gets a private slot instead of allocating it on the stack. */
1157    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1158      {      {
1159      common->private_data_ptrs[cc - common->start] = private_data_ptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
# Line 1124  while (cc < ccend) Line 1184  while (cc < ccend)
1184      cc += bracketlen;      cc += bracketlen;
1185      }      }
1186    }    }
1187    *private_data_start = private_data_ptr;
1188  }  }
1189    
1190  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1191  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)
1192  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1193  int length = 0;  int length = 0;
1194  int possessive = 0;  int possessive = 0;
1195  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1138  BOOL setmark_found = recursive; Line 1198  BOOL setmark_found = recursive;
1198  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1199  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1200    
1201  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1202    SLJIT_ASSERT(common->control_head_ptr != 0);
1203    *needs_control_head = TRUE;
1204    #else
1205    *needs_control_head = FALSE;
1206    #endif
1207    
1208    if (ccend == NULL)
1209    {    {
1210    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1211    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1212    capture_last_found = TRUE;      {
1213        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1214        /* This is correct regardless of common->capture_last_ptr. */
1215        capture_last_found = TRUE;
1216        }
1217      cc = next_opcode(common, cc);
1218    }    }
1219    
 cc = next_opcode(common, cc);  
1220  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1221  while (cc < ccend)  while (cc < ccend)
1222    switch(*cc)    switch(*cc)
# Line 1163  while (cc < ccend) Line 1234  while (cc < ccend)
1234    
1235      case OP_MARK:      case OP_MARK:
1236      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1237        case OP_THEN_ARG:
1238      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1239      stack_restore = TRUE;      stack_restore = TRUE;
1240      if (!setmark_found)      if (!setmark_found)
# Line 1170  while (cc < ccend) Line 1242  while (cc < ccend)
1242        length += 2;        length += 2;
1243        setmark_found = TRUE;        setmark_found = TRUE;
1244        }        }
1245        if (common->control_head_ptr != 0)
1246          *needs_control_head = TRUE;
1247      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1248      break;      break;
1249    
# Line 1289  if (length > 0) Line 1363  if (length > 0)
1363  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1364  }  }
1365    
1366  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)
1367  {  {
1368  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1369  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1370  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1371  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
# Line 1304  SLJIT_UNUSED_ARG(stacktop); Line 1377  SLJIT_UNUSED_ARG(stacktop);
1377  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1378    
1379  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1380  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1381    cc = next_opcode(common, cc);    {
1382      ccend = bracketend(cc) - (1 + LINK_SIZE);
1383      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1384        cc = next_opcode(common, cc);
1385      }
1386    
1387  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1388  while (cc < ccend)  while (cc < ccend)
1389    switch(*cc)    switch(*cc)
# Line 1326  while (cc < ccend) Line 1404  while (cc < ccend)
1404    
1405      case OP_MARK:      case OP_MARK:
1406      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
1407        case OP_THEN_ARG:
1408      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1409      if (!setmark_found)      if (!setmark_found)
1410        {        {
# Line 1406  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1485  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1485  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1486  }  }
1487    
1488  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)
1489  {  {
1490  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1491  int size;  int size;
1492  pcre_uchar *alternative;  pcre_uchar *alternative;
1493  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1417  while (cc < ccend) Line 1496  while (cc < ccend)
1496    size = 0;    size = 0;
1497    switch(*cc)    switch(*cc)
1498      {      {
1499        case OP_KET:
1500        if (PRIVATE_DATA(cc) != 0)
1501          private_data_length++;
1502        cc += 1 + LINK_SIZE;
1503        break;
1504    
1505      case OP_ASSERT:      case OP_ASSERT:
1506      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1507      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1521  return private_data_length; Line 1606  return private_data_length;
1606  }  }
1607    
1608  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,
1609    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1610  {  {
1611  DEFINE_COMPILER;  DEFINE_COMPILER;
1612  int srcw[2];  int srcw[2];
# Line 1542  stacktop = STACK(stacktop - 1); Line 1627  stacktop = STACK(stacktop - 1);
1627    
1628  if (!save)  if (!save)
1629    {    {
1630    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1631    if (stackptr < stacktop)    if (stackptr < stacktop)
1632      {      {
1633      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1558  if (!save) Line 1643  if (!save)
1643    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1644    }    }
1645    
1646  while (status != end)  do
1647    {    {
1648    count = 0;    count = 0;
1649    switch(status)    switch(status)
# Line 1567  while (status != end) Line 1652  while (status != end)
1652      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1653      count = 1;      count = 1;
1654      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1655        if (needs_control_head)
1656          {
1657          SLJIT_ASSERT(common->control_head_ptr != 0);
1658          count = 2;
1659          srcw[1] = common->control_head_ptr;
1660          }
1661      status = loop;      status = loop;
1662      break;      break;
1663    
# Line 1579  while (status != end) Line 1670  while (status != end)
1670    
1671      switch(*cc)      switch(*cc)
1672        {        {
1673          case OP_KET:
1674          if (PRIVATE_DATA(cc) != 0)
1675            {
1676            count = 1;
1677            srcw[0] = PRIVATE_DATA(cc);
1678            }
1679          cc += 1 + LINK_SIZE;
1680          break;
1681    
1682        case OP_ASSERT:        case OP_ASSERT:
1683        case OP_ASSERT_NOT:        case OP_ASSERT_NOT:
1684        case OP_ASSERTBACK:        case OP_ASSERTBACK:
# Line 1791  while (status != end) Line 1891  while (status != end)
1891        }        }
1892      }      }
1893    }    }
1894    while (status != end);
1895    
1896  if (save)  if (save)
1897    {    {
# Line 1824  if (save) Line 1925  if (save)
1925  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1926  }  }
1927    
1928    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1929    {
1930    pcre_uchar *end = bracketend(cc);
1931    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1932    
1933    /* Assert captures then. */
1934    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1935      current_offset = NULL;
1936    /* Conditional block does not. */
1937    if (*cc == OP_COND || *cc == OP_SCOND)
1938      has_alternatives = FALSE;
1939    
1940    cc = next_opcode(common, cc);
1941    if (has_alternatives)
1942      current_offset = common->then_offsets + (cc - common->start);
1943    
1944    while (cc < end)
1945      {
1946      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1947        cc = set_then_offsets(common, cc, current_offset);
1948      else
1949        {
1950        if (*cc == OP_ALT && has_alternatives)
1951          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1952        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1953          *current_offset = 1;
1954        cc = next_opcode(common, cc);
1955        }
1956      }
1957    
1958    return end;
1959    }
1960    
1961  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1962  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1963  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1943  else Line 2077  else
2077    }    }
2078  }  }
2079    
2080  static void do_reset_match(compiler_common *common, int length)  static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2081  {  {
2082  DEFINE_COMPILER;  DEFINE_COMPILER;
2083  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1953  SLJIT_ASSERT(length > 1); Line 2087  SLJIT_ASSERT(length > 1);
2087  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
2088  if (length > 2)  if (length > 2)
2089    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
 OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);  
2090  if (length < 8)  if (length < 8)
2091    {    {
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));  
2092    for (i = 2; i < length; i++)    for (i = 2; i < length; i++)
2093      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2094    }    }
2095  else  else
2096    {    {
2097    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2098    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, length - 2);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));  
2099    loop = LABEL();    loop = LABEL();
2100    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2101    OP2(SLJIT_SUB | SLJIT_SET_E, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2102    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
2103    }    }
2104    
2105    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2106    if (common->mark_ptr != 0)
2107      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2108    if (common->control_head_ptr != 0)
2109      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2110    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2111    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2112  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));
2113  }  }
2114    
2115    static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2116    {
2117    while (current != NULL)
2118      {
2119      switch (current[-2])
2120        {
2121        case type_then_trap:
2122        break;
2123    
2124        case type_mark:
2125        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2126          return current[-4];
2127        break;
2128    
2129        default:
2130        SLJIT_ASSERT_STOP();
2131        break;
2132        }
2133      current = (sljit_sw*)current[-1];
2134      }
2135    return -1;
2136    }
2137    
2138  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2139  {  {
2140  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2042  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 2204  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2204  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));
2205    
2206  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);
2207  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);
2208  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2209  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);
2210  #endif  #endif
# Line 5178  DEFINE_COMPILER; Line 5340  DEFINE_COMPILER;
5340  backtrack_common *backtrack;  backtrack_common *backtrack;
5341  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5342  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5343  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5344  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5345    BOOL needs_control_head;
5346    
5347  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5348    
5349  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5350  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5351    {    {
5352    start_cc = common->start + start;    start_cc = common->start + start;
5353    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 5343  static pcre_uchar *compile_assert_matchi Line 5506  static pcre_uchar *compile_assert_matchi
5506  {  {
5507  DEFINE_COMPILER;  DEFINE_COMPILER;
5508  int framesize;  int framesize;
5509    int extrasize;
5510    BOOL needs_control_head;
5511  int private_data_ptr;  int private_data_ptr;
5512  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5513  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5352  jump_list *tmp = NULL; Line 5517  jump_list *tmp = NULL;
5517  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5518  jump_list **found;  jump_list **found;
5519  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5520    BOOL save_local_exit = common->local_exit;
5521    BOOL save_positive_assert = common->positive_assert;
5522    then_trap_backtrack *save_then_trap = common->then_trap;
5523  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5524  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5525  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5526    jump_list *save_positive_assert_quit = common->positive_assert_quit;
5527  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5528  struct sljit_jump *jump;  struct sljit_jump *jump;
5529  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5530    
5531    /* Assert captures then. */
5532    common->then_trap = NULL;
5533    
5534  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5535    {    {
5536    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5367  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5539  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5539    }    }
5540  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5541  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5542  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5543  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5544  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5545  opcode = *cc;  opcode = *cc;
# Line 5386  if (bra == OP_BRAMINZERO) Line 5558  if (bra == OP_BRAMINZERO)
5558    
5559  if (framesize < 0)  if (framesize < 0)
5560    {    {
5561    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5562    allocate_stack(common, 1);    if (framesize == no_frame)
5563        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5564      allocate_stack(common, extrasize);
5565      if (needs_control_head)
5566        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5567    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5568      if (needs_control_head)
5569        {
5570        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5571        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5572        }
5573    }    }
5574  else  else
5575    {    {
5576    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5577      allocate_stack(common, framesize + extrasize);
5578    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);
5579    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5580    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);
5581      if (needs_control_head)
5582        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5583    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5584    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5585    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5586        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5587        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5588        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5589        }
5590      else
5591        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5592      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5593    }    }
5594    
5595  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5596  common->quit_label = NULL;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5597  common->quit = NULL;    {
5598      /* Negative assert is stronger than positive assert. */
5599      common->local_exit = TRUE;
5600      common->quit_label = NULL;
5601      common->quit = NULL;
5602      common->positive_assert = FALSE;
5603      }
5604    else
5605      common->positive_assert = TRUE;
5606    common->positive_assert_quit = NULL;
5607    
5608  while (1)  while (1)
5609    {    {
5610    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5418  while (1) Line 5619  while (1)
5619    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5620    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5621      {      {
5622      common->quit_label = save_quit_label;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5623          {
5624          common->local_exit = save_local_exit;
5625          common->quit_label = save_quit_label;
5626          common->quit = save_quit;
5627          }
5628        common->positive_assert = save_positive_assert;
5629        common->then_trap = save_then_trap;
5630      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5631      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5632      common->accept = save_accept;      common->accept = save_accept;
5633      return NULL;      return NULL;
5634      }      }
# Line 5430  while (1) Line 5638  while (1)
5638    
5639    /* Reset stack. */    /* Reset stack. */
5640    if (framesize < 0)    if (framesize < 0)
5641      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5642    else {      if (framesize == no_frame)
5643          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5644        else
5645          free_stack(common, extrasize);
5646        if (needs_control_head)
5647          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5648        }
5649      else
5650        {
5651      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5652        {        {
5653        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5654        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5655          if (needs_control_head)
5656            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5657        }        }
5658      else      else
5659        {        {
5660        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);
5661          if (needs_control_head)
5662            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5663        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5664        }        }
5665    }      }
5666    
5667    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5668      {      {
5669      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5670      if (conditional)      if (conditional)
5671        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
5672      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5673        {        {
5674        if (framesize < 0)        if (framesize < 0)
5675          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5676        else        else
5677          {          {
5678          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5679          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
5680          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5681          }          }
5682        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5473  while (1) Line 5693  while (1)
5693    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5694    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5695      {      {
5696      common->quit_label = save_quit_label;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5697          {
5698          common->local_exit = save_local_exit;
5699          common->quit_label = save_quit_label;
5700          common->quit = save_quit;
5701          }
5702        common->positive_assert = save_positive_assert;
5703        common->then_trap = save_then_trap;
5704      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5705      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5706      common->accept = save_accept;      common->accept = save_accept;
5707      return NULL;      return NULL;
5708      }      }
# Line 5487  while (1) Line 5714  while (1)
5714    ccbegin = cc;    ccbegin = cc;
5715    cc += GET(cc, 1);    cc += GET(cc, 1);
5716    }    }
5717    
5718    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5719      {
5720      SLJIT_ASSERT(common->positive_assert_quit == NULL);
5721      /* Makes the check less complicated below. */
5722      common->positive_assert_quit = common->quit;
5723      }
5724    
5725  /* None of them matched. */  /* None of them matched. */
5726  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
5727    set_jumps(common->quit, LABEL());    {
5728      jump = JUMP(SLJIT_JUMP);
5729      set_jumps(common->positive_assert_quit, LABEL());
5730      SLJIT_ASSERT(framesize != no_stack);
5731      if (framesize < 0)
5732        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5733      else
5734        {
5735        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5736        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5737        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5738        }
5739      JUMPHERE(jump);
5740      }
5741    
5742    if (needs_control_head)
5743      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5744    
5745  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5746    {    {
# Line 5501  if (opcode == OP_ASSERT || opcode == OP_ Line 5752  if (opcode == OP_ASSERT || opcode == OP_
5752      {      {
5753      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5754      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5755          {
5756          if (extrasize == 2)
5757            free_stack(common, 1);
5758        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5759          }
5760      else      else
5761        free_stack(common, 1);        free_stack(common, extrasize);
5762      }      }
5763    else    else
5764      {      {
5765      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5766      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5767      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5768        {        {
5769        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5770        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5771        }        }
5772      else      else
5773        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5774      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5775      }      }
5776    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5527  if (opcode == OP_ASSERT || opcode == OP_ Line 5782  if (opcode == OP_ASSERT || opcode == OP_
5782    if (framesize < 0)    if (framesize < 0)
5783      {      {
5784      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5785      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5786      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5787      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5788          {
5789        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5790          if (extrasize == 2)
5791            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5792          }
5793      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5794        {        {
5795        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5543  if (opcode == OP_ASSERT || opcode == OP_ Line 5802  if (opcode == OP_ASSERT || opcode == OP_
5802        {        {
5803        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5804        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5805        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
5806        }        }
5807      else      else
5808        {        {
5809        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5810        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
5811        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5812        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5813            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5814            if (bra == OP_BRAMINZERO)
5815              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5816            }
5817          else
5818            {
5819            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5820            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5821            }
5822        }        }
5823      }      }
5824    
# Line 5579  else Line 5847  else
5847      {      {
5848      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5849      if (bra != OP_BRA)      if (bra != OP_BRA)
5850          {
5851          if (extrasize == 2)
5852            free_stack(common, 1);
5853        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5854          }
5855      else      else
5856        free_stack(common, 1);        free_stack(common, extrasize);
5857      }      }
5858    else    else
5859      {      {
5860      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5861      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5862      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5863      if (bra != OP_BRA)      if (bra != OP_BRA)
5864        {        {
5865        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5866        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5867        }        }
5868      else      else
5869        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5870      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5871      }      }
5872    
# Line 5614  else Line 5886  else
5886      }      }
5887    }    }
5888    
5889  common->quit_label = save_quit_label;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5890      {
5891      common->local_exit = save_local_exit;
5892      common->quit_label = save_quit_label;
5893      common->quit = save_quit;
5894      }
5895    common->positive_assert = save_positive_assert;
5896    common->then_trap = save_then_trap;
5897  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5898  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
5899  common->accept = save_accept;  common->accept = save_accept;
5900  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5901  }  }
# Line 5731  if (i < name_count) Line 6010  if (i < name_count)
6010  return condition;  return condition;
6011  }  }
6012    
6013    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)
6014    {
6015    DEFINE_COMPILER;
6016    int stacksize;
6017    
6018    if (framesize < 0)
6019      {
6020      if (framesize == no_frame)
6021        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6022      else
6023        {
6024        stacksize = needs_control_head ? 1 : 0;
6025        if (ket != OP_KET || has_alternatives)
6026          stacksize++;
6027        free_stack(common, stacksize);
6028        }
6029    
6030      if (needs_control_head)
6031        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6032    
6033      /* TMP2 which is set here used by OP_KETRMAX below. */
6034      if (ket == OP_KETRMAX)
6035        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6036      else if (ket == OP_KETRMIN)
6037        {
6038        /* Move the STR_PTR to the private_data_ptr. */
6039        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6040        }
6041      }
6042    else
6043      {
6044      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6045      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6046      if (needs_control_head)
6047        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6048    
6049      if (ket == OP_KETRMAX)
6050        {
6051        /* TMP2 which is set here used by OP_KETRMAX below. */
6052        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6053        }
6054      }
6055    if (needs_control_head)
6056      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6057    }
6058    
6059    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6060    {
6061    DEFINE_COMPILER;
6062    
6063    if (common->capture_last_ptr != 0)
6064      {
6065      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6066      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6067      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6068      stacksize++;
6069      }
6070    if (common->optimized_cbracket[offset >> 1] == 0)
6071      {
6072      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6073      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6074      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6075      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6076      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6077      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6078      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6079      stacksize += 2;
6080      }
6081    return stacksize;
6082    }
6083    
6084  /*  /*
6085    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6086    
# Line 5793  pcre_uchar opcode; Line 6143  pcre_uchar opcode;
6143  int private_data_ptr = 0;  int private_data_ptr = 0;
6144  int offset = 0;  int offset = 0;
6145  int stacksize;  int stacksize;
6146    int repeat_ptr = 0, repeat_length = 0;
6147    int repeat_type = 0, repeat_count = 0;
6148  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6149  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6150  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6151  pcre_uchar ket;  pcre_uchar ket;
6152  assert_backtrack *assert;  assert_backtrack *assert;
6153  BOOL has_alternatives;  BOOL has_alternatives;
6154    BOOL needs_control_head = FALSE;
6155  struct sljit_jump *jump;  struct sljit_jump *jump;
6156  struct sljit_jump *skip;  struct sljit_jump *skip;
6157  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmax_label = NULL;
6158  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzero = NULL;
6159    
6160  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6161    
# Line 5815  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6168  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6168    
6169  opcode = *cc;  opcode = *cc;
6170  ccbegin = cc;  ccbegin = cc;
6171  matchingpath = ccbegin + 1 + LINK_SIZE;  matchingpath = bracketend(cc) - 1 - LINK_SIZE;
6172    ket = *matchingpath;
6173    if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
6174      {
6175      repeat_ptr = PRIVATE_DATA(matchingpath);
6176      repeat_length = PRIVATE_DATA(matchingpath + 1);
6177      repeat_type = PRIVATE_DATA(matchingpath + 2);
6178      repeat_count = PRIVATE_DATA(matchingpath + 3);
6179      SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
6180      if (repeat_type == OP_UPTO)
6181        ket = OP_KETRMAX;
6182      if (repeat_type == OP_MINUPTO)
6183        ket = OP_KETRMIN;
6184      }
6185    
6186  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)
6187    {    {
6188    /* Drop this bracket_backtrack. */    /* Drop this bracket_backtrack. */
6189    parent->top = backtrack->prev;    parent->top = backtrack->prev;
6190    return bracketend(cc);    return matchingpath + 1 + LINK_SIZE + repeat_length;
6191    }    }
6192    
6193  ket = *(bracketend(cc) - 1 - LINK_SIZE);  matchingpath = ccbegin + 1 + LINK_SIZE;
6194  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
6195  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)));
6196  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 5874  else if (opcode == OP_ONCE || opcode == Line 6240  else if (opcode == OP_ONCE || opcode ==
6240    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6241    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6242    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6243      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);
6244    }    }
6245    
6246  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6247  stacksize = 0;  stacksize = 0;
6248  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6249    stacksize++;    stacksize++;
6250  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6251    stacksize++;    stacksize++;
# Line 5888  if (stacksize > 0) Line 6254  if (stacksize > 0)
6254    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6255    
6256  stacksize = 0;  stacksize = 0;
6257  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6258    {    {
6259    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6260    stacksize++;    stacksize++;
# Line 5904  if (bra == OP_BRAMINZERO) Line 6270  if (bra == OP_BRAMINZERO)
6270    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
6271      {      {
6272      free_stack(common, 1);      free_stack(common, 1);
6273      braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);      braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6274      }      }
6275    else    else
6276      {      {
# Line 5919  if (bra == OP_BRAMINZERO) Line 6285  if (bra == OP_BRAMINZERO)
6285        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6286          {          {
6287          /* 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. */
6288          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);
6289          }          }
6290        else        else
6291          {          {
6292          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
6293          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);
6294          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));
6295          }          }
6296        JUMPHERE(skip);        JUMPHERE(skip);
6297        }        }
# Line 5938  if (bra == OP_BRAMINZERO) Line 6304  if (bra == OP_BRAMINZERO)
6304      }      }
6305    }    }
6306    
6307    if (repeat_type != 0)
6308      {
6309      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
6310      if (repeat_type == OP_EXACT)
6311        rmax_label = LABEL();
6312      }
6313    
6314  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
6315    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6316    
6317  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6318    {    {
6319    rmaxlabel = LABEL();    rmax_label = LABEL();
6320    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
6321      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
6322    }    }
6323    
6324  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6325  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6326    {    {
6327      stacksize = 0;
6328      if (needs_control_head)
6329        {
6330        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6331        stacksize++;
6332        }
6333    
6334    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6335      {      {
6336      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6337      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6338        {        {
6339        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6340        allocate_stack(common, 2);        if (!needs_control_head)
6341        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));  
6342        }        }
6343      else if (ket == OP_KETRMAX || has_alternatives)      else
6344        {        {
6345        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6346        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6347        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6348            stacksize++;
6349        }        }
6350      else  
6351        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6352          allocate_stack(common, stacksize);
6353    
6354        stacksize = 0;
6355        if (needs_control_head)
6356          {
6357          stacksize++;
6358          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6359          }
6360    
6361        if (ket == OP_KETRMIN)
6362          {
6363          if (needs_control_head)
6364            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6365          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6366          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6367            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));
6368          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6369          }
6370        else if (ket == OP_KETRMAX || has_alternatives)
6371          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6372      }      }
6373    else    else
6374      {      {
6375      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6376          stacksize++;
6377    
6378        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6379        allocate_stack(common, stacksize);
6380    
6381        if (needs_control_head)
6382          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6383    
6384        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6385        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6386    
6387        stacksize = needs_control_head ? 1 : 0;
6388        if (ket != OP_KET || has_alternatives)
6389        {        {
6390        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);  
6391        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);
6392        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6393        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6394        }        }
6395      else      else
6396        {        {
       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));  
6397        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);
6398        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);  
6399        }        }
6400        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6401      }      }
6402    }    }
6403  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6127  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6533  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6533    return NULL;    return NULL;
6534    
6535  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6536    {    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));  
       }  
     }  
   }  
6537    
6538  stacksize = 0;  stacksize = 0;
6539    if (repeat_type == OP_MINUPTO)
6540      {
6541      /* We need to preserve the counter. TMP2 will be used below. */
6542      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6543      stacksize++;
6544      }
6545  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6546    stacksize++;    stacksize++;
6547  if (offset != 0)  if (offset != 0)
# Line 6169  if (stacksize > 0) Line 6558  if (stacksize > 0)
6558    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6559    
6560  stacksize = 0;  stacksize = 0;
6561    if (repeat_type == OP_MINUPTO)
6562      {
6563      /* TMP2 was set above. */
6564      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
6565      stacksize++;
6566      }
6567    
6568  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6569    {    {
6570    if (ket != OP_KET)    if (ket != OP_KET)
# Line 6178  if (ket != OP_KET || bra != OP_BRA) Line 6574  if (ket != OP_KET || bra != OP_BRA)
6574    stacksize++;    stacksize++;
6575    }    }
6576    
6577  if (offset != 0)  if (offset != 0)
6578    {    stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
6579    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;  
     }  
   }  
   
6580  if (has_alternatives)  if (has_alternatives)
6581    {    {
6582    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
# Line 6217  if (offset != 0 && common->optimized_cbr Line 6594  if (offset != 0 && common->optimized_cbr
6594    
6595  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6596    {    {
6597    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (repeat_type != 0)
6598        {
6599        if (has_alternatives)
6600          BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6601        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6602        JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
6603        /* Drop STR_PTR for greedy plus quantifier. */
6604        if (opcode != OP_ONCE)
6605          free_stack(common, 1);
6606        }
6607      else if (opcode == OP_ONCE || opcode >= OP_SBRA)
6608      {      {
6609      if (has_alternatives)      if (has_alternatives)
6610        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6611      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
6612      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
6613        {        {
6614        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);
6615        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
6616        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
6617          free_stack(common, 1);          free_stack(common, 1);
6618        }        }
6619      else      else
6620        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
6621        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
6622      }      }
6623    else    else
6624      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmax_label);
6625    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6626    }    }
6627    
6628    if (repeat_type == OP_EXACT)
6629      {
6630      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6631      JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
6632      }
6633    else if (repeat_type == OP_UPTO)
6634      {
6635      /* We need to preserve the counter. */
6636      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6637      allocate_stack(common, 1);
6638      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6639      }
6640    
6641  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6642    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
6643    
# Line 6245  if (bra == OP_BRAMINZERO) Line 6645  if (bra == OP_BRAMINZERO)
6645    {    {
6646    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
6647    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
6648    if (braminzerojump != NULL)    if (braminzero != NULL)
6649      {      {
6650      JUMPHERE(braminzerojump);      JUMPHERE(braminzero);
6651      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
6652      backtrack for the zero-length iteration. When      backtrack for the zero-length iteration. When
6653      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
# Line 6269  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6669  if ((ket != OP_KET && bra != OP_BRAMINZE
6669  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6670    cc += GET(cc, 1);    cc += GET(cc, 1);
6671  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6672  return cc;  
6673    /* Temporarily encoding the needs_control_head in framesize. */
6674    if (opcode == OP_ONCE)
6675      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6676    return cc + repeat_length;
6677  }  }
6678    
6679  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 6279  backtrack_common *backtrack; Line 6683  backtrack_common *backtrack;
6683  pcre_uchar opcode;  pcre_uchar opcode;
6684  int private_data_ptr;  int private_data_ptr;
6685  int cbraprivptr = 0;  int cbraprivptr = 0;
6686    BOOL needs_control_head;
6687  int framesize;  int framesize;
6688  int stacksize;  int stacksize;
6689  int offset = 0;  int offset = 0;
6690  BOOL zero = FALSE;  BOOL zero = FALSE;
6691  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6692  int stack;  int stack; /* Also contains the offset of control head. */
6693  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6694  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6695    
# Line 6322  switch(opcode) Line 6727  switch(opcode)
6727    break;    break;
6728    }    }
6729    
6730  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6731  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6732  if (framesize < 0)  if (framesize < 0)
6733    {    {
# Line 6335  if (framesize < 0) Line 6740  if (framesize < 0)
6740    else    else
6741      stacksize = 1;      stacksize = 1;
6742    
6743      if (needs_control_head)
6744        stacksize++;
6745    if (!zero)    if (!zero)
6746      stacksize++;      stacksize++;
6747    
# Line 6343  if (framesize < 0) Line 6750  if (framesize < 0)
6750    if (framesize == no_frame)    if (framesize == no_frame)
6751      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);
6752    
6753      stack = 0;
6754    if (offset != 0)    if (offset != 0)
6755      {      {
6756        stack = 2;
6757      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6758      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));
6759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6760      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6761        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);
6762      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6763        if (needs_control_head)
6764          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6765      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6766          {
6767        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6768          stack = 3;
6769          }
6770      }      }
6771    else    else
6772        {
6773        if (needs_control_head)
6774          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6775      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6776        stack = 1;
6777        }
6778    
6779      if (needs_control_head)
6780        stack++;
6781    if (!zero)    if (!zero)
6782      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);
6783      if (needs_control_head)
6784        {
6785        stack--;
6786        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6787        }
6788    }    }
6789  else  else
6790    {    {
6791    stacksize = framesize + 1;    stacksize = framesize + 1;
6792    if (!zero)    if (!zero)
6793      stacksize++;      stacksize++;
6794    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6795        stacksize++;
6796      if (offset == 0)
6797      stacksize++;      stacksize++;
6798    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6799    
6800    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6801    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);
6802    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6803    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);
6804      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6805    
6806    stack = 0;    stack = 0;
6807    if (!zero)    if (!zero)
6808      {      {
6809      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6810        stack = 1;
6811        }
6812      if (needs_control_head)
6813        {
6814        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6815      stack++;      stack++;
6816      }      }
6817    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6818      {      {
6819      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6820      stack++;      stack++;
6821      }      }
6822    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6823    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6824      stack -= 1 + (offset == 0);
6825    }    }
6826    
6827  if (offset != 0)  if (offset != 0)
# Line 6462  while (*cc != OP_KETRPOS) Line 6897  while (*cc != OP_KETRPOS)
6897          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6898        }        }
6899      }      }
6900    
6901      if (needs_control_head)
6902        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6903    
6904    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6905    flush_stubs(common);    flush_stubs(common);
6906    
# Line 6498  while (*cc != OP_KETRPOS) Line 6937  while (*cc != OP_KETRPOS)
6937    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6938    }    }
6939    
6940    /* We don't have to restore the control head in case of a failed match. */
6941    
6942  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6943  if (!zero)  if (!zero)
6944    {    {
# Line 6886  if (!optimized_cbracket) Line 7327  if (!optimized_cbracket)
7327  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7328  }  }
7329    
7330    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7331    {
7332    DEFINE_COMPILER;
7333    backtrack_common *backtrack;
7334    pcre_uchar opcode = *cc;
7335    pcre_uchar *ccend = cc + 1;
7336    
7337    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7338      ccend += 2 + cc[1];
7339    
7340    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7341    
7342    if (opcode == OP_SKIP)
7343      {
7344      allocate_stack(common, 1);
7345      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7346      return ccend;
7347      }
7348    
7349    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7350      {
7351      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7352      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7353      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7354      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7355      }
7356    
7357    return ccend;
7358    }
7359    
7360    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7361    
7362    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7363    {
7364    DEFINE_COMPILER;
7365    backtrack_common *backtrack;
7366    BOOL needs_control_head;
7367    int size;
7368    
7369    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7370    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7371    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7372    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7373    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7374    
7375    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7376    size = 3 + (size < 0 ? 0 : size);
7377    
7378    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7379    allocate_stack(common, size);
7380    if (size > 3)
7381      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7382    else
7383      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7384    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7385    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7386    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7387    
7388    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7389    if (size >= 0)
7390      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7391    }
7392    
7393  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)
7394  {  {
7395  DEFINE_COMPILER;  DEFINE_COMPILER;
7396  backtrack_common *backtrack;  backtrack_common *backtrack;
7397    BOOL has_then_trap = FALSE;
7398    then_trap_backtrack *save_then_trap = NULL;
7399    
7400    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7401    
7402    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7403      {
7404      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7405      has_then_trap = TRUE;
7406      save_then_trap = common->then_trap;
7407      /* Tail item on backtrack. */
7408      compile_then_trap_matchingpath(common, cc, ccend, parent);
7409      }
7410    
7411  while (cc < ccend)  while (cc < ccend)
7412    {    {
# Line 7106  while (cc < ccend) Line 7623  while (cc < ccend)
7623      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7624      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7625      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);
7626      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
     OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 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);  
     cc += 1 + 2 + cc[1];  
     break;  
   
     case OP_PRUNE_ARG:  
     PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);  
7627      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7628        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
7629      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7630      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);
7631      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);
7632        if (common->has_skip_arg)
7633          {
7634          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7635          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7636          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7637          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7638          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7639          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7640          }
7641      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7642      break;      break;
7643    
7644      case OP_PRUNE:      case OP_PRUNE:
7645        case OP_PRUNE_ARG:
7646        case OP_SKIP:
7647        case OP_SKIP_ARG:
7648        case OP_THEN:
7649        case OP_THEN_ARG:
7650      case OP_COMMIT:      case OP_COMMIT:
7651      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7652      break;      break;
7653    
7654      case OP_FAIL:      case OP_FAIL:
# Line 7151  while (cc < ccend) Line 7672  while (cc < ccend)
7672    if (cc == NULL)    if (cc == NULL)
7673      return;      return;
7674    }    }
7675    
7676    if (has_then_trap)
7677      {
7678      /* Head item on backtrack. */
7679      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7680      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7681      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7682      common->then_trap = save_then_trap;
7683      }
7684  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7685  }  }
7686    
# Line 7312  switch(opcode) Line 7842  switch(opcode)
7842    }    }
7843  }  }
7844    
7845  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)
7846  {  {
7847  DEFINE_COMPILER;  DEFINE_COMPILER;
7848  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7334  set_jumps(current->topbacktracks, LABEL( Line 7864  set_jumps(current->topbacktracks, LABEL(
7864  free_stack(common, 2);  free_stack(common, 2);
7865  }  }
7866    
7867  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)
7868  {  {
7869  DEFINE_COMPILER;  DEFINE_COMPILER;
7870    
# Line 7430  if (bra == OP_BRAZERO) Line 7960  if (bra == OP_BRAZERO)
7960  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7961  {  {
7962  DEFINE_COMPILER;  DEFINE_COMPILER;
7963  int opcode;  int opcode, stacksize, count;
7964  int offset = 0;  int offset = 0;
7965  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7966  int stacksize;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
 int count;  
7967  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
7968  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
7969  pcre_uchar *ccprev;  pcre_uchar *ccprev;
# Line 7444  pcre_uchar bra = OP_BRA; Line 7973  pcre_uchar bra = OP_BRA;
7973  pcre_uchar ket;  pcre_uchar ket;
7974  assert_backtrack *assert;  assert_backtrack *assert;
7975  BOOL has_alternatives;  BOOL has_alternatives;
7976    BOOL needs_control_head = FALSE;
7977  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7978  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7979  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
7980  struct sljit_label *rminlabel = NULL;  struct sljit_label *rmin_label = NULL;
7981    struct sljit_label *exact_label = NULL;
7982    
7983  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
7984    {    {
# Line 7456  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 7987  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
7987    }    }
7988    
7989  opcode = *cc;  opcode = *cc;
7990    ccbegin = bracketend(cc) - 1 - LINK_SIZE;
7991    ket = *ccbegin;
7992    if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
7993      {
7994      repeat_ptr = PRIVATE_DATA(ccbegin);
7995      repeat_type = PRIVATE_DATA(ccbegin + 2);
7996      repeat_count = PRIVATE_DATA(ccbegin + 3);
7997      SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
7998      if (repeat_type == OP_UPTO)
7999        ket = OP_KETRMAX;
8000      if (repeat_type == OP_MINUPTO)
8001        ket = OP_KETRMIN;
8002      }
8003  ccbegin = cc;  ccbegin = cc;
 ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  
8004  cc += GET(cc, 1);  cc += GET(cc, 1);
8005  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
8006  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
# Line 7469  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 8012  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
8012  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
8013    opcode = OP_ONCE;    opcode = OP_ONCE;
8014    
8015    /* Decoding the needs_control_head in framesize. */
8016    if (opcode == OP_ONCE)
8017      {
8018      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
8019      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
8020      }
8021    
8022    if (ket != OP_KET && repeat_type != 0)
8023      {
8024      /* TMP1 is used in OP_KETRMIN below. */
8025      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8026      free_stack(common, 1);
8027      if (repeat_type == OP_UPTO)
8028        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
8029      else
8030        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8031      }
8032    
8033  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
8034    {    {
8035    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7483  else if (ket == OP_KETRMIN) Line 8044  else if (ket == OP_KETRMIN)
8044    if (bra != OP_BRAMINZERO)    if (bra != OP_BRAMINZERO)
8045      {      {
8046      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8047      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (repeat_type != 0)
8048          {
8049          /* TMP1 was set a few lines above. */
8050          CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8051          /* Drop STR_PTR for non-greedy plus quantifier. */
8052          if (opcode != OP_ONCE)
8053            free_stack(common, 1);
8054          }
8055        else if (opcode >= OP_SBRA || opcode == OP_ONCE)
8056        {        {
8057        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
8058        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 7493  else if (ket == OP_KETRMIN) Line 8062  else if (ket == OP_KETRMIN)
8062          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);
8063          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);
8064          }          }
8065          /* Drop STR_PTR for non-greedy plus quantifier. */
8066        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
8067          free_stack(common, 1);          free_stack(common, 1);
8068        }        }
8069      else      else
8070        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8071      }      }
8072    rminlabel = LABEL();    rmin_label = LABEL();
8073      if (repeat_type != 0)
8074        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8075    }    }
8076  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
8077    {    {
# Line 7507  else if (bra == OP_BRAZERO) Line 8079  else if (bra == OP_BRAZERO)
8079    free_stack(common, 1);    free_stack(common, 1);
8080    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
8081    }    }
8082    else if (repeat_type == OP_EXACT)
8083      {
8084      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8085      exact_label = LABEL();
8086      }
8087    
8088  if (offset != 0)  if (offset != 0)
8089    {    {
# Line 7626  if (has_alternatives) Line 8203  if (has_alternatives)
8203      current->top = NULL;      current->top = NULL;
8204      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8205      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8206        /* Conditional blocks always have an additional alternative, even if it is empty. */
8207      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8208        {        {
8209        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8210        cc += GET(cc, 1);        cc += GET(cc, 1);
8211        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8212          {          {
8213          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8214            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8215              if (private_data_ptr != 0)
8216                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8217              else
8218                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8219              }
8220          else          else
8221            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));
8222          }          }
8223        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8224        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7645  if (has_alternatives) Line 8228  if (has_alternatives)
8228      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8229      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8230      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8231        {        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));  
           }  
         }  
       }  
8232    
8233      stacksize = 0;      stacksize = 0;
8234        if (repeat_type == OP_MINUPTO)
8235          {
8236          /* We need to preserve the counter. TMP2 will be used below. */
8237          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
8238          stacksize++;
8239          }
8240      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8241        stacksize++;        stacksize++;
8242      if (offset != 0)      if (offset != 0)
# Line 7682  if (has_alternatives) Line 8249  if (has_alternatives)
8249      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8250        stacksize++;        stacksize++;
8251    
8252      if (stacksize > 0) {      if (stacksize > 0)
8253        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));  
         }  
     }  
8254    
8255      stacksize = 0;      stacksize = 0;
8256        if (repeat_type == OP_MINUPTO)
8257          {
8258          /* TMP2 was set above. */
8259          OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
8260          stacksize++;
8261          }
8262    
8263      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8264        {        {
8265        if (ket != OP_KET)        if (ket != OP_KET)
# Line 7704  if (has_alternatives) Line 8270  if (has_alternatives)
8270        }        }
8271    
8272      if (offset != 0)      if (offset != 0)
8273        {        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;  
         }  
       }  
8274    
8275      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8276        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 7757  if (has_alternatives) Line 8304  if (has_alternatives)
8304      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8305      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8306      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
   
8307        {        {
8308        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->private_data_ptr);
8309        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7797  else if (opcode == OP_SBRA || opcode == Line 8343  else if (opcode == OP_SBRA || opcode ==
8343  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8344    {    {
8345    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8346      stacksize = needs_control_head ? 1 : 0;
8347    
8348    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8349      {      {
8350      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8351      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);  
8352      }      }
8353    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8354      {      {
8355      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8356      free_stack(common, 1);      stacksize++;
8357      }      }
8358      free_stack(common, stacksize);
8359    
8360    JUMPHERE(once);    JUMPHERE(once);
8361    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7822  else if (opcode == OP_ONCE) Line 8370  else if (opcode == OP_ONCE)
8370      }      }
8371    }    }
8372    
8373  if (ket == OP_KETRMAX)  if (repeat_type == OP_EXACT)
8374      {
8375      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8376      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8377      CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
8378      }
8379    else if (ket == OP_KETRMAX)
8380    {    {
8381    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8382    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
8383      free_stack(common, 1);      free_stack(common, 1);
8384    
8385    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);
8386    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
8387      {      {
# Line 7845  else if (ket == OP_KETRMIN) Line 8400  else if (ket == OP_KETRMIN)
8400    affect badly the free_stack(2) above. */    affect badly the free_stack(2) above. */
8401    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
8402      free_stack(common, 1);      free_stack(common, 1);
8403    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
8404    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
8405      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
8406    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
# Line 7859  else if (bra == OP_BRAZERO) Line 8414  else if (bra == OP_BRAZERO)
8414    }    }
8415  }  }
8416    
8417  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)
8418  {  {
8419  DEFINE_COMPILER;  DEFINE_COMPILER;
8420  int offset;  int offset;
# Line 7898  if (current->topbacktracks) Line 8453  if (current->topbacktracks)
8453  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));
8454  }  }
8455    
8456  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)
8457  {  {
8458  assert_backtrack backtrack;  assert_backtrack backtrack;
8459    
# Line 7922  else Line 8477  else
8477  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8478  }  }
8479    
8480    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8481    {
8482    DEFINE_COMPILER;
8483    pcre_uchar opcode = *current->cc;
8484    struct sljit_label *loop;
8485    struct sljit_jump *jump;
8486    
8487    if (opcode == OP_THEN || opcode == OP_THEN_ARG)
8488      {
8489      if (common->then_trap != NULL)
8490        {
8491        SLJIT_ASSERT(common->control_head_ptr != 0);
8492    
8493        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8494        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8495        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8496        jump = JUMP(SLJIT_JUMP);
8497    
8498        loop = LABEL();
8499        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8500        JUMPHERE(jump);
8501        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8502        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8503        add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8504        return;
8505        }
8506      else if (common->positive_assert)
8507        {
8508        add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
8509        return;
8510        }
8511      }
8512    
8513    if (common->local_exit)
8514      {
8515      if (common->quit_label == NULL)
8516        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8517      else
8518        JUMPTO(SLJIT_JUMP, common->quit_label);
8519      return;
8520      }
8521    
8522    if (opcode == OP_SKIP_ARG)
8523      {
8524      SLJIT_ASSERT(common->control_head_ptr != 0);
8525      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8526      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8527      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8528      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8529      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8530    
8531      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8532      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8533      return;
8534      }
8535    
8536    if (opcode == OP_SKIP)
8537      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8538    else
8539      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8540    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8541    }
8542    
8543    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8544    {
8545    DEFINE_COMPILER;
8546    struct sljit_jump *jump;
8547    int size;
8548    
8549    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8550      {
8551      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8552      return;
8553      }
8554    
8555    size = CURRENT_AS(then_trap_backtrack)->framesize;
8556    size = 3 + (size < 0 ? 0 : size);
8557    
8558    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8559    free_stack(common, size);
8560    jump = JUMP(SLJIT_JUMP);
8561    
8562    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8563    /* STACK_TOP is set by THEN. */
8564    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8565      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8566    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8567    free_stack(common, 3);
8568    
8569    JUMPHERE(jump);
8570    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8571    }
8572    
8573  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8574  {  {
8575  DEFINE_COMPILER;  DEFINE_COMPILER;
8576    then_trap_backtrack *save_then_trap = common->then_trap;
8577    
8578  while (current)  while (current)
8579    {    {
# Line 8058  while (current) Line 8707  while (current)
8707      break;      break;
8708    
8709      case OP_MARK:      case OP_MARK:
8710      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));
8711      free_stack(common, 1);      if (common->has_skip_arg)
8712          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8713        free_stack(common, common->has_skip_arg ? 5 : 1);
8714      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);
8715        if (common->has_skip_arg)
8716          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8717      break;      break;
8718    
8719        case OP_THEN:
8720        case OP_THEN_ARG:
8721      case OP_PRUNE:      case OP_PRUNE:
8722      case OP_PRUNE_ARG:      case OP_PRUNE_ARG:
8723      if (!common->in_recurse)      case OP_SKIP:
8724        add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));      case OP_SKIP_ARG:
8725      else if (common->quit_label == NULL)      compile_control_verb_backtrackingpath(common, current);
       add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));  
     else  
       JUMPTO(SLJIT_JUMP, common->quit_label);  
8726      break;      break;
8727    
8728      case OP_COMMIT:      case OP_COMMIT:
8729      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8730          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8731      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8732        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8733      else      else
# Line 8088  while (current) Line 8741  while (current)
8741      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8742      break;      break;
8743    
8744        case OP_THEN_TRAP:
8745        /* A virtual opcode for then traps. */
8746        compile_then_trap_backtrackingpath(common, current);
8747        break;
8748    
8749      default:      default:
8750      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8751      break;      break;
8752      }      }
8753    current = current->prev;    current = current->prev;
8754    }    }
8755    common->then_trap = save_then_trap;
8756  }  }
8757    
8758  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8102  DEFINE_COMPILER; Line 8761  DEFINE_COMPILER;
8761  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8762  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);
8763  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8764  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8765  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8766    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8767  int alternativesize;  int alternativesize;
8768  BOOL needsframe;  BOOL needs_frame;
8769  backtrack_common altbacktrack;  backtrack_common altbacktrack;
8770  struct sljit_jump *jump;  struct sljit_jump *jump;
8771    
8772    /* Recurse captures then. */
8773    common->then_trap = NULL;
8774    
8775  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);
8776  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8777  if (!needsframe)  if (!needs_frame)
8778    framesize = 0;    framesize = 0;
8779  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8780    
# Line 8122  set_jumps(common->currententry->calls, c Line 8785  set_jumps(common->currententry->calls, c
8785  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8786  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8787  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);
8788  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);
8789    if (needs_control_head)
8790      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8791  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);
8792  if (needsframe)  if (needs_frame)
8793    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8794    
8795  if (alternativesize > 0)  if (alternativesize > 0)
8796    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 8162  while (1) Line 8827  while (1)
8827    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8828    cc += GET(cc, 1);    cc += GET(cc, 1);
8829    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8830    
8831    /* None of them matched. */
8832  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8833  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8834    
8835    if (common->quit != NULL)
8836      {
8837      set_jumps(common->quit, LABEL());
8838      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8839      if (needs_frame)
8840        {
8841        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8842        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8843        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8844        }
8845      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8846      common->quit = NULL;
8847      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8848      }
8849    
8850  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8851  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8852  if (needsframe)  if (needs_frame)
8853    {    {
8854    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8855    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 8180  if (needsframe) Line 8858  if (needsframe)
8858  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8859    
8860  JUMPHERE(jump);  JUMPHERE(jump);
8861  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8862      set_jumps(common->quit, LABEL());
8863    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8864  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8865  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8866  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8867  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8868      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8869      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8870      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8871      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8872      }
8873    else
8874      {
8875      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8876      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8877      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8878      }
8879  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
8880  }  }
8881    
# Line 8205  pcre_uchar *ccend; Line 8896  pcre_uchar *ccend;
8896  executable_functions *functions;  executable_functions *functions;
8897  void *executable_func;  void *executable_func;
8898  sljit_uw executable_size;  sljit_uw executable_size;
8899  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8900    struct sljit_label *continue_match_label;
8901  struct sljit_label *empty_match_found_label;  struct sljit_label *empty_match_found_label;
8902  struct sljit_label *empty_match_backtrack_label;  struct sljit_label *empty_match_backtrack_label;
8903  struct sljit_label *reset_match_label;  struct sljit_label *reset_match_label;
# Line 8293  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA Line 8985  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA
8985  common->capture_last_ptr = common->ovector_start;  common->capture_last_ptr = common->ovector_start;
8986  common->ovector_start += sizeof(sljit_sw);  common->ovector_start += sizeof(sljit_sw);
8987  #endif  #endif
8988  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  if (!check_opcode_types(common, rootbacktrack.cc, ccend))
 if (private_data_size < 0)  
8989    {    {
8990    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8991    return;    return;
# Line 8326  if ((re->options & PCRE_FIRSTLINE) != 0) Line 9017  if ((re->options & PCRE_FIRSTLINE) != 0)
9017    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
9018    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
9019    }    }
9020    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
9021    common->control_head_ptr = 1;
9022    #endif
9023    if (common->control_head_ptr != 0)
9024      {
9025      common->control_head_ptr = common->ovector_start;
9026      common->ovector_start += sizeof(sljit_sw);
9027      }
9028  if (common->needs_start_ptr && common->has_set_som)  if (common->needs_start_ptr && common->has_set_som)
9029    {    {
9030    /* Saving the real start pointer is necessary. */    /* Saving the real start pointer is necessary. */
# Line 8348  if (common->capture_last_ptr != 0) Line 9047  if (common->capture_last_ptr != 0)
9047    
9048  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
9049  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);
9050  private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);  
9051  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));
9052    if (!common->private_data_ptrs)
9053    {    {
9054    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9055    return;    return;
9056    }    }
9057  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
9058  if (!common->private_data_ptrs)  
9059    private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
9060    set_private_data_ptrs(common, &private_data_size, ccend);
9061    if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
9062    {    {
9063      SLJIT_FREE(common->private_data_ptrs);
9064    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9065    return;    return;
9066    }    }
9067  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  
9068  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  if (common->has_then)
9069      {
9070      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
9071      if (!common->then_offsets)
9072        {
9073        SLJIT_FREE(common->optimized_cbracket);
9074        SLJIT_FREE(common->private_data_ptrs);
9075        return;
9076        }
9077      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
9078      set_then_offsets(common, rootbacktrack.cc, NULL);
9079      }
9080    
9081  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
9082  if (!compiler)  if (!compiler)
9083    {    {
9084    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9085    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9086      if (common->has_then)
9087        SLJIT_FREE(common->then_offsets);
9088    return;    return;
9089    }    }
9090  common->compiler = compiler;  common->compiler = compiler;
# Line 8392  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 9109  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
9109    
9110  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9111    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);
9112    if (common->mark_ptr != 0)
9113      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
9114    if (common->control_head_ptr != 0)
9115      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
9116    
9117  /* Main part of the matching */  /* Main part of the matching */
9118  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9119    {    {
9120    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
9121      continue_match_label = LABEL();
9122    /* Forward search if possible. */    /* Forward search if possible. */
9123    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
9124      {      {
# Line 8410  if ((re->options & PCRE_ANCHORED) == 0) Line 9132  if ((re->options & PCRE_ANCHORED) == 0)
9132        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
9133      }      }
9134    }    }
9135    else
9136      continue_match_label = LABEL();
9137    
9138  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
9139    {    {
9140    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
# Line 8423  if (common->req_char_ptr != 0) Line 9148  if (common->req_char_ptr != 0)
9148  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);
9149  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9150  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
 if (common->mark_ptr != 0)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);  
9151  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9152    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);
9153    
# Line 8453  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9176  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9176    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9177    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9178    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9179      if (common->has_then)
9180        SLJIT_FREE(common->then_offsets);
9181    return;    return;
9182    }    }
9183    
# Line 8488  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9213  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9213    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9214    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9215    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9216      if (common->has_then)
9217        SLJIT_FREE(common->then_offsets);
9218    return;    return;
9219    }    }
9220    
# Line 8516  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SL Line 9243  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SL
9243  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9244    {    {
9245    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
9246      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
9247    else    else
9248      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
9249    }    }
9250    
9251  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8544  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PT Line 9271  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PT
9271  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9272    
9273  common->currententry = common->entries;  common->currententry = common->entries;
9274  common->in_recurse = TRUE;  common->local_exit = TRUE;
9275  quit_label = common->quit_label;  quit_label = common->quit_label;
9276  while (common->currententry != NULL)  while (common->currententry != NULL)
9277    {    {
# Line 8555  while (common->currententry != NULL) Line 9282  while (common->currententry != NULL)
9282      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9283      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9284      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9285        if (common->has_then)
9286          SLJIT_FREE(common->then_offsets);
9287      return;      return;
9288      }      }
9289    flush_stubs(common);    flush_stubs(common);
9290    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
9291    }    }
9292  common->in_recurse = FALSE;  common->local_exit = FALSE;
9293  common->quit_label = quit_label;  common->quit_label = quit_label;
9294    
9295  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
# Line 8633  if (common->reset_match != NULL) Line 9362  if (common->reset_match != NULL)
9362    {    {
9363    set_jumps(common->reset_match, LABEL());    set_jumps(common->reset_match, LABEL());
9364    do_reset_match(common, (re->top_bracket + 1) * 2);    do_reset_match(common, (re->top_bracket + 1) * 2);
9365      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
9366      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
9367    JUMPTO(SLJIT_JUMP, reset_match_label);    JUMPTO(SLJIT_JUMP, reset_match_label);
9368    }    }
9369  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 8661  if (common->getucd != NULL) Line 9392  if (common->getucd != NULL)
9392    
9393  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9394  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9395    if (common->has_then)
9396      SLJIT_FREE(common->then_offsets);
9397    
9398  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9399  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9400  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

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

  ViewVC Help
Powered by ViewVC 1.1.5