/[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 1268 by zherczeg, Mon Mar 4 08:42:15 2013 UTC revision 1306 by zherczeg, Mon Apr 1 17:04:17 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 {
311      /* The sljit ceneric compiler. */
312    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
313      /* 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 cbraptr;    int cbra_ptr;
325    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
326    int ovector_start;    int ovector_start;
327    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
328    int req_char_ptr;    int req_char_ptr;
# Line 305  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. */
344      int start_ptr;
345    
346    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
347    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
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 found in the pattern. */
352      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. */
358      BOOL needs_start_ptr;
359      /* Currently in recurse or negative assert. */
360      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;
366    int bsr_nltype;    int bsr_nltype;
367    /* Dollar endonly. */    /* Dollar endonly. */
368    int endonly;    int endonly;
   BOOL has_set_som;  
369    /* Tables. */    /* Tables. */
370    sljit_sw ctypes;    sljit_sw ctypes;
371    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 338  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 349  typedef struct compiler_common { Line 396  typedef struct compiler_common {
396    jump_list *vspace;    jump_list *vspace;
397    jump_list *casefulcmp;    jump_list *casefulcmp;
398    jump_list *caselesscmp;    jump_list *caselesscmp;
399      jump_list *reset_match;
400    BOOL jscript_compat;    BOOL jscript_compat;
401  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
402    BOOL utf;    BOOL utf;
# Line 433  group contains the start / end character Line 481  group contains the start / end character
481  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
482  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
483  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
484  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
485  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
486    
487  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 486  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 572  switch(*cc) Line 620  switch(*cc)
620    case OP_BRAZERO:    case OP_BRAZERO:
621    case OP_BRAMINZERO:    case OP_BRAMINZERO:
622    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
623      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 670  switch(*cc) Line 721  switch(*cc)
721  #endif  #endif
722    
723    case OP_MARK:    case OP_MARK:
724      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 782  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 807  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 828  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 921  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:
824        common->needs_start_ptr = TRUE;
825        /* Fall through. */
826    
827      case OP_MARK:      case OP_MARK:
828      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
829        {        {
# Line 930  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:
842        case OP_SKIP:
843        common->needs_start_ptr = TRUE;
844        cc += 1;
845        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 979  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_BRA || *cc == OP_CBRA || *cc == OP_ONCE || *cc == OP_ONCE_NC)
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 1074  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 1104  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 1118  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 1142  while (cc < ccend) Line 1233  while (cc < ccend)
1233      break;      break;
1234    
1235      case OP_MARK:      case OP_MARK:
1236        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 1149  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 1268  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 1283  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 1304  while (cc < ccend) Line 1403  while (cc < ccend)
1403      break;      break;
1404    
1405      case OP_MARK:      case OP_MARK:
1406        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 1384  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 1499  return private_data_length; Line 1600  return private_data_length;
1600  }  }
1601    
1602  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,
1603    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1604  {  {
1605  DEFINE_COMPILER;  DEFINE_COMPILER;
1606  int srcw[2];  int srcw[2];
# Line 1520  stacktop = STACK(stacktop - 1); Line 1621  stacktop = STACK(stacktop - 1);
1621    
1622  if (!save)  if (!save)
1623    {    {
1624    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1625    if (stackptr < stacktop)    if (stackptr < stacktop)
1626      {      {
1627      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1536  if (!save) Line 1637  if (!save)
1637    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1638    }    }
1639    
1640  while (status != end)  do
1641    {    {
1642    count = 0;    count = 0;
1643    switch(status)    switch(status)
# Line 1545  while (status != end) Line 1646  while (status != end)
1646      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1647      count = 1;      count = 1;
1648      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1649        if (needs_control_head)
1650          {
1651          SLJIT_ASSERT(common->control_head_ptr != 0);
1652          count = 2;
1653          srcw[1] = common->control_head_ptr;
1654          }
1655      status = loop;      status = loop;
1656      break;      break;
1657    
# Line 1769  while (status != end) Line 1876  while (status != end)
1876        }        }
1877      }      }
1878    }    }
1879    while (status != end);
1880    
1881  if (save)  if (save)
1882    {    {
# Line 1799  if (save) Line 1907  if (save)
1907        }        }
1908      }      }
1909    }    }
1910  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1911    }
1912    
1913    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1914    {
1915    pcre_uchar *end = bracketend(cc);
1916    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1917    
1918    /* Assert captures then. */
1919    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1920      current_offset = NULL;
1921    /* Conditional block does not. */
1922    if (*cc == OP_COND || *cc == OP_SCOND)
1923      has_alternatives = FALSE;
1924    
1925    cc = next_opcode(common, cc);
1926    if (has_alternatives)
1927      current_offset = common->then_offsets + (cc - common->start);
1928    
1929    while (cc < end)
1930      {
1931      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1932        cc = set_then_offsets(common, cc, current_offset);
1933      else
1934        {
1935        if (*cc == OP_ALT && has_alternatives)
1936          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1937        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1938          *current_offset = 1;
1939        cc = next_opcode(common, cc);
1940        }
1941      }
1942    
1943    return end;
1944  }  }
1945    
1946  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
# Line 1900  static SLJIT_INLINE void reset_ovector(c Line 2041  static SLJIT_INLINE void reset_ovector(c
2041  DEFINE_COMPILER;  DEFINE_COMPILER;
2042  struct sljit_label *loop;  struct sljit_label *loop;
2043  int i;  int i;
2044    
2045  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2046    SLJIT_ASSERT(length > 1);
2047  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2048  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2049  if (length < 8)  if (length < 8)
2050    {    {
2051    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2052      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2053    }    }
2054  else  else
2055    {    {
2056    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2057    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2058    loop = LABEL();    loop = LABEL();
2059    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2060    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
# Line 1919  else Line 2062  else
2062    }    }
2063  }  }
2064    
2065    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2066    {
2067    DEFINE_COMPILER;
2068    struct sljit_label *loop;
2069    int i;
2070    
2071    SLJIT_ASSERT(length > 1);
2072    /* OVECTOR(1) contains the "string begin - 1" constant. */
2073    if (length > 2)
2074      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2075    if (length < 8)
2076      {
2077      for (i = 2; i < length; i++)
2078        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2079      }
2080    else
2081      {
2082      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2083      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2084      loop = LABEL();
2085      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2086      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2087      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2088      }
2089    
2090    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2091    if (common->mark_ptr != 0)
2092      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2093    if (common->control_head_ptr != 0)
2094      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2095    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2096    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2097    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2098    }
2099    
2100    static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2101    {
2102    while (current != NULL)
2103      {
2104      switch (current[-2])
2105        {
2106        case type_then_trap:
2107        break;
2108    
2109        case type_mark:
2110        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2111          return current[-4];
2112        break;
2113    
2114        default:
2115        SLJIT_ASSERT_STOP();
2116        break;
2117        }
2118      current = (sljit_sw*)current[-1];
2119      }
2120    return -1;
2121    }
2122    
2123  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2124  {  {
2125  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1975  DEFINE_COMPILER; Line 2176  DEFINE_COMPILER;
2176  struct sljit_jump *jump;  struct sljit_jump *jump;
2177    
2178  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
2179  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));  SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2180      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2181    
2182  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2183  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
# Line 1987  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI Line 2189  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2189  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));
2190    
2191  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);
2192  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr + 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);
2193  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2194  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);
2195  #endif  #endif
# Line 2170  else if (common->mode == JIT_PARTIAL_SOF Line 2372  else if (common->mode == JIT_PARTIAL_SOF
2372    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2373    
2374  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2375    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, 0);
2376  else  else
2377    {    {
2378    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2183  if (jump != NULL) Line 2385  if (jump != NULL)
2385    JUMPHERE(jump);    JUMPHERE(jump);
2386  }  }
2387    
2388  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2389  {  {
2390  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2391  DEFINE_COMPILER;  DEFINE_COMPILER;
2392  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2393    
2394  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2395    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2396      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2397      return;
2398      }
2399    
2400  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2401  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2402    {    {
2403    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2404    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, 0);
2405    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2406    }    }
2407  else  else
2408    {    {
2409    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2410    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2411      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2412    else    else
2413      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2414    }    }
2415  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2416  }  }
2417    
2418  static void detect_partial_match(compiler_common *common, jump_list **backtracks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
# Line 2230  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR Line 2431  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2431  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2432  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2433    {    {
2434    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, 0);
2435    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2436    }    }
2437  else  else
# Line 3178  static void check_wordboundary(compiler_ Line 3379  static void check_wordboundary(compiler_
3379  {  {
3380  DEFINE_COMPILER;  DEFINE_COMPILER;
3381  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3382    jump_list *skipread_list = NULL;
3383  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3384  struct sljit_jump *jump;  struct sljit_jump *jump;
3385  #endif  #endif
# Line 3235  else Line 3437  else
3437  JUMPHERE(skipread);  JUMPHERE(skipread);
3438    
3439  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3440  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3441  peek_char(common);  peek_char(common);
3442    
3443  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3276  else Line 3478  else
3478      JUMPHERE(jump);      JUMPHERE(jump);
3479  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3480    }    }
3481  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3482    
3483  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3484  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 4224  int length; Line 4426  int length;
4426  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4427  compare_context context;  compare_context context;
4428  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4429    jump_list *end_list;
4430  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4431  struct sljit_label *label;  struct sljit_label *label;
4432  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4292  switch(type) Line 4495  switch(type)
4495    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4496      {      {
4497      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4498        end_list = NULL;
4499      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4500        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);        add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4501      else      else
4502        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4503    
4504      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4505      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4506      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4507      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4508      }      }
4509    else    else
# Line 4359  switch(type) Line 4562  switch(type)
4562    read_char(common);    read_char(common);
4563    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
4564    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4565      end_list = NULL;
4566    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4567      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4568    else    else
4569      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4570    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4571    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4572    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4573    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4574    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4575    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4576      set_jumps(end_list, LABEL());
4577    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4578    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4579    return cc;    return cc;
4580    
4581    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 5121  DEFINE_COMPILER; Line 5325  DEFINE_COMPILER;
5325  backtrack_common *backtrack;  backtrack_common *backtrack;
5326  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5327  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5328  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5329  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5330    BOOL needs_control_head;
5331    
5332  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5333    
5334  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5335  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5336    {    {
5337    start_cc = common->start + start;    start_cc = common->start + start;
5338    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 5246  allocate_stack(common, CALLOUT_ARG_SIZE Line 5451  allocate_stack(common, CALLOUT_ARG_SIZE
5451  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5452  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5453  SLJIT_ASSERT(common->capture_last_ptr != 0);  SLJIT_ASSERT(common->capture_last_ptr != 0);
5454  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5455  OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5456    
5457  /* These pointer sized fields temporarly stores internal variables. */  /* These pointer sized fields temporarly stores internal variables. */
5458  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 5256  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA Line 5461  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA
5461    
5462  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
5463    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5464  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5465  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5466  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5467    
5468  /* Needed to save important temporary registers. */  /* Needed to save important temporary registers. */
# Line 5286  static pcre_uchar *compile_assert_matchi Line 5491  static pcre_uchar *compile_assert_matchi
5491  {  {
5492  DEFINE_COMPILER;  DEFINE_COMPILER;
5493  int framesize;  int framesize;
5494    int extrasize;
5495    BOOL needs_control_head;
5496  int private_data_ptr;  int private_data_ptr;
5497  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5498  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5295  jump_list *tmp = NULL; Line 5502  jump_list *tmp = NULL;
5502  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5503  jump_list **found;  jump_list **found;
5504  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5505    BOOL save_local_exit = common->local_exit;
5506    BOOL save_positive_assert = common->positive_assert;
5507    then_trap_backtrack *save_then_trap = common->then_trap;
5508  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5509  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5510  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5511    jump_list *save_positive_assert_quit = common->positive_assert_quit;
5512  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5513  struct sljit_jump *jump;  struct sljit_jump *jump;
5514  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5515    
5516    /* Assert captures then. */
5517    common->then_trap = NULL;
5518    
5519  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5520    {    {
5521    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5310  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5524  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5524    }    }
5525  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5526  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5527  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5528  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5529  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5530  opcode = *cc;  opcode = *cc;
# Line 5329  if (bra == OP_BRAMINZERO) Line 5543  if (bra == OP_BRAMINZERO)
5543    
5544  if (framesize < 0)  if (framesize < 0)
5545    {    {
5546    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5547    allocate_stack(common, 1);    if (framesize == no_frame)
5548        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5549      allocate_stack(common, extrasize);
5550      if (needs_control_head)
5551        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5552    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5553      if (needs_control_head)
5554        {
5555        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5556        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5557        }
5558    }    }
5559  else  else
5560    {    {
5561    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5562      allocate_stack(common, framesize + extrasize);
5563    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);
5564    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));
5565    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);
5566      if (needs_control_head)
5567        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5568    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5569    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5570    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5571        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5572        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5573        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5574        }
5575      else
5576        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5577      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5578    }    }
5579    
5580  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5581  common->quit_label = NULL;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5582  common->quit = NULL;    {
5583      /* Negative assert is stronger than positive assert. */
5584      common->local_exit = TRUE;
5585      common->quit_label = NULL;
5586      common->quit = NULL;
5587      common->positive_assert = FALSE;
5588      }
5589    else
5590      common->positive_assert = TRUE;
5591    common->positive_assert_quit = NULL;
5592    
5593  while (1)  while (1)
5594    {    {
5595    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5361  while (1) Line 5604  while (1)
5604    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5605    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5606      {      {
5607      common->quit_label = save_quit_label;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5608          {
5609          common->local_exit = save_local_exit;
5610          common->quit_label = save_quit_label;
5611          common->quit = save_quit;
5612          }
5613        common->positive_assert = save_positive_assert;
5614        common->then_trap = save_then_trap;
5615      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5616      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5617      common->accept = save_accept;      common->accept = save_accept;
5618      return NULL;      return NULL;
5619      }      }
# Line 5373  while (1) Line 5623  while (1)
5623    
5624    /* Reset stack. */    /* Reset stack. */
5625    if (framesize < 0)    if (framesize < 0)
5626      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5627    else {      if (framesize == no_frame)
5628          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5629        else
5630          free_stack(common, extrasize);
5631        if (needs_control_head)
5632          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5633        }
5634      else
5635        {
5636      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5637        {        {
5638        /* 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. */
5639        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));
5640          if (needs_control_head)
5641            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5642        }        }
5643      else      else
5644        {        {
5645        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5646          if (needs_control_head)
5647            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5648        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5649        }        }
5650    }      }
5651    
5652    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5653      {      {
5654      /* 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. */
5655      if (conditional)      if (conditional)
5656        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);
5657      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5658        {        {
5659        if (framesize < 0)        if (framesize < 0)
5660          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));
5661        else        else
5662          {          {
5663          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));
5664          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));
5665          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);
5666          }          }
5667        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 5416  while (1) Line 5678  while (1)
5678    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5679    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5680      {      {
5681      common->quit_label = save_quit_label;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5682          {
5683          common->local_exit = save_local_exit;
5684          common->quit_label = save_quit_label;
5685          common->quit = save_quit;
5686          }
5687        common->positive_assert = save_positive_assert;
5688        common->then_trap = save_then_trap;
5689      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5690      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5691      common->accept = save_accept;      common->accept = save_accept;
5692      return NULL;      return NULL;
5693      }      }
# Line 5430  while (1) Line 5699  while (1)
5699    ccbegin = cc;    ccbegin = cc;
5700    cc += GET(cc, 1);    cc += GET(cc, 1);
5701    }    }
5702    
5703    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5704      {
5705      SLJIT_ASSERT(common->positive_assert_quit == NULL);
5706      /* Makes the check less complicated below. */
5707      common->positive_assert_quit = common->quit;
5708      }
5709    
5710  /* None of them matched. */  /* None of them matched. */
5711  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
5712    set_jumps(common->quit, LABEL());    {
5713      jump = JUMP(SLJIT_JUMP);
5714      set_jumps(common->positive_assert_quit, LABEL());
5715      SLJIT_ASSERT(framesize != no_stack);
5716      if (framesize < 0)
5717        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5718      else
5719        {
5720        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5721        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5722        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5723        }
5724      JUMPHERE(jump);
5725      }
5726    
5727    if (needs_control_head)
5728      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5729    
5730  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5731    {    {
# Line 5444  if (opcode == OP_ASSERT || opcode == OP_ Line 5737  if (opcode == OP_ASSERT || opcode == OP_
5737      {      {
5738      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5739      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5740          {
5741          if (extrasize == 2)
5742            free_stack(common, 1);
5743        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5744          }
5745      else      else
5746        free_stack(common, 1);        free_stack(common, extrasize);
5747      }      }
5748    else    else
5749      {      {
5750      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5751      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5752      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5753        {        {
5754        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5755        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5756        }        }
5757      else      else
5758        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5759      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);
5760      }      }
5761    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5470  if (opcode == OP_ASSERT || opcode == OP_ Line 5767  if (opcode == OP_ASSERT || opcode == OP_
5767    if (framesize < 0)    if (framesize < 0)
5768      {      {
5769      /* 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. */
5770      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));
5771      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5772      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5773          {
5774        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));
5775          if (extrasize == 2)
5776            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5777          }
5778      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5779        {        {
5780        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 5486  if (opcode == OP_ASSERT || opcode == OP_ Line 5787  if (opcode == OP_ASSERT || opcode == OP_
5787        {        {
5788        /* 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. */
5789        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));
5790        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));
5791        }        }
5792      else      else
5793        {        {
5794        /* 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. */
5795        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));
5796        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5797        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5798            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5799            if (bra == OP_BRAMINZERO)
5800              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5801            }
5802          else
5803            {
5804            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5805            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5806            }
5807        }        }
5808      }      }
5809    
# Line 5522  else Line 5832  else
5832      {      {
5833      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5834      if (bra != OP_BRA)      if (bra != OP_BRA)
5835          {
5836          if (extrasize == 2)
5837            free_stack(common, 1);
5838        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5839          }
5840      else      else
5841        free_stack(common, 1);        free_stack(common, extrasize);
5842      }      }
5843    else    else
5844      {      {
5845      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5846      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5847      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5848      if (bra != OP_BRA)      if (bra != OP_BRA)
5849        {        {
5850        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5851        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5852        }        }
5853      else      else
5854        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5855      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);
5856      }      }
5857    
# Line 5557  else Line 5871  else
5871      }      }
5872    }    }
5873    
5874  common->quit_label = save_quit_label;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5875      {
5876      common->local_exit = save_local_exit;
5877      common->quit_label = save_quit_label;
5878      common->quit = save_quit;
5879      }
5880    common->positive_assert = save_positive_assert;
5881    common->then_trap = save_then_trap;
5882  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5883  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
5884  common->accept = save_accept;  common->accept = save_accept;
5885  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5886  }  }
# Line 5674  if (i < name_count) Line 5995  if (i < name_count)
5995  return condition;  return condition;
5996  }  }
5997    
5998    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)
5999    {
6000    DEFINE_COMPILER;
6001    int stacksize;
6002    
6003    if (framesize < 0)
6004      {
6005      if (framesize == no_frame)
6006        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6007      else
6008        {
6009        stacksize = needs_control_head ? 1 : 0;
6010        if (ket != OP_KET || has_alternatives)
6011          stacksize++;
6012        free_stack(common, stacksize);
6013        }
6014    
6015      if (needs_control_head)
6016        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6017    
6018      /* TMP2 which is set here used by OP_KETRMAX below. */
6019      if (ket == OP_KETRMAX)
6020        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6021      else if (ket == OP_KETRMIN)
6022        {
6023        /* Move the STR_PTR to the private_data_ptr. */
6024        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6025        }
6026      }
6027    else
6028      {
6029      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6030      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6031      if (needs_control_head)
6032        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6033    
6034      if (ket == OP_KETRMAX)
6035        {
6036        /* TMP2 which is set here used by OP_KETRMAX below. */
6037        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6038        }
6039      }
6040    if (needs_control_head)
6041      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6042    }
6043    
6044    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6045    {
6046    DEFINE_COMPILER;
6047    
6048    if (common->capture_last_ptr != 0)
6049      {
6050      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6051      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6052      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6053      stacksize++;
6054      }
6055    if (common->optimized_cbracket[offset >> 1] == 0)
6056      {
6057      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6058      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6059      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6060      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6061      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6062      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6063      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6064      stacksize += 2;
6065      }
6066    return stacksize;
6067    }
6068    
6069  /*  /*
6070    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6071    
# Line 5736  pcre_uchar opcode; Line 6128  pcre_uchar opcode;
6128  int private_data_ptr = 0;  int private_data_ptr = 0;
6129  int offset = 0;  int offset = 0;
6130  int stacksize;  int stacksize;
6131    int repeat_ptr = 0, repeat_length = 0;
6132    int repeat_type = 0, repeat_count = 0;
6133  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6134  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6135  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6136  pcre_uchar ket;  pcre_uchar ket;
6137  assert_backtrack *assert;  assert_backtrack *assert;
6138  BOOL has_alternatives;  BOOL has_alternatives;
6139    BOOL needs_control_head = FALSE;
6140  struct sljit_jump *jump;  struct sljit_jump *jump;
6141  struct sljit_jump *skip;  struct sljit_jump *skip;
6142  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 5758  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6153  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6153    
6154  opcode = *cc;  opcode = *cc;
6155  ccbegin = cc;  ccbegin = cc;
6156  matchingpath = ccbegin + 1 + LINK_SIZE;  matchingpath = bracketend(cc) - 1 - LINK_SIZE;
6157    ket = *matchingpath;
6158    if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
6159      {
6160      repeat_ptr = PRIVATE_DATA(matchingpath);
6161      repeat_length = PRIVATE_DATA(matchingpath + 1);
6162      repeat_type = PRIVATE_DATA(matchingpath + 2);
6163      repeat_count = PRIVATE_DATA(matchingpath + 3);
6164      SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
6165      if (repeat_type == OP_UPTO)
6166        ket = OP_KETRMAX;
6167      if (repeat_type == OP_MINUPTO)
6168        ket = OP_KETRMIN;
6169      }
6170    
6171  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)
6172    {    {
6173    /* Drop this bracket_backtrack. */    /* Drop this bracket_backtrack. */
6174    parent->top = backtrack->prev;    parent->top = backtrack->prev;
6175    return bracketend(cc);    return matchingpath + 1 + LINK_SIZE + repeat_length;
6176    }    }
6177    
6178  ket = *(bracketend(cc) - 1 - LINK_SIZE);  matchingpath = ccbegin + 1 + LINK_SIZE;
6179  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
6180  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)));
6181  cc += GET(cc, 1);  cc += GET(cc, 1);
# Line 5817  else if (opcode == OP_ONCE || opcode == Line 6225  else if (opcode == OP_ONCE || opcode ==
6225    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6226    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6227    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6228      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);
6229    }    }
6230    
6231  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6232  stacksize = 0;  stacksize = 0;
6233  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6234    stacksize++;    stacksize++;
6235  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6236    stacksize++;    stacksize++;
# Line 5831  if (stacksize > 0) Line 6239  if (stacksize > 0)
6239    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6240    
6241  stacksize = 0;  stacksize = 0;
6242  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6243    {    {
6244    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6245    stacksize++;    stacksize++;
# Line 5881  if (bra == OP_BRAMINZERO) Line 6289  if (bra == OP_BRAMINZERO)
6289      }      }
6290    }    }
6291    
6292    if (repeat_type != 0)
6293      {
6294      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
6295      if (repeat_type == OP_EXACT)
6296        rmaxlabel = LABEL();
6297      }
6298    
6299  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
6300    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6301    
6302  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6303    {    {
6304    rmaxlabel = LABEL();    rmaxlabel = LABEL();
6305    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
6306      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
6307    }    }
6308    
6309  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6310  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6311    {    {
6312      stacksize = 0;
6313      if (needs_control_head)
6314        {
6315        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6316        stacksize++;
6317        }
6318    
6319    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6320      {      {
6321      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6322      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6323        {        {
6324        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6325        allocate_stack(common, 2);        if (!needs_control_head)
6326        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));  
6327        }        }
6328      else if (ket == OP_KETRMAX || has_alternatives)      else
6329        {        {
6330        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6331        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6332        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6333            stacksize++;
6334        }        }
6335      else  
6336        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6337          allocate_stack(common, stacksize);
6338    
6339        stacksize = 0;
6340        if (needs_control_head)
6341          {
6342          stacksize++;
6343          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6344          }
6345    
6346        if (ket == OP_KETRMIN)
6347          {
6348          if (needs_control_head)
6349            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6350          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6351          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6352            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));
6353          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6354          }
6355        else if (ket == OP_KETRMAX || has_alternatives)
6356          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6357      }      }
6358    else    else
6359      {      {
6360      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6361          stacksize++;
6362    
6363        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6364        allocate_stack(common, stacksize);
6365    
6366        if (needs_control_head)
6367          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6368    
6369        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6370        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6371    
6372        stacksize = needs_control_head ? 1 : 0;
6373        if (ket != OP_KET || has_alternatives)
6374        {        {
6375        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);  
6376        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);
6377        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6378        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6379        }        }
6380      else      else
6381        {        {
       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));  
6382        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);
6383        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);  
6384        }        }
6385        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6386      }      }
6387    }    }
6388  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 6070  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6518  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6518    return NULL;    return NULL;
6519    
6520  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6521    {    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));  
       }  
     }  
   }  
6522    
6523  stacksize = 0;  stacksize = 0;
6524    if (repeat_type == OP_MINUPTO)
6525      {
6526      /* We need to preserve the counter. TMP2 will be used below. */
6527      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6528      stacksize++;
6529      }
6530  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6531    stacksize++;    stacksize++;
6532  if (offset != 0)  if (offset != 0)
# Line 6112  if (stacksize > 0) Line 6543  if (stacksize > 0)
6543    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6544    
6545  stacksize = 0;  stacksize = 0;
6546    if (repeat_type == OP_MINUPTO)
6547      {
6548      /* TMP2 was set above. */
6549      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
6550      stacksize++;
6551      }
6552    
6553  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6554    {    {
6555    if (ket != OP_KET)    if (ket != OP_KET)
# Line 6122  if (ket != OP_KET || bra != OP_BRA) Line 6560  if (ket != OP_KET || bra != OP_BRA)
6560    }    }
6561    
6562  if (offset != 0)  if (offset != 0)
6563    {    stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
   if (common->capture_last_ptr != 0)  
     {  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);  
     stacksize++;  
     }  
   if (common->optimized_cbracket[offset >> 1] == 0)  
     {  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     stacksize += 2;  
     }  
   }  
6564    
6565  if (has_alternatives)  if (has_alternatives)
6566    {    {
# Line 6160  if (offset != 0 && common->optimized_cbr Line 6579  if (offset != 0 && common->optimized_cbr
6579    
6580  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6581    {    {
6582    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (repeat_type != 0)
6583        {
6584        if (has_alternatives)
6585          BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6586        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6587        JUMPTO(SLJIT_C_NOT_ZERO, rmaxlabel);
6588        /* Drop STR_PTR for greedy plus quantifier. */
6589        if (opcode != OP_ONCE)
6590          free_stack(common, 1);
6591        }
6592      else if (opcode == OP_ONCE || opcode >= OP_SBRA)
6593      {      {
6594      if (has_alternatives)      if (has_alternatives)
6595        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
# Line 6181  if (ket == OP_KETRMAX) Line 6610  if (ket == OP_KETRMAX)
6610    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6611    }    }
6612    
6613    if (repeat_type == OP_EXACT)
6614      {
6615      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6616      JUMPTO(SLJIT_C_NOT_ZERO, rmaxlabel);
6617      }
6618    else if (repeat_type == OP_UPTO)
6619      {
6620      /* We need to preserve the counter. */
6621      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6622      allocate_stack(common, 1);
6623      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6624      }
6625    
6626  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6627    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
6628    
# Line 6212  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6654  if ((ket != OP_KET && bra != OP_BRAMINZE
6654  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6655    cc += GET(cc, 1);    cc += GET(cc, 1);
6656  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6657  return cc;  
6658    /* Temporarily encoding the needs_control_head in framesize. */
6659    if (opcode == OP_ONCE)
6660      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6661    return cc + repeat_length;
6662  }  }
6663    
6664  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 6222  backtrack_common *backtrack; Line 6668  backtrack_common *backtrack;
6668  pcre_uchar opcode;  pcre_uchar opcode;
6669  int private_data_ptr;  int private_data_ptr;
6670  int cbraprivptr = 0;  int cbraprivptr = 0;
6671    BOOL needs_control_head;
6672  int framesize;  int framesize;
6673  int stacksize;  int stacksize;
6674  int offset = 0;  int offset = 0;
6675  BOOL zero = FALSE;  BOOL zero = FALSE;
6676  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6677  int stack;  int stack; /* Also contains the offset of control head. */
6678  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6679  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6680    
# Line 6265  switch(opcode) Line 6712  switch(opcode)
6712    break;    break;
6713    }    }
6714    
6715  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6716  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6717  if (framesize < 0)  if (framesize < 0)
6718    {    {
# Line 6278  if (framesize < 0) Line 6725  if (framesize < 0)
6725    else    else
6726      stacksize = 1;      stacksize = 1;
6727    
6728      if (needs_control_head)
6729        stacksize++;
6730    if (!zero)    if (!zero)
6731      stacksize++;      stacksize++;
6732    
# Line 6286  if (framesize < 0) Line 6735  if (framesize < 0)
6735    if (framesize == no_frame)    if (framesize == no_frame)
6736      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);
6737    
6738      stack = 0;
6739    if (offset != 0)    if (offset != 0)
6740      {      {
6741        stack = 2;
6742      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6743      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));
6744      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6745      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6746        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);
6747      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6748        if (needs_control_head)
6749          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6750      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6751          {
6752        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6753          stack = 3;
6754          }
6755      }      }
6756    else    else
6757        {
6758        if (needs_control_head)
6759          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6760      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6761        stack = 1;
6762        }
6763    
6764      if (needs_control_head)
6765        stack++;
6766    if (!zero)    if (!zero)
6767      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);
6768      if (needs_control_head)
6769        {
6770        stack--;
6771        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6772        }
6773    }    }
6774  else  else
6775    {    {
6776    stacksize = framesize + 1;    stacksize = framesize + 1;
6777    if (!zero)    if (!zero)
6778      stacksize++;      stacksize++;
6779    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6780        stacksize++;
6781      if (offset == 0)
6782      stacksize++;      stacksize++;
6783    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6784    
6785    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6786    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);
6787    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6788    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);
6789      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6790    
6791    stack = 0;    stack = 0;
6792    if (!zero)    if (!zero)
6793      {      {
6794      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6795        stack = 1;
6796        }
6797      if (needs_control_head)
6798        {
6799        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6800      stack++;      stack++;
6801      }      }
6802    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6803      {      {
6804      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6805      stack++;      stack++;
6806      }      }
6807    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6808    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6809      stack -= 1 + (offset == 0);
6810    }    }
6811    
6812  if (offset != 0)  if (offset != 0)
# Line 6405  while (*cc != OP_KETRPOS) Line 6882  while (*cc != OP_KETRPOS)
6882          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6883        }        }
6884      }      }
6885    
6886      if (needs_control_head)
6887        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6888    
6889    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6890    flush_stubs(common);    flush_stubs(common);
6891    
# Line 6441  while (*cc != OP_KETRPOS) Line 6922  while (*cc != OP_KETRPOS)
6922    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6923    }    }
6924    
6925    /* We don't have to restore the control head in case of a failed match. */
6926    
6927  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6928  if (!zero)  if (!zero)
6929    {    {
# Line 6829  if (!optimized_cbracket) Line 7312  if (!optimized_cbracket)
7312  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7313  }  }
7314    
7315    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7316    {
7317    DEFINE_COMPILER;
7318    backtrack_common *backtrack;
7319    pcre_uchar opcode = *cc;
7320    pcre_uchar *ccend = cc + 1;
7321    
7322    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7323      ccend += 2 + cc[1];
7324    
7325    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7326    
7327    if (opcode == OP_SKIP)
7328      {
7329      allocate_stack(common, 1);
7330      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7331      return ccend;
7332      }
7333    
7334    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7335      {
7336      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7337      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7338      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7339      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7340      }
7341    
7342    return ccend;
7343    }
7344    
7345    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7346    
7347    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7348    {
7349    DEFINE_COMPILER;
7350    backtrack_common *backtrack;
7351    BOOL needs_control_head;
7352    int size;
7353    
7354    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7355    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7356    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7357    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7358    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7359    
7360    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7361    size = 3 + (size < 0 ? 0 : size);
7362    
7363    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7364    allocate_stack(common, size);
7365    if (size > 3)
7366      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7367    else
7368      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7369    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7370    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7371    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7372    
7373    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7374    if (size >= 0)
7375      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7376    }
7377    
7378  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)
7379  {  {
7380  DEFINE_COMPILER;  DEFINE_COMPILER;
7381  backtrack_common *backtrack;  backtrack_common *backtrack;
7382    BOOL has_then_trap = FALSE;
7383    then_trap_backtrack *save_then_trap = NULL;
7384    
7385    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7386    
7387    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7388      {
7389      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7390      has_then_trap = TRUE;
7391      save_then_trap = common->then_trap;
7392      /* Tail item on backtrack. */
7393      compile_then_trap_matchingpath(common, cc, ccend, parent);
7394      }
7395    
7396  while (cc < ccend)  while (cc < ccend)
7397    {    {
# Line 7049  while (cc < ccend) Line 7608  while (cc < ccend)
7608      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7609      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7610      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);
7611      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7612      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7613      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(common->has_skip_arg ? 4 : 0), TMP2, 0);
7614      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7615      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);
7616      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);
7617        if (common->has_skip_arg)
7618          {
7619          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7620          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7621          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7622          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7623          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7624          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7625          }
7626      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7627      break;      break;
7628    
7629        case OP_PRUNE:
7630        case OP_PRUNE_ARG:
7631        case OP_SKIP:
7632        case OP_SKIP_ARG:
7633        case OP_THEN:
7634        case OP_THEN_ARG:
7635      case OP_COMMIT:      case OP_COMMIT:
7636      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7637      break;      break;
7638    
7639      case OP_FAIL:      case OP_FAIL:
# Line 7084  while (cc < ccend) Line 7657  while (cc < ccend)
7657    if (cc == NULL)    if (cc == NULL)
7658      return;      return;
7659    }    }
7660    
7661    if (has_then_trap)
7662      {
7663      /* Head item on backtrack. */
7664      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7665      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7666      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7667      common->then_trap = save_then_trap;
7668      }
7669  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7670  }  }
7671    
# Line 7245  switch(opcode) Line 7827  switch(opcode)
7827    }    }
7828  }  }
7829    
7830  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)
7831  {  {
7832  DEFINE_COMPILER;  DEFINE_COMPILER;
7833  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7267  set_jumps(current->topbacktracks, LABEL( Line 7849  set_jumps(current->topbacktracks, LABEL(
7849  free_stack(common, 2);  free_stack(common, 2);
7850  }  }
7851    
7852  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)
7853  {  {
7854  DEFINE_COMPILER;  DEFINE_COMPILER;
7855    
# Line 7363  if (bra == OP_BRAZERO) Line 7945  if (bra == OP_BRAZERO)
7945  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7946  {  {
7947  DEFINE_COMPILER;  DEFINE_COMPILER;
7948  int opcode;  int opcode, stacksize, count;
7949  int offset = 0;  int offset = 0;
7950  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7951  int stacksize;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
 int count;  
7952  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
7953  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
7954  pcre_uchar *ccprev;  pcre_uchar *ccprev;
# Line 7377  pcre_uchar bra = OP_BRA; Line 7958  pcre_uchar bra = OP_BRA;
7958  pcre_uchar ket;  pcre_uchar ket;
7959  assert_backtrack *assert;  assert_backtrack *assert;
7960  BOOL has_alternatives;  BOOL has_alternatives;
7961    BOOL needs_control_head = FALSE;
7962  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7963  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7964  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
7965  struct sljit_label *rminlabel = NULL;  struct sljit_label *rminlabel = NULL;
7966    struct sljit_label *exact_label = NULL;
7967    
7968  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
7969    {    {
# Line 7389  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 7972  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
7972    }    }
7973    
7974  opcode = *cc;  opcode = *cc;
7975    ccbegin = bracketend(cc) - 1 - LINK_SIZE;
7976    ket = *ccbegin;
7977    if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
7978      {
7979      repeat_ptr = PRIVATE_DATA(ccbegin);
7980      repeat_type = PRIVATE_DATA(ccbegin + 2);
7981      repeat_count = PRIVATE_DATA(ccbegin + 3);
7982      SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
7983      if (repeat_type == OP_UPTO)
7984        ket = OP_KETRMAX;
7985      if (repeat_type == OP_MINUPTO)
7986        ket = OP_KETRMIN;
7987      }
7988  ccbegin = cc;  ccbegin = cc;
 ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  
7989  cc += GET(cc, 1);  cc += GET(cc, 1);
7990  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
7991  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
# Line 7402  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7997  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7997  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7998    opcode = OP_ONCE;    opcode = OP_ONCE;
7999    
8000    /* Decoding the needs_control_head in framesize. */
8001    if (opcode == OP_ONCE)
8002      {
8003      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
8004      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
8005      }
8006    
8007    if (ket != OP_KET && repeat_type != 0)
8008      {
8009      /* TMP1 is used in OP_KETRMIN below. */
8010      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8011      free_stack(common, 1);
8012      if (repeat_type == OP_UPTO)
8013        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
8014      else
8015        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8016      }
8017    
8018  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
8019    {    {
8020    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7416  else if (ket == OP_KETRMIN) Line 8029  else if (ket == OP_KETRMIN)
8029    if (bra != OP_BRAMINZERO)    if (bra != OP_BRAMINZERO)
8030      {      {
8031      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8032      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (repeat_type != 0)
8033          {
8034          /* TMP1 was set a few lines above. */
8035          CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8036          /* Drop STR_PTR for non-greedy plus quantifier. */
8037          if (opcode != OP_ONCE)
8038            free_stack(common, 1);
8039          }
8040        else if (opcode >= OP_SBRA || opcode == OP_ONCE)
8041        {        {
8042        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
8043        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 7426  else if (ket == OP_KETRMIN) Line 8047  else if (ket == OP_KETRMIN)
8047          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);
8048          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);
8049          }          }
8050          /* Drop STR_PTR for non-greedy plus quantifier. */
8051        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
8052          free_stack(common, 1);          free_stack(common, 1);
8053        }        }
# Line 7433  else if (ket == OP_KETRMIN) Line 8055  else if (ket == OP_KETRMIN)
8055        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8056      }      }
8057    rminlabel = LABEL();    rminlabel = LABEL();
8058      if (repeat_type != 0)
8059        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8060    }    }
8061  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
8062    {    {
# Line 7440  else if (bra == OP_BRAZERO) Line 8064  else if (bra == OP_BRAZERO)
8064    free_stack(common, 1);    free_stack(common, 1);
8065    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
8066    }    }
8067    else if (repeat_type == OP_EXACT)
8068      {
8069      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8070      exact_label = LABEL();
8071      }
8072    
8073  if (offset != 0)  if (offset != 0)
8074    {    {
# Line 7559  if (has_alternatives) Line 8188  if (has_alternatives)
8188      current->top = NULL;      current->top = NULL;
8189      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8190      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8191        /* Conditional blocks always have an additional alternative, even if it is empty. */
8192      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8193        {        {
8194        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8195        cc += GET(cc, 1);        cc += GET(cc, 1);
8196        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8197          {          {
8198          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8199            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8200              if (private_data_ptr != 0)
8201                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8202              else
8203                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8204              }
8205          else          else
8206            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));
8207          }          }
8208        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8209        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7578  if (has_alternatives) Line 8213  if (has_alternatives)
8213      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8214      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8215      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8216        {        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));  
           }  
         }  
       }  
8217    
8218      stacksize = 0;      stacksize = 0;
8219        if (repeat_type == OP_MINUPTO)
8220          {
8221          /* We need to preserve the counter. TMP2 will be used below. */
8222          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
8223          stacksize++;
8224          }
8225      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8226        stacksize++;        stacksize++;
8227      if (offset != 0)      if (offset != 0)
# Line 7615  if (has_alternatives) Line 8234  if (has_alternatives)
8234      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8235        stacksize++;        stacksize++;
8236    
8237      if (stacksize > 0) {      if (stacksize > 0)
8238        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));  
         }  
     }  
8239    
8240      stacksize = 0;      stacksize = 0;
8241        if (repeat_type == OP_MINUPTO)
8242          {
8243          /* TMP2 was set above. */
8244          OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
8245          stacksize++;
8246          }
8247    
8248      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8249        {        {
8250        if (ket != OP_KET)        if (ket != OP_KET)
# Line 7637  if (has_alternatives) Line 8255  if (has_alternatives)
8255        }        }
8256    
8257      if (offset != 0)      if (offset != 0)
8258        {        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;  
         }  
       }  
8259    
8260      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8261        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 7690  if (has_alternatives) Line 8289  if (has_alternatives)
8289      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8290      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8291      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)
   
8292        {        {
8293        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);
8294        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7730  else if (opcode == OP_SBRA || opcode == Line 8328  else if (opcode == OP_SBRA || opcode ==
8328  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8329    {    {
8330    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8331      stacksize = needs_control_head ? 1 : 0;
8332    
8333    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8334      {      {
8335      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8336      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);  
8337      }      }
8338    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8339      {      {
8340      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8341      free_stack(common, 1);      stacksize++;
8342      }      }
8343      free_stack(common, stacksize);
8344    
8345    JUMPHERE(once);    JUMPHERE(once);
8346    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7755  else if (opcode == OP_ONCE) Line 8355  else if (opcode == OP_ONCE)
8355      }      }
8356    }    }
8357    
8358  if (ket == OP_KETRMAX)  if (repeat_type == OP_EXACT)
8359      {
8360      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8361      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8362      CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
8363      }
8364    else if (ket == OP_KETRMAX)
8365    {    {
8366    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8367    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
8368      free_stack(common, 1);      free_stack(common, 1);
8369    
8370    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);
8371    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
8372      {      {
# Line 7792  else if (bra == OP_BRAZERO) Line 8399  else if (bra == OP_BRAZERO)
8399    }    }
8400  }  }
8401    
8402  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)
8403  {  {
8404  DEFINE_COMPILER;  DEFINE_COMPILER;
8405  int offset;  int offset;
# Line 7831  if (current->topbacktracks) Line 8438  if (current->topbacktracks)
8438  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));
8439  }  }
8440    
8441  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)
8442  {  {
8443  assert_backtrack backtrack;  assert_backtrack backtrack;
8444    
# Line 7855  else Line 8462  else
8462  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8463  }  }
8464    
8465    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8466    {
8467    DEFINE_COMPILER;
8468    pcre_uchar opcode = *current->cc;
8469    struct sljit_label *loop;
8470    struct sljit_jump *jump;
8471    
8472    if (opcode == OP_THEN || opcode == OP_THEN_ARG)
8473      {
8474      if (common->then_trap != NULL)
8475        {
8476        SLJIT_ASSERT(common->control_head_ptr != 0);
8477    
8478        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8479        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8480        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8481        jump = JUMP(SLJIT_JUMP);
8482    
8483        loop = LABEL();
8484        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8485        JUMPHERE(jump);
8486        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8487        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8488        add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8489        return;
8490        }
8491      else if (common->positive_assert)
8492        {
8493        add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
8494        return;
8495        }
8496      }
8497    
8498    if (common->local_exit)
8499      {
8500      if (common->quit_label == NULL)
8501        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8502      else
8503        JUMPTO(SLJIT_JUMP, common->quit_label);
8504      return;
8505      }
8506    
8507    if (opcode == OP_SKIP_ARG)
8508      {
8509      SLJIT_ASSERT(common->control_head_ptr != 0);
8510      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8511      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8512      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8513      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8514      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8515    
8516      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8517      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8518      return;
8519      }
8520    
8521    if (opcode == OP_SKIP)
8522      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8523    else
8524      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8525    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8526    }
8527    
8528    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8529    {
8530    DEFINE_COMPILER;
8531    struct sljit_jump *jump;
8532    int size;
8533    
8534    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8535      {
8536      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8537      return;
8538      }
8539    
8540    size = CURRENT_AS(then_trap_backtrack)->framesize;
8541    size = 3 + (size < 0 ? 0 : size);
8542    
8543    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8544    free_stack(common, size);
8545    jump = JUMP(SLJIT_JUMP);
8546    
8547    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8548    /* STACK_TOP is set by THEN. */
8549    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8550      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8551    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8552    free_stack(common, 3);
8553    
8554    JUMPHERE(jump);
8555    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8556    }
8557    
8558  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8559  {  {
8560  DEFINE_COMPILER;  DEFINE_COMPILER;
8561    then_trap_backtrack *save_then_trap = common->then_trap;
8562    
8563  while (current)  while (current)
8564    {    {
# Line 7991  while (current) Line 8692  while (current)
8692      break;      break;
8693    
8694      case OP_MARK:      case OP_MARK:
8695      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));
8696      free_stack(common, 1);      if (common->has_skip_arg)
8697          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8698        free_stack(common, common->has_skip_arg ? 5 : 1);
8699      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);
8700        if (common->has_skip_arg)
8701          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8702        break;
8703    
8704        case OP_THEN:
8705        case OP_THEN_ARG:
8706        case OP_PRUNE:
8707        case OP_PRUNE_ARG:
8708        case OP_SKIP:
8709        case OP_SKIP_ARG:
8710        compile_control_verb_backtrackingpath(common, current);
8711      break;      break;
8712    
8713      case OP_COMMIT:      case OP_COMMIT:
8714      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8715          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8716      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8717        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8718      else      else
# Line 8011  while (current) Line 8726  while (current)
8726      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8727      break;      break;
8728    
8729        case OP_THEN_TRAP:
8730        /* A virtual opcode for then traps. */
8731        compile_then_trap_backtrackingpath(common, current);
8732        break;
8733    
8734      default:      default:
8735      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8736      break;      break;
8737      }      }
8738    current = current->prev;    current = current->prev;
8739    }    }
8740    common->then_trap = save_then_trap;
8741  }  }
8742    
8743  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 8025  DEFINE_COMPILER; Line 8746  DEFINE_COMPILER;
8746  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8747  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);
8748  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8749  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8750  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8751    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8752  int alternativesize;  int alternativesize;
8753  BOOL needsframe;  BOOL needs_frame;
8754  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quit_label = common->quit_label;  
 jump_list *save_quit = common->quit;  
8755  struct sljit_jump *jump;  struct sljit_jump *jump;
8756    
8757    /* Recurse captures then. */
8758    common->then_trap = NULL;
8759    
8760  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);
8761  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8762  if (!needsframe)  if (!needs_frame)
8763    framesize = 0;    framesize = 0;
8764  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8765    
# Line 8047  set_jumps(common->currententry->calls, c Line 8770  set_jumps(common->currententry->calls, c
8770  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8771  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8772  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);
8773  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);
8774    if (needs_control_head)
8775      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8776  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);
8777  if (needsframe)  if (needs_frame)
8778    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8779    
8780  if (alternativesize > 0)  if (alternativesize > 0)
8781    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 8072  while (1) Line 8797  while (1)
8797    
8798    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8799    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quit_label = save_quit_label;  
     common->quit = save_quit;  
8800      return;      return;
     }  
8801    
8802    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8803    
8804    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8805    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quit_label = save_quit_label;  
     common->quit = save_quit;  
8806      return;      return;
     }  
8807    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8808    
8809    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 8095  while (1) Line 8812  while (1)
8812    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8813    cc += GET(cc, 1);    cc += GET(cc, 1);
8814    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8815    
8816    /* None of them matched. */
8817  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8818  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8819    
8820    if (common->quit != NULL)
8821      {
8822      set_jumps(common->quit, LABEL());
8823      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8824      if (needs_frame)
8825        {
8826        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8827        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8828        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8829        }
8830      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8831      common->quit = NULL;
8832      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8833      }
8834    
8835  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8836  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);
8837  if (needsframe)  if (needs_frame)
8838    {    {
8839    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));
8840    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 8113  if (needsframe) Line 8843  if (needsframe)
8843  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8844    
8845  JUMPHERE(jump);  JUMPHERE(jump);
8846  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8847      set_jumps(common->quit, LABEL());
8848    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8849  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8850  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8851  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8852  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));
8853      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8854      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8855      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8856      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8857      }
8858    else
8859      {
8860      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8861      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8862      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8863      }
8864  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
   
 common->quit_label = save_quit_label;  
 common->quit = save_quit;  
8865  }  }
8866    
8867  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 8141  pcre_uchar *ccend; Line 8881  pcre_uchar *ccend;
8881  executable_functions *functions;  executable_functions *functions;
8882  void *executable_func;  void *executable_func;
8883  sljit_uw executable_size;  sljit_uw executable_size;
8884  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8885  struct sljit_label *empty_match_found;  struct sljit_label *continue_match_label;
8886  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_found_label;
8887    struct sljit_label *empty_match_backtrack_label;
8888    struct sljit_label *reset_match_label;
8889  struct sljit_jump *jump;  struct sljit_jump *jump;
8890  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
8891  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8892  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8893    struct sljit_label *quit_label;
8894    
8895  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8896  study = extra->study_data;  study = extra->study_data;
# Line 8227  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA Line 8970  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA
8970  common->capture_last_ptr = common->ovector_start;  common->capture_last_ptr = common->ovector_start;
8971  common->ovector_start += sizeof(sljit_sw);  common->ovector_start += sizeof(sljit_sw);
8972  #endif  #endif
8973  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  if (!check_opcode_types(common, rootbacktrack.cc, ccend))
 if (private_data_size < 0)  
8974    {    {
8975    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8976    return;    return;
# Line 8243  if (mode == JIT_COMPILE && (re->flags & Line 8985  if (mode == JIT_COMPILE && (re->flags &
8985  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8986    {    {
8987    common->start_used_ptr = common->ovector_start;    common->start_used_ptr = common->ovector_start;
8988    common->ovector_start += 2 * sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8989    if (mode == JIT_PARTIAL_SOFT_COMPILE)    if (mode == JIT_PARTIAL_SOFT_COMPILE)
8990      {      {
8991      common->hit_start = common->ovector_start;      common->hit_start = common->ovector_start;
8992      common->ovector_start += sizeof(sljit_sw);      common->ovector_start += 2 * sizeof(sljit_sw);
8993        }
8994      else
8995        {
8996        SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
8997        common->needs_start_ptr = TRUE;
8998      }      }
8999    }    }
9000  if ((re->options & PCRE_FIRSTLINE) != 0)  if ((re->options & PCRE_FIRSTLINE) != 0)
# Line 8255  if ((re->options & PCRE_FIRSTLINE) != 0) Line 9002  if ((re->options & PCRE_FIRSTLINE) != 0)
9002    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
9003    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
9004    }    }
9005    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
9006    common->control_head_ptr = 1;
9007    #endif
9008    if (common->control_head_ptr != 0)
9009      {
9010      common->control_head_ptr = common->ovector_start;
9011      common->ovector_start += sizeof(sljit_sw);
9012      }
9013    if (common->needs_start_ptr && common->has_set_som)
9014      {
9015      /* Saving the real start pointer is necessary. */
9016      common->start_ptr = common->ovector_start;
9017      common->ovector_start += sizeof(sljit_sw);
9018      }
9019    else
9020      common->needs_start_ptr = FALSE;
9021    
9022  /* Aligning ovector to even number of sljit words. */  /* Aligning ovector to even number of sljit words. */
9023  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
9024    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
9025    
9026    if (common->start_ptr == 0)
9027      common->start_ptr = OVECTOR(0);
9028    
9029  /* Capturing brackets cannot be optimized if callouts are allowed. */  /* Capturing brackets cannot be optimized if callouts are allowed. */
9030  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9031    memset(common->optimized_cbracket, 0, re->top_bracket + 1);    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
9032    
9033  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
9034  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
9035  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);  
9036  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(sljit_si));
9037    if (!common->private_data_ptrs)
9038    {    {
9039    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9040    return;    return;
9041    }    }
9042  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
9043  if (!common->private_data_ptrs)  
9044    private_data_size = common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
9045    set_private_data_ptrs(common, &private_data_size, ccend);
9046    if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
9047    {    {
9048      SLJIT_FREE(common->private_data_ptrs);
9049    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9050    return;    return;
9051    }    }
9052  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  
9053  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  if (common->has_then)
9054      {
9055      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
9056      if (!common->then_offsets)
9057        {
9058        SLJIT_FREE(common->optimized_cbracket);
9059        SLJIT_FREE(common->private_data_ptrs);
9060        return;
9061        }
9062      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
9063      set_then_offsets(common, rootbacktrack.cc, NULL);
9064      }
9065    
9066  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
9067  if (!compiler)  if (!compiler)
9068    {    {
9069    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9070    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9071      if (common->has_then)
9072        SLJIT_FREE(common->then_offsets);
9073    return;    return;
9074    }    }
9075  common->compiler = compiler;  common->compiler = compiler;
# Line 8309  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM Line 9093  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM
9093  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
9094    
9095  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9096    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
9097    if (common->mark_ptr != 0)
9098      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
9099    if (common->control_head_ptr != 0)
9100      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
9101    
9102  /* Main part of the matching */  /* Main part of the matching */
9103  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9104    {    {
9105    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);
9106      continue_match_label = LABEL();
9107    /* Forward search if possible. */    /* Forward search if possible. */
9108    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
9109      {      {
# Line 8328  if ((re->options & PCRE_ANCHORED) == 0) Line 9117  if ((re->options & PCRE_ANCHORED) == 0)
9117        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);
9118      }      }
9119    }    }
9120    else
9121      continue_match_label = LABEL();
9122    
9123  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)
9124    {    {
9125    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 8341  if (common->req_char_ptr != 0) Line 9133  if (common->req_char_ptr != 0)
9133  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);
9134  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9135  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);  
9136  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9137    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);
9138    
9139    if (common->needs_start_ptr)
9140      {
9141      SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
9142      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
9143      }
9144    else
9145      SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
9146    
9147  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
9148  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9149    {    {
9150    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
9151    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
9152    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr + sizeof(sljit_sw), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
9153    JUMPHERE(jump);    JUMPHERE(jump);
9154    }    }
9155  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
   {  
9156    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr + sizeof(sljit_sw), STR_PTR, 0);  
   }  
9157    
9158  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);  compile_matchingpath(common, rootbacktrack.cc, ccend, &rootbacktrack);
9159  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 8365  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9161  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9161    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9162    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9163    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9164      if (common->has_then)
9165        SLJIT_FREE(common->then_offsets);
9166    return;    return;
9167    }    }
9168    
9169  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
9170  empty_match_found = LABEL();  empty_match_found_label = LABEL();
9171    
9172  common->accept_label = LABEL();  common->accept_label = LABEL();
9173  if (common->accept != NULL)  if (common->accept != NULL)
# Line 8393  if (mode != JIT_COMPILE) Line 9191  if (mode != JIT_COMPILE)
9191    return_with_partial_match(common, common->quit_label);    return_with_partial_match(common, common->quit_label);
9192    }    }
9193    
9194  empty_match_backtrack = LABEL();  empty_match_backtrack_label = LABEL();
9195  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
9196  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9197    {    {
9198    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9199    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9200    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9201      if (common->has_then)
9202        SLJIT_FREE(common->then_offsets);
9203    return;    return;
9204    }    }
9205    
9206  SLJIT_ASSERT(rootbacktrack.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
9207    reset_match_label = LABEL();
9208    
9209  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9210    {    {
9211    /* Update hit_start only in the first time. */    /* Update hit_start only in the first time. */
9212    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
9213    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
9214    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
9215    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
# Line 8421  if ((re->options & PCRE_ANCHORED) == 0 & Line 9222  if ((re->options & PCRE_ANCHORED) == 0 &
9222    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
9223    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
9224    }    }
9225  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
9226    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
9227    
9228  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9229    {    {
9230    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
9231      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
9232    else    else
9233      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
9234    }    }
9235    
9236  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8436  if (reqbyte_notfound != NULL) Line 9238  if (reqbyte_notfound != NULL)
9238    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
9239    
9240  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9241    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
9242    
9243  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
9244  JUMPTO(SLJIT_JUMP, common->quit_label);  JUMPTO(SLJIT_JUMP, common->quit_label);
# Line 8446  flush_stubs(common); Line 9248  flush_stubs(common);
9248  JUMPHERE(empty_match);  JUMPHERE(empty_match);
9249  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9250  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
9251  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
9252  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
9253  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
9254  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9255  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
9256  JUMPTO(SLJIT_JUMP, empty_match_backtrack);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9257    
9258  common->currententry = common->entries;  common->currententry = common->entries;
9259    common->local_exit = TRUE;
9260    quit_label = common->quit_label;
9261  while (common->currententry != NULL)  while (common->currententry != NULL)
9262    {    {
9263    /* Might add new entries. */    /* Might add new entries. */
# Line 8463  while (common->currententry != NULL) Line 9267  while (common->currententry != NULL)
9267      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9268      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9269      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9270        if (common->has_then)
9271          SLJIT_FREE(common->then_offsets);
9272      return;      return;
9273      }      }
9274    flush_stubs(common);    flush_stubs(common);
9275    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
9276    }    }
9277    common->local_exit = FALSE;
9278    common->quit_label = quit_label;
9279    
9280  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
9281  /* This is a (really) rare case. */  /* This is a (really) rare case. */
# Line 8535  if (common->caselesscmp != NULL) Line 9343  if (common->caselesscmp != NULL)
9343    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
9344    do_caselesscmp(common);    do_caselesscmp(common);
9345    }    }
9346    if (common->reset_match != NULL)
9347      {
9348      set_jumps(common->reset_match, LABEL());
9349      do_reset_match(common, (re->top_bracket + 1) * 2);
9350      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
9351      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
9352      JUMPTO(SLJIT_JUMP, reset_match_label);
9353      }
9354  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9355  #ifndef COMPILE_PCRE32  #ifndef COMPILE_PCRE32
9356  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
# Line 8561  if (common->getucd != NULL) Line 9377  if (common->getucd != NULL)
9377    
9378  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9379  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9380    if (common->has_then)
9381      SLJIT_FREE(common->then_offsets);
9382    
9383  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9384  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9385  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);

Legend:
Removed from v.1268  
changed lines
  Added in v.1306

  ViewVC Help
Powered by ViewVC 1.1.5