/[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 1269 by zherczeg, Mon Mar 4 10:47:12 2013 UTC revision 1377 by zherczeg, Sun Oct 13 20:44:30 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 165  typedef struct jit_arguments { Line 168  typedef struct jit_arguments {
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169    void *callout_data;    void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171      pcre_uint32 limit_match;
172    int real_offset_count;    int real_offset_count;
173    int offset_count;    int offset_count;
   int call_limit;  
174    pcre_uint8 notbol;    pcre_uint8 notbol;
175    pcre_uint8 noteol;    pcre_uint8 noteol;
176    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 179  typedef struct executable_functions { Line 182  typedef struct executable_functions {
182    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
183    void *userdata;    void *userdata;
184    pcre_uint32 top_bracket;    pcre_uint32 top_bracket;
185      pcre_uint32 limit_match;
186    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
187  } executable_functions;  } executable_functions;
188    
# Line 193  typedef struct stub_list { Line 197  typedef struct stub_list {
197    struct stub_list *next;    struct stub_list *next;
198  } stub_list;  } stub_list;
199    
200  enum frame_types { no_frame = -1, no_stack = -2 };  enum frame_types {
201      no_frame = -1,
202      no_stack = -2
203    };
204    
205    enum control_types {
206      type_mark = 0,
207      type_then_trap = 1
208    };
209    
210  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
211    
212  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
213  code generator. It is allocated by compile_matchingpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
214  the aguments for compile_backtrackingpath. Must be the first member  the arguments for compile_backtrackingpath. Must be the first member
215  of its descendants. */  of its descendants. */
216  typedef struct backtrack_common {  typedef struct backtrack_common {
217    /* Concatenation stack. */    /* Concatenation stack. */
# Line 215  typedef struct backtrack_common { Line 227  typedef struct backtrack_common {
227  typedef struct assert_backtrack {  typedef struct assert_backtrack {
228    backtrack_common common;    backtrack_common common;
229    jump_list *condfailed;    jump_list *condfailed;
230    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
231    int framesize;    int framesize;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int private_data_ptr;    int private_data_ptr;
# Line 236  typedef struct bracket_backtrack { Line 248  typedef struct bracket_backtrack {
248      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
249      jump_list *condfailed;      jump_list *condfailed;
250      assert_backtrack *assert;      assert_backtrack *assert;
251      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
252      int framesize;      int framesize;
253    } u;    } u;
254    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 271  typedef struct recurse_entry { Line 283  typedef struct recurse_entry {
283    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
284    jump_list *calls;    jump_list *calls;
285    /* Points to the starting opcode. */    /* Points to the starting opcode. */
286    int start;    sljit_sw start;
287  } recurse_entry;  } recurse_entry;
288    
289  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
# Line 279  typedef struct recurse_backtrack { Line 291  typedef struct recurse_backtrack {
291    BOOL inlined_pattern;    BOOL inlined_pattern;
292  } recurse_backtrack;  } recurse_backtrack;
293    
294    #define OP_THEN_TRAP OP_TABLE_LENGTH
295    
296    typedef struct then_trap_backtrack {
297      backtrack_common common;
298      /* If then_trap is not NULL, this structure contains the real
299      then_trap for the backtracking path. */
300      struct then_trap_backtrack *then_trap;
301      /* Points to the starting opcode. */
302      sljit_sw start;
303      /* Exit point for the then opcodes of this alternative. */
304      jump_list *quit;
305      /* Frame size of the current alternative. */
306      int framesize;
307    } then_trap_backtrack;
308    
309  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
310    
311  typedef struct compiler_common {  typedef struct compiler_common {
312      /* The sljit ceneric compiler. */
313    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
314      /* First byte code. */
315    pcre_uchar *start;    pcre_uchar *start;
   
316    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
317    int *private_data_ptrs;    sljit_si *private_data_ptrs;
318    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
319    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
320      /* Tells whether the starting offset is a target of then. */
321      pcre_uint8 *then_offsets;
322      /* Current position where a THEN must jump. */
323      then_trap_backtrack *then_trap;
324    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
325    int cbraptr;    int cbra_ptr;
326    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
327    int ovector_start;    int ovector_start;
328    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
329    int req_char_ptr;    int req_char_ptr;
# Line 305  typedef struct compiler_common { Line 337  typedef struct compiler_common {
337    int first_line_end;    int first_line_end;
338    /* Points to the marked string. */    /* Points to the marked string. */
339    int mark_ptr;    int mark_ptr;
340      /* Recursive control verb management chain. */
341      int control_head_ptr;
342    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
343    int capture_last_ptr;    int capture_last_ptr;
344      /* Points to the starting position of the current match. */
345      int start_ptr;
346    
347    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
348    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
349    sljit_sw lcc;    sljit_sw lcc;
350    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
351    int mode;    int mode;
352      /* \K is found in the pattern. */
353      BOOL has_set_som;
354      /* (*SKIP:arg) is found in the pattern. */
355      BOOL has_skip_arg;
356      /* (*THEN) is found in the pattern. */
357      BOOL has_then;
358      /* Needs to know the start position anytime. */
359      BOOL needs_start_ptr;
360      /* Currently in recurse or negative assert. */
361      BOOL local_exit;
362      /* Currently in a positive assert. */
363      BOOL positive_assert;
364    /* Newline control. */    /* Newline control. */
365    int nltype;    int nltype;
366    int newline;    int newline;
367    int bsr_nltype;    int bsr_nltype;
368    /* Dollar endonly. */    /* Dollar endonly. */
369    int endonly;    int endonly;
   BOOL has_set_som;  
370    /* Tables. */    /* Tables. */
371    sljit_sw ctypes;    sljit_sw ctypes;
372    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
373    /* Named capturing brackets. */    /* Named capturing brackets. */
374    sljit_uw name_table;    pcre_uchar *name_table;
375    sljit_sw name_count;    sljit_sw name_count;
376    sljit_sw name_entry_size;    sljit_sw name_entry_size;
377    
# Line 338  typedef struct compiler_common { Line 385  typedef struct compiler_common {
385    recurse_entry *currententry;    recurse_entry *currententry;
386    jump_list *partialmatch;    jump_list *partialmatch;
387    jump_list *quit;    jump_list *quit;
388      jump_list *positive_assert_quit;
389    jump_list *forced_quit;    jump_list *forced_quit;
390    jump_list *accept;    jump_list *accept;
391    jump_list *calllimit;    jump_list *calllimit;
# Line 349  typedef struct compiler_common { Line 397  typedef struct compiler_common {
397    jump_list *vspace;    jump_list *vspace;
398    jump_list *casefulcmp;    jump_list *casefulcmp;
399    jump_list *caselesscmp;    jump_list *caselesscmp;
400      jump_list *reset_match;
401    BOOL jscript_compat;    BOOL jscript_compat;
402  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
403    BOOL utf;    BOOL utf;
# Line 415  typedef struct compare_context { Line 464  typedef struct compare_context {
464  #define STACK_TOP     SLJIT_SCRATCH_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
465  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
466  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
467  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define COUNT_MATCH   SLJIT_SAVED_EREG2
468  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
469    
470  /* Local space layout. */  /* Local space layout. */
# Line 426  typedef struct compare_context { Line 475  typedef struct compare_context {
475  #define POSSESSIVE0      (2 * sizeof(sljit_sw))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
476  #define POSSESSIVE1      (3 * sizeof(sljit_sw))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
477  /* Max limit of recursions. */  /* Max limit of recursions. */
478  #define CALL_LIMIT       (4 * sizeof(sljit_sw))  #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
479  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
480  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
481  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
482  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
483  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
484  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
485  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
486  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
487    
488  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 486  return cc; Line 535  return cc;
535    
536  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
537   next_opcode   next_opcode
538   get_private_data_length   check_opcode_types
539   set_private_data_ptrs   set_private_data_ptrs
540   get_framesize   get_framesize
541   init_frame   init_frame
542   get_private_data_length_for_copy   get_private_data_copy_length
543   copy_private_data   copy_private_data
544   compile_matchingpath   compile_matchingpath
545   compile_backtrackingpath   compile_backtrackingpath
# Line 540  switch(*cc) Line 589  switch(*cc)
589    case OP_NCLASS:    case OP_NCLASS:
590    case OP_REF:    case OP_REF:
591    case OP_REFI:    case OP_REFI:
592      case OP_DNREF:
593      case OP_DNREFI:
594    case OP_RECURSE:    case OP_RECURSE:
595    case OP_CALLOUT:    case OP_CALLOUT:
596    case OP_ALT:    case OP_ALT:
# Line 565  switch(*cc) Line 616  switch(*cc)
616    case OP_SCBRAPOS:    case OP_SCBRAPOS:
617    case OP_SCOND:    case OP_SCOND:
618    case OP_CREF:    case OP_CREF:
619    case OP_NCREF:    case OP_DNCREF:
620    case OP_RREF:    case OP_RREF:
621    case OP_NRREF:    case OP_DNRREF:
622    case OP_DEF:    case OP_DEF:
623    case OP_BRAZERO:    case OP_BRAZERO:
624    case OP_BRAMINZERO:    case OP_BRAMINZERO:
625    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
626      case OP_PRUNE:
627      case OP_SKIP:
628      case OP_THEN:
629    case OP_COMMIT:    case OP_COMMIT:
630    case OP_FAIL:    case OP_FAIL:
631    case OP_ACCEPT:    case OP_ACCEPT:
# Line 670  switch(*cc) Line 724  switch(*cc)
724  #endif  #endif
725    
726    case OP_MARK:    case OP_MARK:
727      case OP_PRUNE_ARG:
728      case OP_SKIP_ARG:
729      case OP_THEN_ARG:
730    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
731    
732    default:    default:
733      /* All opcodes are supported now! */
734      SLJIT_ASSERT_STOP();
735    return NULL;    return NULL;
736    }    }
737  }  }
738    
739  #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)  
740  {  {
741  switch(*cc)  int count;
742    {  pcre_uchar *slot;
   case OP_CRSTAR:  
   case OP_CRPLUS:  
   return 2;  
   
   case OP_CRMINSTAR:  
   case OP_CRMINPLUS:  
   case OP_CRQUERY:  
   case OP_CRMINQUERY:  
   return 1;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))  
     return 0;  
   return 2;  
   
   default:  
   return 0;  
   }  
 }  
   
 static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  
 {  
 int private_data_length = 0;  
 pcre_uchar *alternative;  
 pcre_uchar *name;  
 pcre_uchar *end = NULL;  
 int space, size, i;  
 pcre_uint32 bracketlen;  
743    
744  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
745  while (cc < ccend)  while (cc < ccend)
746    {    {
   space = 0;  
   size = 0;  
   bracketlen = 0;  
747    switch(*cc)    switch(*cc)
748      {      {
749      case OP_SET_SOM:      case OP_SET_SOM:
# Line 782  while (cc < ccend) Line 757  while (cc < ccend)
757      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
758      break;      break;
759    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     case OP_ONCE_NC:  
     case OP_BRAPOS:  
     case OP_SBRA:  
     case OP_SBRAPOS:  
     private_data_length += sizeof(sljit_sw);  
     bracketlen = 1 + LINK_SIZE;  
     break;  
   
760      case OP_CBRAPOS:      case OP_CBRAPOS:
761      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     private_data_length += sizeof(sljit_sw);  
762      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
763      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
764      break;      break;
765    
766      case OP_COND:      case OP_COND:
# Line 807  while (cc < ccend) Line 768  while (cc < ccend)
768      /* Only AUTO_CALLOUT can insert this opcode. We do      /* Only AUTO_CALLOUT can insert this opcode. We do
769         not intend to support this case. */         not intend to support this case. */
770      if (cc[1 + LINK_SIZE] == OP_CALLOUT)      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
771        return -1;        return FALSE;
772        cc += 1 + LINK_SIZE;
     if (*cc == OP_COND)  
       {  
       /* Might be a hidden SCOND. */  
       alternative = cc + GET(cc, 1);  
       if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)  
         private_data_length += sizeof(sljit_sw);  
       }  
     else  
       private_data_length += sizeof(sljit_sw);  
     bracketlen = 1 + LINK_SIZE;  
773      break;      break;
774    
775      case OP_CREF:      case OP_CREF:
776      i = GET2(cc, 1);      common->optimized_cbracket[GET2(cc, 1)] = 0;
     common->optimized_cbracket[i] = 0;  
777      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
778      break;      break;
779    
780      case OP_NCREF:      case OP_DNREF:
781      bracketlen = GET2(cc, 1);      case OP_DNREFI:
782      name = (pcre_uchar *)common->name_table;      case OP_DNCREF:
783      alternative = name;      count = GET2(cc, 1 + IMM2_SIZE);
784      for (i = 0; i < common->name_count; i++)      slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
785        while (count-- > 0)
786        {        {
787        if (GET2(name, 0) == bracketlen) break;        common->optimized_cbracket[GET2(slot, 0)] = 0;
788        name += common->name_entry_size;        slot += common->name_entry_size;
789        }        }
790      SLJIT_ASSERT(i != common->name_count);      cc += 1 + 2 * IMM2_SIZE;
   
     for (i = 0; i < common->name_count; i++)  
       {  
       if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)  
         common->optimized_cbracket[GET2(alternative, 0)] = 0;  
       alternative += common->name_entry_size;  
       }  
     bracketlen = 0;  
     cc += 1 + IMM2_SIZE;  
791      break;      break;
792    
     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  
   
793      case OP_RECURSE:      case OP_RECURSE:
794      /* Set its value only once. */      /* Set its value only once. */
795      if (common->recursive_head_ptr == 0)      if (common->recursive_head_ptr == 0)
# Line 921  while (cc < ccend) Line 809  while (cc < ccend)
809      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
810      break;      break;
811    
812        case OP_THEN_ARG:
813        common->has_then = TRUE;
814        common->control_head_ptr = 1;
815        /* Fall through. */
816    
817        case OP_PRUNE_ARG:
818        common->needs_start_ptr = TRUE;
819        /* Fall through. */
820    
821      case OP_MARK:      case OP_MARK:
822      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
823        {        {
# Line 930  while (cc < ccend) Line 827  while (cc < ccend)
827      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
828      break;      break;
829    
830        case OP_THEN:
831        common->has_then = TRUE;
832        common->control_head_ptr = 1;
833        /* Fall through. */
834    
835        case OP_PRUNE:
836        case OP_SKIP:
837        common->needs_start_ptr = TRUE;
838        cc += 1;
839        break;
840    
841        case OP_SKIP_ARG:
842        common->control_head_ptr = 1;
843        common->has_skip_arg = TRUE;
844        cc += 1 + 2 + cc[1];
845        break;
846    
847      default:      default:
848      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
849      if (cc == NULL)      if (cc == NULL)
850        return -1;        return FALSE;
851      break;      break;
852      }      }
853      }
854    return TRUE;
855    }
856    
857    if (space > 0 && cc >= end)  static int get_class_iterator_size(pcre_uchar *cc)
858      private_data_length += sizeof(sljit_sw) * space;  {
859    switch(*cc)
860      {
861      case OP_CRSTAR:
862      case OP_CRPLUS:
863      return 2;
864    
865    if (size != 0)    case OP_CRMINSTAR:
866      case OP_CRMINPLUS:
867      case OP_CRQUERY:
868      case OP_CRMINQUERY:
869      return 1;
870    
871      case OP_CRRANGE:
872      case OP_CRMINRANGE:
873      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
874        return 0;
875      return 2;
876    
877      default:
878      return 0;
879      }
880    }
881    
882    static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
883    {
884    pcre_uchar *end = bracketend(begin);
885    pcre_uchar *next;
886    pcre_uchar *next_end;
887    pcre_uchar *max_end;
888    pcre_uchar type;
889    sljit_sw length = end - begin;
890    int min, max, i;
891    
892    /* Detect fixed iterations first. */
893    if (end[-(1 + LINK_SIZE)] != OP_KET)
894      return FALSE;
895    
896    /* Already detected repeat. */
897    if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
898      return TRUE;
899    
900    next = end;
901    min = 1;
902    while (1)
903      {
904      if (*next != *begin)
905        break;
906      next_end = bracketend(next);
907      if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
908        break;
909      next = next_end;
910      min++;
911      }
912    
913    if (min == 2)
914      return FALSE;
915    
916    max = 0;
917    max_end = next;
918    if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
919      {
920      type = *next;
921      while (1)
922      {      {
923      if (size < 0)      if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
924        {        break;
925        cc += -size;      next_end = bracketend(next + 2 + LINK_SIZE);
926  #ifdef SUPPORT_UTF      if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
927        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);        break;
928  #endif      next = next_end;
929        }      max++;
     else  
       cc += size;  
930      }      }
931    
932    if (bracketlen != 0)    if (next[0] == type && next[1] == *begin && max >= 1)
933      {      {
934      if (cc >= end)      next_end = bracketend(next + 1);
935        if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
936        {        {
937        end = bracketend(cc);        for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
938        if (end[-1 - LINK_SIZE] == OP_KET)          if (*next_end != OP_KET)
939          end = NULL;            break;
940    
941          if (i == max)
942            {
943            common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
944            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
945            /* +2 the original and the last. */
946            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
947            if (min == 1)
948              return TRUE;
949            min--;
950            max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
951            }
952        }        }
     cc += bracketlen;  
953      }      }
954    }    }
955  return private_data_length;  
956    if (min >= 3)
957      {
958      common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
959      common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
960      common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
961      return TRUE;
962      }
963    
964    return FALSE;
965  }  }
966    
967  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
968        case OP_MINSTAR: \
969        case OP_MINPLUS: \
970        case OP_QUERY: \
971        case OP_MINQUERY: \
972        case OP_MINSTARI: \
973        case OP_MINPLUSI: \
974        case OP_QUERYI: \
975        case OP_MINQUERYI: \
976        case OP_NOTMINSTAR: \
977        case OP_NOTMINPLUS: \
978        case OP_NOTQUERY: \
979        case OP_NOTMINQUERY: \
980        case OP_NOTMINSTARI: \
981        case OP_NOTMINPLUSI: \
982        case OP_NOTQUERYI: \
983        case OP_NOTMINQUERYI:
984    
985    #define CASE_ITERATOR_PRIVATE_DATA_2A \
986        case OP_STAR: \
987        case OP_PLUS: \
988        case OP_STARI: \
989        case OP_PLUSI: \
990        case OP_NOTSTAR: \
991        case OP_NOTPLUS: \
992        case OP_NOTSTARI: \
993        case OP_NOTPLUSI:
994    
995    #define CASE_ITERATOR_PRIVATE_DATA_2B \
996        case OP_UPTO: \
997        case OP_MINUPTO: \
998        case OP_UPTOI: \
999        case OP_MINUPTOI: \
1000        case OP_NOTUPTO: \
1001        case OP_NOTMINUPTO: \
1002        case OP_NOTUPTOI: \
1003        case OP_NOTMINUPTOI:
1004    
1005    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1006        case OP_TYPEMINSTAR: \
1007        case OP_TYPEMINPLUS: \
1008        case OP_TYPEQUERY: \
1009        case OP_TYPEMINQUERY:
1010    
1011    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1012        case OP_TYPESTAR: \
1013        case OP_TYPEPLUS:
1014    
1015    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1016        case OP_TYPEUPTO: \
1017        case OP_TYPEMINUPTO:
1018    
1019    static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1020  {  {
1021  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1022  pcre_uchar *alternative;  pcre_uchar *alternative;
1023  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
1024    int private_data_ptr = *private_data_start;
1025  int space, size, bracketlen;  int space, size, bracketlen;
1026    
1027  while (cc < ccend)  while (cc < ccend)
# Line 979  while (cc < ccend) Line 1029  while (cc < ccend)
1029    space = 0;    space = 0;
1030    size = 0;    size = 0;
1031    bracketlen = 0;    bracketlen = 0;
1032      if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1033        return;
1034    
1035      if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
1036        if (detect_repeat(common, cc))
1037          {
1038          /* These brackets are converted to repeats, so no global
1039          based single character repeat is allowed. */
1040          if (cc >= end)
1041            end = bracketend(cc);
1042          }
1043    
1044    switch(*cc)    switch(*cc)
1045      {      {
1046        case OP_KET:
1047        if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1048          {
1049          common->private_data_ptrs[cc - common->start] = private_data_ptr;
1050          private_data_ptr += sizeof(sljit_sw);
1051          cc += common->private_data_ptrs[cc + 1 - common->start];
1052          }
1053        cc += 1 + LINK_SIZE;
1054        break;
1055    
1056      case OP_ASSERT:      case OP_ASSERT:
1057      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1058      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 1074  while (cc < ccend) Line 1146  while (cc < ccend)
1146      break;      break;
1147      }      }
1148    
1149      /* Character iterators, which are not inside a repeated bracket,
1150         gets a private slot instead of allocating it on the stack. */
1151    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1152      {      {
1153      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 1178  while (cc < ccend)
1178      cc += bracketlen;      cc += bracketlen;
1179      }      }
1180    }    }
1181    *private_data_start = private_data_ptr;
1182  }  }
1183    
1184  /* Returns with a frame_types (always < 0) if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1185  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)
1186  {  {
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1187  int length = 0;  int length = 0;
1188  int possessive = 0;  int possessive = 0;
1189  BOOL stack_restore = FALSE;  BOOL stack_restore = FALSE;
# Line 1118  BOOL setmark_found = recursive; Line 1192  BOOL setmark_found = recursive;
1192  /* The last capture is a local variable even for recursions. */  /* The last capture is a local variable even for recursions. */
1193  BOOL capture_last_found = FALSE;  BOOL capture_last_found = FALSE;
1194    
1195  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1196    SLJIT_ASSERT(common->control_head_ptr != 0);
1197    *needs_control_head = TRUE;
1198    #else
1199    *needs_control_head = FALSE;
1200    #endif
1201    
1202    if (ccend == NULL)
1203    {    {
1204    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1205    /* This is correct regardless of common->capture_last_ptr. */    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1206    capture_last_found = TRUE;      {
1207        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1208        /* This is correct regardless of common->capture_last_ptr. */
1209        capture_last_found = TRUE;
1210        }
1211      cc = next_opcode(common, cc);
1212    }    }
1213    
 cc = next_opcode(common, cc);  
1214  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1215  while (cc < ccend)  while (cc < ccend)
1216    switch(*cc)    switch(*cc)
# Line 1142  while (cc < ccend) Line 1227  while (cc < ccend)
1227      break;      break;
1228    
1229      case OP_MARK:      case OP_MARK:
1230        case OP_PRUNE_ARG:
1231        case OP_THEN_ARG:
1232      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1233      stack_restore = TRUE;      stack_restore = TRUE;
1234      if (!setmark_found)      if (!setmark_found)
# Line 1149  while (cc < ccend) Line 1236  while (cc < ccend)
1236        length += 2;        length += 2;
1237        setmark_found = TRUE;        setmark_found = TRUE;
1238        }        }
1239        if (common->control_head_ptr != 0)
1240          *needs_control_head = TRUE;
1241      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1242      break;      break;
1243    
# Line 1268  if (length > 0) Line 1357  if (length > 0)
1357  return stack_restore ? no_frame : no_stack;  return stack_restore ? no_frame : no_stack;
1358  }  }
1359    
1360  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)
1361  {  {
1362  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);  
1363  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1364  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1365  /* 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 1371  SLJIT_UNUSED_ARG(stacktop);
1371  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1372    
1373  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1374  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1375    cc = next_opcode(common, cc);    {
1376      ccend = bracketend(cc) - (1 + LINK_SIZE);
1377      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1378        cc = next_opcode(common, cc);
1379      }
1380    
1381  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1382  while (cc < ccend)  while (cc < ccend)
1383    switch(*cc)    switch(*cc)
# Line 1304  while (cc < ccend) Line 1397  while (cc < ccend)
1397      break;      break;
1398    
1399      case OP_MARK:      case OP_MARK:
1400        case OP_PRUNE_ARG:
1401        case OP_THEN_ARG:
1402      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1403      if (!setmark_found)      if (!setmark_found)
1404        {        {
# Line 1384  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1479  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1479  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1480  }  }
1481    
1482  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)
1483  {  {
1484  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1485  int size;  int size;
1486  pcre_uchar *alternative;  pcre_uchar *alternative;
1487  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1395  while (cc < ccend) Line 1490  while (cc < ccend)
1490    size = 0;    size = 0;
1491    switch(*cc)    switch(*cc)
1492      {      {
1493        case OP_KET:
1494        if (PRIVATE_DATA(cc) != 0)
1495          private_data_length++;
1496        cc += 1 + LINK_SIZE;
1497        break;
1498    
1499      case OP_ASSERT:      case OP_ASSERT:
1500      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1501      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# 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 1557  while (status != end) Line 1664  while (status != end)
1664    
1665      switch(*cc)      switch(*cc)
1666        {        {
1667          case OP_KET:
1668          if (PRIVATE_DATA(cc) != 0)
1669            {
1670            count = 1;
1671            srcw[0] = PRIVATE_DATA(cc);
1672            }
1673          cc += 1 + LINK_SIZE;
1674          break;
1675    
1676        case OP_ASSERT:        case OP_ASSERT:
1677        case OP_ASSERT_NOT:        case OP_ASSERT_NOT:
1678        case OP_ASSERTBACK:        case OP_ASSERTBACK:
# Line 1769  while (status != end) Line 1885  while (status != end)
1885        }        }
1886      }      }
1887    }    }
1888    while (status != end);
1889    
1890  if (save)  if (save)
1891    {    {
# Line 1802  if (save) Line 1919  if (save)
1919  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1920  }  }
1921    
1922    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1923    {
1924    pcre_uchar *end = bracketend(cc);
1925    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1926    
1927    /* Assert captures then. */
1928    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1929      current_offset = NULL;
1930    /* Conditional block does not. */
1931    if (*cc == OP_COND || *cc == OP_SCOND)
1932      has_alternatives = FALSE;
1933    
1934    cc = next_opcode(common, cc);
1935    if (has_alternatives)
1936      current_offset = common->then_offsets + (cc - common->start);
1937    
1938    while (cc < end)
1939      {
1940      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1941        cc = set_then_offsets(common, cc, current_offset);
1942      else
1943        {
1944        if (*cc == OP_ALT && has_alternatives)
1945          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1946        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1947          *current_offset = 1;
1948        cc = next_opcode(common, cc);
1949        }
1950      }
1951    
1952    return end;
1953    }
1954    
1955  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1956  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1957  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1865  while (list_item) Line 2015  while (list_item)
2015  common->stubs = NULL;  common->stubs = NULL;
2016  }  }
2017    
2018  static SLJIT_INLINE void decrease_call_count(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2019  {  {
2020  DEFINE_COMPILER;  DEFINE_COMPILER;
2021    
2022  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
2023  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
2024  }  }
2025    
# Line 1900  static SLJIT_INLINE void reset_ovector(c Line 2050  static SLJIT_INLINE void reset_ovector(c
2050  DEFINE_COMPILER;  DEFINE_COMPILER;
2051  struct sljit_label *loop;  struct sljit_label *loop;
2052  int i;  int i;
2053    
2054  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2055    SLJIT_ASSERT(length > 1);
2056  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2057  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));
2058  if (length < 8)  if (length < 8)
2059    {    {
2060    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2061      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);
2062    }    }
2063  else  else
2064    {    {
2065    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2066    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2067    loop = LABEL();    loop = LABEL();
2068    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);
2069    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 2071  else
2071    }    }
2072  }  }
2073    
2074    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2075    {
2076    DEFINE_COMPILER;
2077    struct sljit_label *loop;
2078    int i;
2079    
2080    SLJIT_ASSERT(length > 1);
2081    /* OVECTOR(1) contains the "string begin - 1" constant. */
2082    if (length > 2)
2083      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2084    if (length < 8)
2085      {
2086      for (i = 2; i < length; i++)
2087        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2088      }
2089    else
2090      {
2091      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2092      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2093      loop = LABEL();
2094      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2095      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2096      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2097      }
2098    
2099    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2100    if (common->mark_ptr != 0)
2101      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2102    if (common->control_head_ptr != 0)
2103      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2104    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2105    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2106    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2107    }
2108    
2109    static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2110    {
2111    while (current != NULL)
2112      {
2113      switch (current[-2])
2114        {
2115        case type_then_trap:
2116        break;
2117    
2118        case type_mark:
2119        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2120          return current[-4];
2121        break;
2122    
2123        default:
2124        SLJIT_ASSERT_STOP();
2125        break;
2126        }
2127      current = (sljit_sw*)current[-1];
2128      }
2129    return -1;
2130    }
2131    
2132  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2133  {  {
2134  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1975  DEFINE_COMPILER; Line 2185  DEFINE_COMPILER;
2185  struct sljit_jump *jump;  struct sljit_jump *jump;
2186    
2187  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);
2188  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
2189      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2190    
2191  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2192  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 2198  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJI
2198  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));
2199    
2200  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);
2201  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);
2202  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2203  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);
2204  #endif  #endif
# Line 2155  return (bit < 256) ? ((0 << 8) | bit) : Line 2366  return (bit < 256) ? ((0 << 8) | bit) :
2366    
2367  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
2368  {  {
2369  /* Checks whether a partial matching is occured. Does not modify registers. */  /* Checks whether a partial matching is occurred. Does not modify registers. */
2370  DEFINE_COMPILER;  DEFINE_COMPILER;
2371  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2372    
# Line 4098  while (*cc != XCL_END) Line 4309  while (*cc != XCL_END)
4309    
4310        case PT_SPACE:        case PT_SPACE:
4311        case PT_PXSPACE:        case PT_PXSPACE:
       if (*cc == PT_SPACE)  
         {  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
         jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 11 - charoffset);  
         }  
4312        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4313        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd - 0x9);
4314        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4315        if (*cc == PT_SPACE)  
4316          JUMPHERE(jump);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x9);
4317          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4318    
4319          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e - 0x9);
4320          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4321    
4322        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4323        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
# Line 4837  if (context.length > 0) Line 5047  if (context.length > 0)
5047  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
5048  }  }
5049    
 static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)  
 {  
 DEFINE_COMPILER;  
 int offset = GET2(cc, 1) << 1;  
   
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
 if (!common->jscript_compat)  
   {  
   if (backtracks == NULL)  
     {  
     /* OVECTOR(1) contains the "string begin - 1" constant. */  
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  
     OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);  
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);  
     return JUMP(SLJIT_C_NOT_ZERO);  
     }  
   add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));  
   }  
 return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
 }  
   
5050  /* Forward definitions. */  /* Forward definitions. */
5051  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
5052  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
# Line 4891  static void compile_backtrackingpath(com Line 5079  static void compile_backtrackingpath(com
5079    
5080  #define BACKTRACK_AS(type) ((type *)backtrack)  #define BACKTRACK_AS(type) ((type *)backtrack)
5081    
5082  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)  static void compile_dnref_search(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
5083    {
5084    /* The OVECTOR offset goes to TMP2. */
5085    DEFINE_COMPILER;
5086    int count = GET2(cc, 1 + IMM2_SIZE);
5087    pcre_uchar *slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
5088    unsigned int offset;
5089    jump_list *found = NULL;
5090    
5091    SLJIT_ASSERT(*cc == OP_DNREF || *cc == OP_DNREFI);
5092    
5093    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5094    
5095    count--;
5096    while (count-- > 0)
5097      {
5098      offset = GET2(slot, 0) << 1;
5099      GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5100      add_jump(compiler, &found, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5101      slot += common->name_entry_size;
5102      }
5103    
5104    offset = GET2(slot, 0) << 1;
5105    GET_LOCAL_BASE(TMP2, 0, OVECTOR(offset));
5106    if (backtracks != NULL && !common->jscript_compat)
5107      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0));
5108    
5109    set_jumps(found, LABEL());
5110    }
5111    
5112    static void compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
5113  {  {
5114  DEFINE_COMPILER;  DEFINE_COMPILER;
5115  int offset = GET2(cc, 1) << 1;  BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5116    int offset = 0;
5117  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5118  struct sljit_jump *partial;  struct sljit_jump *partial;
5119  struct sljit_jump *nopartial;  struct sljit_jump *nopartial;
5120    
5121  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  if (ref)
5122  /* OVECTOR(1) contains the "string begin - 1" constant. */    {
5123  if (withchecks && !common->jscript_compat)    offset = GET2(cc, 1) << 1;
5124    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5125      /* OVECTOR(1) contains the "string begin - 1" constant. */
5126      if (withchecks && !common->jscript_compat)
5127        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5128      }
5129    else
5130      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5131    
5132  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5133  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5134    {    {
5135    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);
5136    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    if (ref)
5137        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5138      else
5139        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5140    
5141    if (withchecks)    if (withchecks)
5142      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5143    
# Line 4933  if (common->utf && *cc == OP_REFI) Line 5162  if (common->utf && *cc == OP_REFI)
5162  else  else
5163  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
5164    {    {
5165    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    if (ref)
5166        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
5167      else
5168        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
5169    
5170    if (withchecks)    if (withchecks)
5171      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
5172    
# Line 4970  if (jump != NULL) Line 5203  if (jump != NULL)
5203    else    else
5204      JUMPHERE(jump);      JUMPHERE(jump);
5205    }    }
 return cc + 1 + IMM2_SIZE;  
5206  }  }
5207    
5208  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5209  {  {
5210  DEFINE_COMPILER;  DEFINE_COMPILER;
5211    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
5212  backtrack_common *backtrack;  backtrack_common *backtrack;
5213  pcre_uchar type;  pcre_uchar type;
5214    int offset = 0;
5215  struct sljit_label *label;  struct sljit_label *label;
5216  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
5217  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 4987  BOOL minimize; Line 5221  BOOL minimize;
5221    
5222  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
5223    
5224    if (ref)
5225      offset = GET2(cc, 1) << 1;
5226    else
5227      cc += IMM2_SIZE;
5228  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
5229    
5230    SLJIT_COMPILE_ASSERT((OP_CRSTAR & 0x1) == 0, crstar_opcode_must_be_even);
5231  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
5232  switch(type)  switch(type)
5233    {    {
# Line 5025  if (!minimize) Line 5265  if (!minimize)
5265    if (min == 0)    if (min == 0)
5266      {      {
5267      allocate_stack(common, 2);      allocate_stack(common, 2);
5268        if (ref)
5269          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5270      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5271      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5272      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
5273      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5274      zerolength = compile_ref_checks(common, ccbegin, NULL);      /* Handles both invalid and empty cases. Since the minimum repeat,
5275        is zero the invalid case is basically the same as an empty case. */
5276        if (ref)
5277          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5278        else
5279          {
5280          compile_dnref_search(common, ccbegin, NULL);
5281          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5282          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5283          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5284          }
5285      /* Restore if not zero length. */      /* Restore if not zero length. */
5286      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));
5287      }      }
5288    else    else
5289      {      {
5290      allocate_stack(common, 1);      allocate_stack(common, 1);
5291        if (ref)
5292          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5293      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5294      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);      if (ref)
5295          {
5296          add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5297          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5298          }
5299        else
5300          {
5301          compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5302          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5303          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, TMP2, 0);
5304          zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5305          }
5306      }      }
5307    
5308    if (min > 1 || max > 1)    if (min > 1 || max > 1)
5309      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
5310    
5311    label = LABEL();    label = LABEL();
5312      if (!ref)
5313        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5314    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
5315    
5316    if (min > 1 || max > 1)    if (min > 1 || max > 1)
# Line 5074  if (!minimize) Line 5341  if (!minimize)
5341    JUMPHERE(zerolength);    JUMPHERE(zerolength);
5342    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5343    
5344    decrease_call_count(common);    count_match(common);
5345    return cc;    return cc;
5346    }    }
5347    
5348  allocate_stack(common, 2);  allocate_stack(common, ref ? 2 : 3);
5349    if (ref)
5350      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5351  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5352  if (type != OP_CRMINSTAR)  if (type != OP_CRMINSTAR)
5353    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5354    
5355  if (min == 0)  if (min == 0)
5356    {    {
5357    zerolength = compile_ref_checks(common, ccbegin, NULL);    /* Handles both invalid and empty cases. Since the minimum repeat,
5358      is zero the invalid case is basically the same as an empty case. */
5359      if (ref)
5360        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5361      else
5362        {
5363        compile_dnref_search(common, ccbegin, NULL);
5364        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5365        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5366        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5367        }
5368      /* Length is non-zero, we can match real repeats. */
5369    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5370    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5371    }    }
5372  else  else
5373    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);    {
5374      if (ref)
5375        {
5376        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5377        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5378        }
5379      else
5380        {
5381        compile_dnref_search(common, ccbegin, &backtrack->topbacktracks);
5382        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), 0);
5383        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP2, 0);
5384        zerolength = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw));
5385        }
5386      }
5387    
5388  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
5389  if (max > 0)  if (max > 0)
5390    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
5391    
5392    if (!ref)
5393      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
5394  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
5395  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5396    
# Line 5113  if (jump != NULL) Line 5408  if (jump != NULL)
5408    JUMPHERE(jump);    JUMPHERE(jump);
5409  JUMPHERE(zerolength);  JUMPHERE(zerolength);
5410    
5411  decrease_call_count(common);  count_match(common);
5412  return cc;  return cc;
5413  }  }
5414    
# Line 5123  DEFINE_COMPILER; Line 5418  DEFINE_COMPILER;
5418  backtrack_common *backtrack;  backtrack_common *backtrack;
5419  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5420  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5421  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5422  pcre_uchar *start_cc;  pcre_uchar *start_cc;
5423    BOOL needs_control_head;
5424    
5425  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5426    
5427  /* Inlining simple patterns. */  /* Inlining simple patterns. */
5428  if (get_framesize(common, common->start + start, TRUE) == no_stack)  if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5429    {    {
5430    start_cc = common->start + start;    start_cc = common->start + start;
5431    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 5248  allocate_stack(common, CALLOUT_ARG_SIZE Line 5544  allocate_stack(common, CALLOUT_ARG_SIZE
5544  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);
5545  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5546  SLJIT_ASSERT(common->capture_last_ptr != 0);  SLJIT_ASSERT(common->capture_last_ptr != 0);
5547  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]);
5548  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);
5549    
5550  /* These pointer sized fields temporarly stores internal variables. */  /* These pointer sized fields temporarly stores internal variables. */
5551  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 5258  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA Line 5554  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA
5554    
5555  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
5556    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));
5557  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));
5558  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));
5559  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);
5560    
5561  /* Needed to save important temporary registers. */  /* Needed to save important temporary registers. */
# Line 5288  static pcre_uchar *compile_assert_matchi Line 5584  static pcre_uchar *compile_assert_matchi
5584  {  {
5585  DEFINE_COMPILER;  DEFINE_COMPILER;
5586  int framesize;  int framesize;
5587    int extrasize;
5588    BOOL needs_control_head;
5589  int private_data_ptr;  int private_data_ptr;
5590  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5591  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5297  jump_list *tmp = NULL; Line 5595  jump_list *tmp = NULL;
5595  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5596  jump_list **found;  jump_list **found;
5597  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5598    BOOL save_local_exit = common->local_exit;
5599    BOOL save_positive_assert = common->positive_assert;
5600    then_trap_backtrack *save_then_trap = common->then_trap;
5601  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5602  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5603  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5604    jump_list *save_positive_assert_quit = common->positive_assert_quit;
5605  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5606  struct sljit_jump *jump;  struct sljit_jump *jump;
5607  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5608    
5609    /* Assert captures then. */
5610    common->then_trap = NULL;
5611    
5612  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5613    {    {
5614    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5312  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5617  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5617    }    }
5618  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5619  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5620  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5621  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5622  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5623  opcode = *cc;  opcode = *cc;
# Line 5331  if (bra == OP_BRAMINZERO) Line 5636  if (bra == OP_BRAMINZERO)
5636    
5637  if (framesize < 0)  if (framesize < 0)
5638    {    {
5639    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5640    allocate_stack(common, 1);    if (framesize == no_frame)
5641        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5642      allocate_stack(common, extrasize);
5643      if (needs_control_head)
5644        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5645    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5646      if (needs_control_head)
5647        {
5648        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5649        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5650        }
5651    }    }
5652  else  else
5653    {    {
5654    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5655      allocate_stack(common, framesize + extrasize);
5656    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);
5657    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));
5658    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);
5659      if (needs_control_head)
5660        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5661    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5662    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5663    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5664        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5665        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5666        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5667        }
5668      else
5669        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5670      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5671    }    }
5672    
5673  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5674  common->quit_label = NULL;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5675  common->quit = NULL;    {
5676      /* Negative assert is stronger than positive assert. */
5677      common->local_exit = TRUE;
5678      common->quit_label = NULL;
5679      common->quit = NULL;
5680      common->positive_assert = FALSE;
5681      }
5682    else
5683      common->positive_assert = TRUE;
5684    common->positive_assert_quit = NULL;
5685    
5686  while (1)  while (1)
5687    {    {
5688    common->accept_label = NULL;    common->accept_label = NULL;
# Line 5363  while (1) Line 5697  while (1)
5697    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5698    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5699      {      {
5700      common->quit_label = save_quit_label;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5701          {
5702          common->local_exit = save_local_exit;
5703          common->quit_label = save_quit_label;
5704          common->quit = save_quit;
5705          }
5706        common->positive_assert = save_positive_assert;
5707        common->then_trap = save_then_trap;
5708      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5709      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5710      common->accept = save_accept;      common->accept = save_accept;
5711      return NULL;      return NULL;
5712      }      }
# Line 5375  while (1) Line 5716  while (1)
5716    
5717    /* Reset stack. */    /* Reset stack. */
5718    if (framesize < 0)    if (framesize < 0)
5719      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5720    else {      if (framesize == no_frame)
5721          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5722        else
5723          free_stack(common, extrasize);
5724        if (needs_control_head)
5725          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5726        }
5727      else
5728        {
5729      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5730        {        {
5731        /* 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. */
5732        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));
5733          if (needs_control_head)
5734            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5735        }        }
5736      else      else
5737        {        {
5738        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);
5739          if (needs_control_head)
5740            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5741        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5742        }        }
5743    }      }
5744    
5745    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5746      {      {
5747      /* 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. */
5748      if (conditional)      if (conditional)
5749        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);
5750      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5751        {        {
5752        if (framesize < 0)        if (framesize < 0)
5753          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));
5754        else        else
5755          {          {
5756          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));
5757          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));
5758          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);
5759          }          }
5760        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 5418  while (1) Line 5771  while (1)
5771    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5772    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5773      {      {
5774      common->quit_label = save_quit_label;      if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5775          {
5776          common->local_exit = save_local_exit;
5777          common->quit_label = save_quit_label;
5778          common->quit = save_quit;
5779          }
5780        common->positive_assert = save_positive_assert;
5781        common->then_trap = save_then_trap;
5782      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5783      common->quit = save_quit;      common->positive_assert_quit = save_positive_assert_quit;
5784      common->accept = save_accept;      common->accept = save_accept;
5785      return NULL;      return NULL;
5786      }      }
# Line 5432  while (1) Line 5792  while (1)
5792    ccbegin = cc;    ccbegin = cc;
5793    cc += GET(cc, 1);    cc += GET(cc, 1);
5794    }    }
5795    
5796    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5797      {
5798      SLJIT_ASSERT(common->positive_assert_quit == NULL);
5799      /* Makes the check less complicated below. */
5800      common->positive_assert_quit = common->quit;
5801      }
5802    
5803  /* None of them matched. */  /* None of them matched. */
5804  if (common->quit != NULL)  if (common->positive_assert_quit != NULL)
5805    set_jumps(common->quit, LABEL());    {
5806      jump = JUMP(SLJIT_JUMP);
5807      set_jumps(common->positive_assert_quit, LABEL());
5808      SLJIT_ASSERT(framesize != no_stack);
5809      if (framesize < 0)
5810        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5811      else
5812        {
5813        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5814        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5815        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5816        }
5817      JUMPHERE(jump);
5818      }
5819    
5820    if (needs_control_head)
5821      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5822    
5823  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5824    {    {
# Line 5446  if (opcode == OP_ASSERT || opcode == OP_ Line 5830  if (opcode == OP_ASSERT || opcode == OP_
5830      {      {
5831      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5832      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5833          {
5834          if (extrasize == 2)
5835            free_stack(common, 1);
5836        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5837          }
5838      else      else
5839        free_stack(common, 1);        free_stack(common, extrasize);
5840      }      }
5841    else    else
5842      {      {
5843      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5844      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5845      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5846        {        {
5847        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5848        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5849        }        }
5850      else      else
5851        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5852      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);
5853      }      }
5854    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5472  if (opcode == OP_ASSERT || opcode == OP_ Line 5860  if (opcode == OP_ASSERT || opcode == OP_
5860    if (framesize < 0)    if (framesize < 0)
5861      {      {
5862      /* 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. */
5863      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));
5864      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5865      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5866          {
5867        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));
5868          if (extrasize == 2)
5869            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5870          }
5871      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5872        {        {
5873        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 5488  if (opcode == OP_ASSERT || opcode == OP_ Line 5880  if (opcode == OP_ASSERT || opcode == OP_
5880        {        {
5881        /* 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. */
5882        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));
5883        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));
5884        }        }
5885      else      else
5886        {        {
5887        /* 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. */
5888        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));
5889        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5890        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5891            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5892            if (bra == OP_BRAMINZERO)
5893              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5894            }
5895          else
5896            {
5897            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5898            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5899            }
5900        }        }
5901      }      }
5902    
# Line 5524  else Line 5925  else
5925      {      {
5926      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5927      if (bra != OP_BRA)      if (bra != OP_BRA)
5928          {
5929          if (extrasize == 2)
5930            free_stack(common, 1);
5931        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5932          }
5933      else      else
5934        free_stack(common, 1);        free_stack(common, extrasize);
5935      }      }
5936    else    else
5937      {      {
5938      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5939      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5940      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5941      if (bra != OP_BRA)      if (bra != OP_BRA)
5942        {        {
5943        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5944        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5945        }        }
5946      else      else
5947        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5948      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);
5949      }      }
5950    
# Line 5559  else Line 5964  else
5964      }      }
5965    }    }
5966    
5967  common->quit_label = save_quit_label;  if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5968      {
5969      common->local_exit = save_local_exit;
5970      common->quit_label = save_quit_label;
5971      common->quit = save_quit;
5972      }
5973    common->positive_assert = save_positive_assert;
5974    common->then_trap = save_then_trap;
5975  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5976  common->quit = save_quit;  common->positive_assert_quit = save_positive_assert_quit;
5977  common->accept = save_accept;  common->accept = save_accept;
5978  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5979  }  }
5980    
5981  static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table)  static SLJIT_INLINE void match_once_common(compiler_common *common, pcre_uchar ket, int framesize, int private_data_ptr, BOOL has_alternatives, BOOL needs_control_head)
5982  {  {
5983  int condition = FALSE;  DEFINE_COMPILER;
5984  pcre_uchar *slotA = name_table;  int stacksize;
 pcre_uchar *slotB;  
 sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)];  
 sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];  
 sljit_sw no_capture;  
 int i;  
   
 locals += refno & 0xff;  
 refno >>= 8;  
 no_capture = locals[1];  
5985    
5986  for (i = 0; i < name_count; i++)  if (framesize < 0)
5987    {    {
5988    if (GET2(slotA, 0) == refno) break;    if (framesize == no_frame)
5989    slotA += name_entry_size;      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5990    }    else
5991        {
5992        stacksize = needs_control_head ? 1 : 0;
5993        if (ket != OP_KET || has_alternatives)
5994          stacksize++;
5995        free_stack(common, stacksize);
5996        }
5997    
5998  if (i < name_count)    if (needs_control_head)
5999    {      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
   /* Found a name for the number - there can be only one; duplicate names  
   for different numbers are allowed, but not vice versa. First scan down  
   for duplicates. */  
6000    
6001    slotB = slotA;    /* TMP2 which is set here used by OP_KETRMAX below. */
6002    while (slotB > name_table)    if (ket == OP_KETRMAX)
6003        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6004      else if (ket == OP_KETRMIN)
6005      {      {
6006      slotB -= name_entry_size;      /* Move the STR_PTR to the private_data_ptr. */
6007      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
       {  
       condition = locals[GET2(slotB, 0) << 1] != no_capture;  
       if (condition) break;  
       }  
     else break;  
6008      }      }
6009      }
6010    else
6011      {
6012      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6013      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6014      if (needs_control_head)
6015        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6016    
6017    /* Scan up for duplicates */    if (ket == OP_KETRMAX)
   if (!condition)  
6018      {      {
6019      slotB = slotA;      /* TMP2 which is set here used by OP_KETRMAX below. */
6020      for (i++; i < name_count; i++)      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
       {  
       slotB += name_entry_size;  
       if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
         {  
         condition = locals[GET2(slotB, 0) << 1] != no_capture;  
         if (condition) break;  
         }  
       else break;  
       }  
6021      }      }
6022    }    }
6023  return condition;  if (needs_control_head)
6024      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6025  }  }
6026    
6027  static sljit_sw SLJIT_CALL do_searchgroups(sljit_uw recno, sljit_uw* locals, pcre_uchar *name_table)  static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6028  {  {
6029  int condition = FALSE;  DEFINE_COMPILER;
 pcre_uchar *slotA = name_table;  
 pcre_uchar *slotB;  
 sljit_uw name_count = locals[LOCALS0 / sizeof(sljit_sw)];  
 sljit_uw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];  
 sljit_uw group_num = locals[POSSESSIVE0 / sizeof(sljit_sw)];  
 sljit_uw i;  
6030    
6031  for (i = 0; i < name_count; i++)  if (common->capture_last_ptr != 0)
6032    {    {
6033    if (GET2(slotA, 0) == recno) break;    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6034    slotA += name_entry_size;    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6035      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6036      stacksize++;
6037    }    }
6038    if (common->optimized_cbracket[offset >> 1] == 0)
 if (i < name_count)  
6039    {    {
6040    /* Found a name for the number - there can be only one; duplicate    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6041    names for different numbers are allowed, but not vice versa. First    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6042    scan down for duplicates. */    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6043      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6044    slotB = slotA;    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6045    while (slotB > name_table)    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6046      {    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6047      slotB -= name_entry_size;    stacksize += 2;
     if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
       {  
       condition = GET2(slotB, 0) == group_num;  
       if (condition) break;  
       }  
     else break;  
     }  
   
   /* Scan up for duplicates */  
   if (!condition)  
     {  
     slotB = slotA;  
     for (i++; i < name_count; i++)  
       {  
       slotB += name_entry_size;  
       if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)  
         {  
         condition = GET2(slotB, 0) == group_num;  
         if (condition) break;  
         }  
       else break;  
       }  
     }  
6048    }    }
6049  return condition;  return stacksize;
6050  }  }
6051    
6052  /*  /*
# Line 5737  backtrack_common *backtrack; Line 6110  backtrack_common *backtrack;
6110  pcre_uchar opcode;  pcre_uchar opcode;
6111  int private_data_ptr = 0;  int private_data_ptr = 0;
6112  int offset = 0;  int offset = 0;
6113  int stacksize;  int i, stacksize;
6114    int repeat_ptr = 0, repeat_length = 0;
6115    int repeat_type = 0, repeat_count = 0;
6116  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
6117  pcre_uchar *matchingpath;  pcre_uchar *matchingpath;
6118    pcre_uchar *slot;
6119  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6120  pcre_uchar ket;  pcre_uchar ket;
6121  assert_backtrack *assert;  assert_backtrack *assert;
6122  BOOL has_alternatives;  BOOL has_alternatives;
6123    BOOL needs_control_head = FALSE;
6124  struct sljit_jump *jump;  struct sljit_jump *jump;
6125  struct sljit_jump *skip;  struct sljit_jump *skip;
6126  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmax_label = NULL;
6127  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzero = NULL;
6128    
6129  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
6130    
# Line 5760  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 6137  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
6137    
6138  opcode = *cc;  opcode = *cc;
6139  ccbegin = cc;  ccbegin = cc;
6140  matchingpath = ccbegin + 1 + LINK_SIZE;  matchingpath = bracketend(cc) - 1 - LINK_SIZE;
6141    ket = *matchingpath;
6142    if (ket == OP_KET && PRIVATE_DATA(matchingpath) != 0)
6143      {
6144      repeat_ptr = PRIVATE_DATA(matchingpath);
6145      repeat_length = PRIVATE_DATA(matchingpath + 1);
6146      repeat_type = PRIVATE_DATA(matchingpath + 2);
6147      repeat_count = PRIVATE_DATA(matchingpath + 3);
6148      SLJIT_ASSERT(repeat_length != 0 && repeat_type != 0 && repeat_count != 0);
6149      if (repeat_type == OP_UPTO)
6150        ket = OP_KETRMAX;
6151      if (repeat_type == OP_MINUPTO)
6152        ket = OP_KETRMIN;
6153      }
6154    
6155  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)
6156    {    {
6157    /* Drop this bracket_backtrack. */    /* Drop this bracket_backtrack. */
6158    parent->top = backtrack->prev;    parent->top = backtrack->prev;
6159    return bracketend(cc);    return matchingpath + 1 + LINK_SIZE + repeat_length;
6160    }    }
6161    
6162  ket = *(bracketend(cc) - 1 - LINK_SIZE);  matchingpath = ccbegin + 1 + LINK_SIZE;
6163  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
6164  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)));
6165  cc += GET(cc, 1);  cc += GET(cc, 1);
6166    
6167  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
6168  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND || opcode == OP_SCOND))
6169    {    has_alternatives = (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF) ? FALSE : TRUE;
   has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;  
   if (*matchingpath == OP_NRREF)  
     {  
     stacksize = GET2(matchingpath, 1);  
     if (common->currententry == NULL || stacksize == RREF_ANY)  
       has_alternatives = FALSE;  
     else if (common->currententry->start == 0)  
       has_alternatives = stacksize != 0;  
     else  
       has_alternatives = stacksize != (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);  
     }  
   }  
6170    
6171  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
6172    opcode = OP_SCOND;    opcode = OP_SCOND;
# Line 5819  else if (opcode == OP_ONCE || opcode == Line 6197  else if (opcode == OP_ONCE || opcode ==
6197    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6198    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6199    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6200      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);
6201    }    }
6202    
6203  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6204  stacksize = 0;  stacksize = 0;
6205  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6206    stacksize++;    stacksize++;
6207  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6208    stacksize++;    stacksize++;
# Line 5833  if (stacksize > 0) Line 6211  if (stacksize > 0)
6211    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6212    
6213  stacksize = 0;  stacksize = 0;
6214  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6215    {    {
6216    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6217    stacksize++;    stacksize++;
# Line 5849  if (bra == OP_BRAMINZERO) Line 6227  if (bra == OP_BRAMINZERO)
6227    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
6228      {      {
6229      free_stack(common, 1);      free_stack(common, 1);
6230      braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);      braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
6231      }      }
6232    else    else
6233      {      {
# Line 5864  if (bra == OP_BRAMINZERO) Line 6242  if (bra == OP_BRAMINZERO)
6242        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6243          {          {
6244          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
6245          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);          braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6246          }          }
6247        else        else
6248          {          {
6249          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
6250          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);
6251          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));          braminzero = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_sw));
6252          }          }
6253        JUMPHERE(skip);        JUMPHERE(skip);
6254        }        }
# Line 5883  if (bra == OP_BRAMINZERO) Line 6261  if (bra == OP_BRAMINZERO)
6261      }      }
6262    }    }
6263    
6264    if (repeat_type != 0)
6265      {
6266      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, repeat_count);
6267      if (repeat_type == OP_EXACT)
6268        rmax_label = LABEL();
6269      }
6270    
6271  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
6272    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6273    
6274  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6275    {    {
6276    rmaxlabel = LABEL();    rmax_label = LABEL();
6277    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0)
6278      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label;
6279    }    }
6280    
6281  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6282  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6283    {    {
6284      stacksize = 0;
6285      if (needs_control_head)
6286        {
6287        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6288        stacksize++;
6289        }
6290    
6291    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6292      {      {
6293      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6294      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6295        {        {
6296        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6297        allocate_stack(common, 2);        if (!needs_control_head)
6298        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));  
6299        }        }
6300      else if (ket == OP_KETRMAX || has_alternatives)      else
6301        {        {
6302        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6303        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6304        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6305            stacksize++;
6306        }        }
6307      else  
6308        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6309          allocate_stack(common, stacksize);
6310    
6311        stacksize = 0;
6312        if (needs_control_head)
6313          {
6314          stacksize++;
6315          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6316          }
6317    
6318        if (ket == OP_KETRMIN)
6319          {
6320          if (needs_control_head)
6321            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6322          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6323          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6324            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));
6325          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6326          }
6327        else if (ket == OP_KETRMAX || has_alternatives)
6328          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6329      }      }
6330    else    else
6331      {      {
6332      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6333          stacksize++;
6334    
6335        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6336        allocate_stack(common, stacksize);
6337    
6338        if (needs_control_head)
6339          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6340    
6341        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6342        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6343    
6344        stacksize = needs_control_head ? 1 : 0;
6345        if (ket != OP_KET || has_alternatives)
6346        {        {
6347        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);  
6348        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);
6349        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6350        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6351        }        }
6352      else      else
6353        {        {
       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));  
6354        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);
6355        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);  
6356        }        }
6357        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6358      }      }
6359    }    }
6360  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 5985  if (opcode == OP_COND || opcode == OP_SC Line 6403  if (opcode == OP_COND || opcode == OP_SC
6403        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
6404      matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
6405      }      }
6406    else if (*matchingpath == OP_NCREF)    else if (*matchingpath == OP_DNCREF)
6407      {      {
6408      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
     stacksize = GET2(matchingpath, 1);  
     jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  
   
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);  
     OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));  
     GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);  
     OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);  
     sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));  
     OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
     add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));  
6409    
6410      JUMPHERE(jump);      i = GET2(matchingpath, 1 + IMM2_SIZE);
6411      matchingpath += 1 + IMM2_SIZE;      slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6412        OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
6413        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
6414        OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6415        slot += common->name_entry_size;
6416        i--;
6417        while (i-- > 0)
6418          {
6419          OP2(SLJIT_SUB, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(slot, 0) << 1), TMP1, 0);
6420          OP2(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, STR_PTR, 0);
6421          slot += common->name_entry_size;
6422          }
6423        OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
6424        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), JUMP(SLJIT_C_ZERO));
6425        matchingpath += 1 + 2 * IMM2_SIZE;
6426      }      }
6427    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_DNRREF)
6428      {      {
6429      /* Never has other case. */      /* Never has other case. */
6430      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
6431        SLJIT_ASSERT(!has_alternatives);
6432    
6433      stacksize = GET2(matchingpath, 1);      if (*matchingpath == OP_RREF)
     if (common->currententry == NULL)  
       stacksize = 0;  
     else if (stacksize == RREF_ANY)  
       stacksize = 1;  
     else if (common->currententry->start == 0)  
       stacksize = stacksize == 0;  
     else  
       stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);  
   
     if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)  
6434        {        {
6435        SLJIT_ASSERT(!has_alternatives);        stacksize = GET2(matchingpath, 1);
6436          if (common->currententry == NULL)
6437            stacksize = 0;
6438          else if (stacksize == RREF_ANY)
6439            stacksize = 1;
6440          else if (common->currententry->start == 0)
6441            stacksize = stacksize == 0;
6442          else
6443            stacksize = stacksize == (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6444    
6445        if (stacksize != 0)        if (stacksize != 0)
6446          matchingpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
6447          }
6448        else
6449          {
6450          if (common->currententry == NULL || common->currententry->start == 0)
6451            stacksize = 0;
6452        else        else
6453          {          {
6454            stacksize = GET2(matchingpath, 1 + IMM2_SIZE);
6455            slot = common->name_table + GET2(matchingpath, 1) * common->name_entry_size;
6456            i = (int)GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
6457            while (stacksize > 0)
6458              {
6459              if ((int)GET2(slot, 0) == i)
6460                break;
6461              slot += common->name_entry_size;
6462              stacksize--;
6463              }
6464            }
6465    
6466          if (stacksize != 0)
6467            matchingpath += 1 + 2 * IMM2_SIZE;
6468          }
6469    
6470          /* The stacksize == 0 is a common "else" case. */
6471          if (stacksize == 0)
6472            {
6473          if (*cc == OP_ALT)          if (*cc == OP_ALT)
6474            {            {
6475            matchingpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
# Line 6034  if (opcode == OP_COND || opcode == OP_SC Line 6478  if (opcode == OP_COND || opcode == OP_SC
6478          else          else
6479            matchingpath = cc;            matchingpath = cc;
6480          }          }
       }  
     else  
       {  
       SLJIT_ASSERT(has_alternatives);  
   
       stacksize = GET2(matchingpath, 1);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));  
       OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize);  
       GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);  
       OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);  
       sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));  
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
       add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));  
       matchingpath += 1 + IMM2_SIZE;  
       }  
6481      }      }
6482    else    else
6483      {      {
# Line 6072  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6498  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6498    return NULL;    return NULL;
6499    
6500  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6501    {    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));  
       }  
     }  
   }  
6502    
6503  stacksize = 0;  stacksize = 0;
6504    if (repeat_type == OP_MINUPTO)
6505      {
6506      /* We need to preserve the counter. TMP2 will be used below. */
6507      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6508      stacksize++;
6509      }
6510  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6511    stacksize++;    stacksize++;
6512  if (offset != 0)  if (offset != 0)
# Line 6114  if (stacksize > 0) Line 6523  if (stacksize > 0)
6523    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6524    
6525  stacksize = 0;  stacksize = 0;
6526    if (repeat_type == OP_MINUPTO)
6527      {
6528      /* TMP2 was set above. */
6529      OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
6530      stacksize++;
6531      }
6532    
6533  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6534    {    {
6535    if (ket != OP_KET)    if (ket != OP_KET)
# Line 6124  if (ket != OP_KET || bra != OP_BRA) Line 6540  if (ket != OP_KET || bra != OP_BRA)
6540    }    }
6541    
6542  if (offset != 0)  if (offset != 0)
6543    {    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;  
     }  
   }  
6544    
6545  if (has_alternatives)  if (has_alternatives)
6546    {    {
# Line 6162  if (offset != 0 && common->optimized_cbr Line 6559  if (offset != 0 && common->optimized_cbr
6559    
6560  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
6561    {    {
6562    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (repeat_type != 0)
6563        {
6564        if (has_alternatives)
6565          BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6566        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6567        JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
6568        /* Drop STR_PTR for greedy plus quantifier. */
6569        if (opcode != OP_ONCE)
6570          free_stack(common, 1);
6571        }
6572      else if (opcode == OP_ONCE || opcode >= OP_SBRA)
6573      {      {
6574      if (has_alternatives)      if (has_alternatives)
6575        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
6576      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
6577      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
6578        {        {
6579        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmax_label);
6580        /* Drop STR_PTR for greedy plus quantifier. */        /* Drop STR_PTR for greedy plus quantifier. */
6581        if (bra != OP_BRAZERO)        if (bra != OP_BRAZERO)
6582          free_stack(common, 1);          free_stack(common, 1);
6583        }        }
6584      else      else
6585        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
6586        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmax_label);
6587      }      }
6588    else    else
6589      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmax_label);
6590    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
6591    }    }
6592    
6593    if (repeat_type == OP_EXACT)
6594      {
6595      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
6596      JUMPTO(SLJIT_C_NOT_ZERO, rmax_label);
6597      }
6598    else if (repeat_type == OP_UPTO)
6599      {
6600      /* We need to preserve the counter. */
6601      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
6602      allocate_stack(common, 1);
6603      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6604      }
6605    
6606  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6607    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
6608    
# Line 6190  if (bra == OP_BRAMINZERO) Line 6610  if (bra == OP_BRAMINZERO)
6610    {    {
6611    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
6612    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
6613    if (braminzerojump != NULL)    if (braminzero != NULL)
6614      {      {
6615      JUMPHERE(braminzerojump);      JUMPHERE(braminzero);
6616      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
6617      backtrack for the zero-length iteration. When      backtrack for the zero-length iteration. When
6618      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
# Line 6208  if (bra == OP_BRAMINZERO) Line 6628  if (bra == OP_BRAMINZERO)
6628    }    }
6629    
6630  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
6631    decrease_call_count(common);    count_match(common);
6632    
6633  /* Skip the other alternatives. */  /* Skip the other alternatives. */
6634  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6635    cc += GET(cc, 1);    cc += GET(cc, 1);
6636  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6637  return cc;  
6638    /* Temporarily encoding the needs_control_head in framesize. */
6639    if (opcode == OP_ONCE)
6640      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6641    return cc + repeat_length;
6642  }  }
6643    
6644  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 6224  backtrack_common *backtrack; Line 6648  backtrack_common *backtrack;
6648  pcre_uchar opcode;  pcre_uchar opcode;
6649  int private_data_ptr;  int private_data_ptr;
6650  int cbraprivptr = 0;  int cbraprivptr = 0;
6651    BOOL needs_control_head;
6652  int framesize;  int framesize;
6653  int stacksize;  int stacksize;
6654  int offset = 0;  int offset = 0;
6655  BOOL zero = FALSE;  BOOL zero = FALSE;
6656  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6657  int stack;  int stack; /* Also contains the offset of control head. */
6658  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6659  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6660    
# Line 6267  switch(opcode) Line 6692  switch(opcode)
6692    break;    break;
6693    }    }
6694    
6695  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6696  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6697  if (framesize < 0)  if (framesize < 0)
6698    {    {
# Line 6280  if (framesize < 0) Line 6705  if (framesize < 0)
6705    else    else
6706      stacksize = 1;      stacksize = 1;
6707    
6708      if (needs_control_head)
6709        stacksize++;
6710    if (!zero)    if (!zero)
6711      stacksize++;      stacksize++;
6712    
# Line 6288  if (framesize < 0) Line 6715  if (framesize < 0)
6715    if (framesize == no_frame)    if (framesize == no_frame)
6716      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);
6717    
6718      stack = 0;
6719    if (offset != 0)    if (offset != 0)
6720      {      {
6721        stack = 2;
6722      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6723      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));
6724      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6725      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6726        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);
6727      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6728        if (needs_control_head)
6729          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6730      if (common->capture_last_ptr != 0)      if (common->capture_last_ptr != 0)
6731          {
6732        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6733          stack = 3;
6734          }
6735      }      }
6736    else    else
6737        {
6738        if (needs_control_head)
6739          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6740      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6741        stack = 1;
6742        }
6743    
6744      if (needs_control_head)
6745        stack++;
6746    if (!zero)    if (!zero)
6747      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);
6748      if (needs_control_head)
6749        {
6750        stack--;
6751        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6752        }
6753    }    }
6754  else  else
6755    {    {
6756    stacksize = framesize + 1;    stacksize = framesize + 1;
6757    if (!zero)    if (!zero)
6758      stacksize++;      stacksize++;
6759    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6760        stacksize++;
6761      if (offset == 0)
6762      stacksize++;      stacksize++;
6763    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6764    
6765    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6766    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);
6767    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6768    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);
6769      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6770    
6771    stack = 0;    stack = 0;
6772    if (!zero)    if (!zero)
6773      {      {
6774      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6775        stack = 1;
6776        }
6777      if (needs_control_head)
6778        {
6779        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6780      stack++;      stack++;
6781      }      }
6782    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6783      {      {
6784      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6785      stack++;      stack++;
6786      }      }
6787    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6788    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6789      stack -= 1 + (offset == 0);
6790    }    }
6791    
6792  if (offset != 0)  if (offset != 0)
# Line 6407  while (*cc != OP_KETRPOS) Line 6862  while (*cc != OP_KETRPOS)
6862          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6863        }        }
6864      }      }
6865    
6866      if (needs_control_head)
6867        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6868    
6869    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6870    flush_stubs(common);    flush_stubs(common);
6871    
# Line 6443  while (*cc != OP_KETRPOS) Line 6902  while (*cc != OP_KETRPOS)
6902    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6903    }    }
6904    
6905    /* We don't have to restore the control head in case of a failed match. */
6906    
6907  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6908  if (!zero)  if (!zero)
6909    {    {
# Line 6454  if (!zero) Line 6915  if (!zero)
6915    
6916  /* None of them matched. */  /* None of them matched. */
6917  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
6918  decrease_call_count(common);  count_match(common);
6919  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
6920  }  }
6921    
# Line 6764  switch(opcode) Line 7225  switch(opcode)
7225    break;    break;
7226    }    }
7227    
7228  decrease_call_count(common);  count_match(common);
7229  return end;  return end;
7230  }  }
7231    
# Line 6822  BOOL optimized_cbracket = common->optimi Line 7283  BOOL optimized_cbracket = common->optimi
7283  if (common->currententry != NULL)  if (common->currententry != NULL)
7284    return cc + 1 + IMM2_SIZE;    return cc + 1 + IMM2_SIZE;
7285    
7286  if (!optimized_cbracket)  if (!optimized_cbracket)
7287    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
7288  offset <<= 1;  offset <<= 1;
7289  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7290  if (!optimized_cbracket)  if (!optimized_cbracket)
7291    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7292  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7293    }
7294    
7295    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7296    {
7297    DEFINE_COMPILER;
7298    backtrack_common *backtrack;
7299    pcre_uchar opcode = *cc;
7300    pcre_uchar *ccend = cc + 1;
7301    
7302    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7303      ccend += 2 + cc[1];
7304    
7305    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7306    
7307    if (opcode == OP_SKIP)
7308      {
7309      allocate_stack(common, 1);
7310      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7311      return ccend;
7312      }
7313    
7314    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7315      {
7316      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7317      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7318      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7319      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7320      }
7321    
7322    return ccend;
7323    }
7324    
7325    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7326    
7327    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7328    {
7329    DEFINE_COMPILER;
7330    backtrack_common *backtrack;
7331    BOOL needs_control_head;
7332    int size;
7333    
7334    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7335    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7336    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7337    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7338    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7339    
7340    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7341    size = 3 + (size < 0 ? 0 : size);
7342    
7343    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7344    allocate_stack(common, size);
7345    if (size > 3)
7346      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7347    else
7348      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7349    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7350    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7351    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7352    
7353    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7354    if (size >= 0)
7355      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7356  }  }
7357    
7358  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)
7359  {  {
7360  DEFINE_COMPILER;  DEFINE_COMPILER;
7361  backtrack_common *backtrack;  backtrack_common *backtrack;
7362    BOOL has_then_trap = FALSE;
7363    then_trap_backtrack *save_then_trap = NULL;
7364    
7365    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7366    
7367    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7368      {
7369      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7370      has_then_trap = TRUE;
7371      save_then_trap = common->then_trap;
7372      /* Tail item on backtrack. */
7373      compile_then_trap_matchingpath(common, cc, ccend, parent);
7374      }
7375    
7376  while (cc < ccend)  while (cc < ccend)
7377    {    {
# Line 6980  while (cc < ccend) Line 7517  while (cc < ccend)
7517      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
7518        cc = compile_ref_iterator_matchingpath(common, cc, parent);        cc = compile_ref_iterator_matchingpath(common, cc, parent);
7519      else      else
7520        cc = compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);        {
7521          compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
7522          cc += 1 + IMM2_SIZE;
7523          }
7524        break;
7525    
7526        case OP_DNREF:
7527        case OP_DNREFI:
7528        if (cc[1 + 2 * IMM2_SIZE] >= OP_CRSTAR && cc[1 + 2 * IMM2_SIZE] <= OP_CRMINRANGE)
7529          cc = compile_ref_iterator_matchingpath(common, cc, parent);
7530        else
7531          {
7532          compile_dnref_search(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks);
7533          compile_ref_matchingpath(common, cc, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, TRUE, FALSE);
7534          cc += 1 + 2 * IMM2_SIZE;
7535          }
7536      break;      break;
7537    
7538      case OP_RECURSE:      case OP_RECURSE:
# Line 7015  while (cc < ccend) Line 7567  while (cc < ccend)
7567        }        }
7568      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();      BACKTRACK_AS(braminzero_backtrack)->matchingpath = LABEL();
7569      if (cc[1] > OP_ASSERTBACK_NOT)      if (cc[1] > OP_ASSERTBACK_NOT)
7570        decrease_call_count(common);        count_match(common);
7571      break;      break;
7572    
7573      case OP_ONCE:      case OP_ONCE:
# Line 7051  while (cc < ccend) Line 7603  while (cc < ccend)
7603      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7604      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7605      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);
7606      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7607      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7608      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);
7609      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7610      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);
7611      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);
7612        if (common->has_skip_arg)
7613          {
7614          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7615          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7616          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7617          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7618          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7619          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7620          }
7621      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7622      break;      break;
7623    
7624        case OP_PRUNE:
7625        case OP_PRUNE_ARG:
7626        case OP_SKIP:
7627        case OP_SKIP_ARG:
7628        case OP_THEN:
7629        case OP_THEN_ARG:
7630      case OP_COMMIT:      case OP_COMMIT:
7631      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7632      break;      break;
7633    
7634      case OP_FAIL:      case OP_FAIL:
# Line 7086  while (cc < ccend) Line 7652  while (cc < ccend)
7652    if (cc == NULL)    if (cc == NULL)
7653      return;      return;
7654    }    }
7655    
7656    if (has_then_trap)
7657      {
7658      /* Head item on backtrack. */
7659      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7660      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7661      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7662      common->then_trap = save_then_trap;
7663      }
7664  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7665  }  }
7666    
# Line 7247  switch(opcode) Line 7822  switch(opcode)
7822    }    }
7823  }  }
7824    
7825  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)
7826  {  {
7827  DEFINE_COMPILER;  DEFINE_COMPILER;
7828  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
7829    BOOL ref = (*cc == OP_REF || *cc == OP_REFI);
7830  pcre_uchar type;  pcre_uchar type;
7831    
7832  type = cc[1 + IMM2_SIZE];  type = cc[ref ? 1 + IMM2_SIZE : 1 + 2 * IMM2_SIZE];
7833    
7834  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
7835    {    {
7836      /* Maximize case. */
7837    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7838    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7839    free_stack(common, 1);    free_stack(common, 1);
# Line 7266  if ((type & 0x1) == 0) Line 7844  if ((type & 0x1) == 0)
7844  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7845  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);  CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0, CURRENT_AS(iterator_backtrack)->matchingpath);
7846  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
7847  free_stack(common, 2);  free_stack(common, ref ? 2 : 3);
7848  }  }
7849    
7850  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)
7851  {  {
7852  DEFINE_COMPILER;  DEFINE_COMPILER;
7853    
# Line 7365  if (bra == OP_BRAZERO) Line 7943  if (bra == OP_BRAZERO)
7943  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_bracket_backtrackingpath(compiler_common *common, struct backtrack_common *current)
7944  {  {
7945  DEFINE_COMPILER;  DEFINE_COMPILER;
7946  int opcode;  int opcode, stacksize, count;
7947  int offset = 0;  int offset = 0;
7948  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;  int private_data_ptr = CURRENT_AS(bracket_backtrack)->private_data_ptr;
7949  int stacksize;  int repeat_ptr = 0, repeat_type = 0, repeat_count = 0;
 int count;  
7950  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
7951  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
7952  pcre_uchar *ccprev;  pcre_uchar *ccprev;
# Line 7379  pcre_uchar bra = OP_BRA; Line 7956  pcre_uchar bra = OP_BRA;
7956  pcre_uchar ket;  pcre_uchar ket;
7957  assert_backtrack *assert;  assert_backtrack *assert;
7958  BOOL has_alternatives;  BOOL has_alternatives;
7959    BOOL needs_control_head = FALSE;
7960  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7961  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7962  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
7963  struct sljit_label *rminlabel = NULL;  struct sljit_label *rmin_label = NULL;
7964    struct sljit_label *exact_label = NULL;
7965    
7966  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
7967    {    {
# Line 7391  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 7970  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
7970    }    }
7971    
7972  opcode = *cc;  opcode = *cc;
7973    ccbegin = bracketend(cc) - 1 - LINK_SIZE;
7974    ket = *ccbegin;
7975    if (ket == OP_KET && PRIVATE_DATA(ccbegin) != 0)
7976      {
7977      repeat_ptr = PRIVATE_DATA(ccbegin);
7978      repeat_type = PRIVATE_DATA(ccbegin + 2);
7979      repeat_count = PRIVATE_DATA(ccbegin + 3);
7980      SLJIT_ASSERT(repeat_type != 0 && repeat_count != 0);
7981      if (repeat_type == OP_UPTO)
7982        ket = OP_KETRMAX;
7983      if (repeat_type == OP_MINUPTO)
7984        ket = OP_KETRMIN;
7985      }
7986  ccbegin = cc;  ccbegin = cc;
 ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  
7987  cc += GET(cc, 1);  cc += GET(cc, 1);
7988  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
7989  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
# Line 7404  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7995  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7995  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7996    opcode = OP_ONCE;    opcode = OP_ONCE;
7997    
7998    /* Decoding the needs_control_head in framesize. */
7999    if (opcode == OP_ONCE)
8000      {
8001      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
8002      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
8003      }
8004    
8005    if (ket != OP_KET && repeat_type != 0)
8006      {
8007      /* TMP1 is used in OP_KETRMIN below. */
8008      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8009      free_stack(common, 1);
8010      if (repeat_type == OP_UPTO)
8011        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0, SLJIT_IMM, 1);
8012      else
8013        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8014      }
8015    
8016  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
8017    {    {
8018    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7418  else if (ket == OP_KETRMIN) Line 8027  else if (ket == OP_KETRMIN)
8027    if (bra != OP_BRAMINZERO)    if (bra != OP_BRAMINZERO)
8028      {      {
8029      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8030      if (opcode >= OP_SBRA || opcode == OP_ONCE)      if (repeat_type != 0)
8031          {
8032          /* TMP1 was set a few lines above. */
8033          CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8034          /* Drop STR_PTR for non-greedy plus quantifier. */
8035          if (opcode != OP_ONCE)
8036            free_stack(common, 1);
8037          }
8038        else if (opcode >= OP_SBRA || opcode == OP_ONCE)
8039        {        {
8040        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
8041        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize < 0)
# Line 7428  else if (ket == OP_KETRMIN) Line 8045  else if (ket == OP_KETRMIN)
8045          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);
8046          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);
8047          }          }
8048          /* Drop STR_PTR for non-greedy plus quantifier. */
8049        if (opcode != OP_ONCE)        if (opcode != OP_ONCE)
8050          free_stack(common, 1);          free_stack(common, 1);
8051        }        }
8052      else      else
8053        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);        JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->recursive_matchingpath);
8054      }      }
8055    rminlabel = LABEL();    rmin_label = LABEL();
8056      if (repeat_type != 0)
8057        OP2(SLJIT_ADD, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8058    }    }
8059  else if (bra == OP_BRAZERO)  else if (bra == OP_BRAZERO)
8060    {    {
# Line 7442  else if (bra == OP_BRAZERO) Line 8062  else if (bra == OP_BRAZERO)
8062    free_stack(common, 1);    free_stack(common, 1);
8063    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
8064    }    }
8065    else if (repeat_type == OP_EXACT)
8066      {
8067      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8068      exact_label = LABEL();
8069      }
8070    
8071  if (offset != 0)  if (offset != 0)
8072    {    {
# Line 7561  if (has_alternatives) Line 8186  if (has_alternatives)
8186      current->top = NULL;      current->top = NULL;
8187      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8188      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8189        /* Conditional blocks always have an additional alternative, even if it is empty. */
8190      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8191        {        {
8192        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8193        cc += GET(cc, 1);        cc += GET(cc, 1);
8194        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8195          {          {
8196          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8197            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8198              if (private_data_ptr != 0)
8199                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8200              else
8201                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8202              }
8203          else          else
8204            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));
8205          }          }
8206        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8207        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8208          return;          return;
8209        }        }
8210    
8211      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is successfully matched. */
8212      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8213      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8214        {        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));  
           }  
         }  
       }  
8215    
8216      stacksize = 0;      stacksize = 0;
8217        if (repeat_type == OP_MINUPTO)
8218          {
8219          /* We need to preserve the counter. TMP2 will be used below. */
8220          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr);
8221          stacksize++;
8222          }
8223      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8224        stacksize++;        stacksize++;
8225      if (offset != 0)      if (offset != 0)
# Line 7617  if (has_alternatives) Line 8232  if (has_alternatives)
8232      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8233        stacksize++;        stacksize++;
8234    
8235      if (stacksize > 0) {      if (stacksize > 0)
8236        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));  
         }  
     }  
8237    
8238      stacksize = 0;      stacksize = 0;
8239        if (repeat_type == OP_MINUPTO)
8240          {
8241          /* TMP2 was set above. */
8242          OP2(SLJIT_SUB, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0, SLJIT_IMM, 1);
8243          stacksize++;
8244          }
8245    
8246      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8247        {        {
8248        if (ket != OP_KET)        if (ket != OP_KET)
# Line 7639  if (has_alternatives) Line 8253  if (has_alternatives)
8253        }        }
8254    
8255      if (offset != 0)      if (offset != 0)
8256        {        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;  
         }  
       }  
8257    
8258      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8259        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 7692  if (has_alternatives) Line 8287  if (has_alternatives)
8287      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8288      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8289      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)
   
8290        {        {
8291        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);
8292        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7732  else if (opcode == OP_SBRA || opcode == Line 8326  else if (opcode == OP_SBRA || opcode ==
8326  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8327    {    {
8328    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8329      stacksize = needs_control_head ? 1 : 0;
8330    
8331    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8332      {      {
8333      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8334      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);  
8335      }      }
8336    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8337      {      {
8338      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8339      free_stack(common, 1);      stacksize++;
8340      }      }
8341      free_stack(common, stacksize);
8342    
8343    JUMPHERE(once);    JUMPHERE(once);
8344    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7757  else if (opcode == OP_ONCE) Line 8353  else if (opcode == OP_ONCE)
8353      }      }
8354    }    }
8355    
8356  if (ket == OP_KETRMAX)  if (repeat_type == OP_EXACT)
8357      {
8358      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, SLJIT_IMM, 1);
8359      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), repeat_ptr, TMP1, 0);
8360      CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, repeat_count, exact_label);
8361      }
8362    else if (ket == OP_KETRMAX)
8363    {    {
8364    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8365    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
8366      free_stack(common, 1);      free_stack(common, 1);
8367    
8368    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);
8369    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
8370      {      {
# Line 7780  else if (ket == OP_KETRMIN) Line 8383  else if (ket == OP_KETRMIN)
8383    affect badly the free_stack(2) above. */    affect badly the free_stack(2) above. */
8384    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
8385      free_stack(common, 1);      free_stack(common, 1);
8386    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rminlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, rmin_label);
8387    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
8388      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);      free_stack(common, bra == OP_BRAMINZERO ? 2 : 1);
8389    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
# Line 7794  else if (bra == OP_BRAZERO) Line 8397  else if (bra == OP_BRAZERO)
8397    }    }
8398  }  }
8399    
8400  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)
8401  {  {
8402  DEFINE_COMPILER;  DEFINE_COMPILER;
8403  int offset;  int offset;
# Line 7833  if (current->topbacktracks) Line 8436  if (current->topbacktracks)
8436  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));
8437  }  }
8438    
8439  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)
8440  {  {
8441  assert_backtrack backtrack;  assert_backtrack backtrack;
8442    
# Line 7857  else Line 8460  else
8460  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8461  }  }
8462    
8463    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8464    {
8465    DEFINE_COMPILER;
8466    pcre_uchar opcode = *current->cc;
8467    struct sljit_label *loop;
8468    struct sljit_jump *jump;
8469    
8470    if (opcode == OP_THEN || opcode == OP_THEN_ARG)
8471      {
8472      if (common->then_trap != NULL)
8473        {
8474        SLJIT_ASSERT(common->control_head_ptr != 0);
8475    
8476        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8477        OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8478        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8479        jump = JUMP(SLJIT_JUMP);
8480    
8481        loop = LABEL();
8482        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8483        JUMPHERE(jump);
8484        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8485        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8486        add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8487        return;
8488        }
8489      else if (common->positive_assert)
8490        {
8491        add_jump(compiler, &common->positive_assert_quit, JUMP(SLJIT_JUMP));
8492        return;
8493        }
8494      }
8495    
8496    if (common->local_exit)
8497      {
8498      if (common->quit_label == NULL)
8499        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8500      else
8501        JUMPTO(SLJIT_JUMP, common->quit_label);
8502      return;
8503      }
8504    
8505    if (opcode == OP_SKIP_ARG)
8506      {
8507      SLJIT_ASSERT(common->control_head_ptr != 0);
8508      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8509      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8510      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8511      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8512      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8513    
8514      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8515      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8516      return;
8517      }
8518    
8519    if (opcode == OP_SKIP)
8520      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8521    else
8522      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8523    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8524    }
8525    
8526    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8527    {
8528    DEFINE_COMPILER;
8529    struct sljit_jump *jump;
8530    int size;
8531    
8532    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8533      {
8534      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8535      return;
8536      }
8537    
8538    size = CURRENT_AS(then_trap_backtrack)->framesize;
8539    size = 3 + (size < 0 ? 0 : size);
8540    
8541    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8542    free_stack(common, size);
8543    jump = JUMP(SLJIT_JUMP);
8544    
8545    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8546    /* STACK_TOP is set by THEN. */
8547    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8548      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8549    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8550    free_stack(common, 3);
8551    
8552    JUMPHERE(jump);
8553    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8554    }
8555    
8556  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8557  {  {
8558  DEFINE_COMPILER;  DEFINE_COMPILER;
8559    then_trap_backtrack *save_then_trap = common->then_trap;
8560    
8561  while (current)  while (current)
8562    {    {
# Line 7948  while (current) Line 8645  while (current)
8645    
8646      case OP_REF:      case OP_REF:
8647      case OP_REFI:      case OP_REFI:
8648        case OP_DNREF:
8649        case OP_DNREFI:
8650      compile_ref_iterator_backtrackingpath(common, current);      compile_ref_iterator_backtrackingpath(common, current);
8651      break;      break;
8652    
# Line 7993  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 8013  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 8027  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 8049  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 8074  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 8097  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 8115  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 8143  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 8200  else Line 8941  else
8941  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
8942  common->ctypes = (sljit_sw)(tables + ctypes_offset);  common->ctypes = (sljit_sw)(tables + ctypes_offset);
8943  common->digits[0] = -2;  common->digits[0] = -2;
8944  common->name_table = (sljit_sw)((pcre_uchar *)re + re->name_table_offset);  common->name_table = ((pcre_uchar *)re) + re->name_table_offset;
8945  common->name_count = re->name_count;  common->name_count = re->name_count;
8946  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
8947  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
# Line 8214  common->use_ucp = (re->options & PCRE_UC Line 8955  common->use_ucp = (re->options & PCRE_UC
8955  ccend = bracketend(rootbacktrack.cc);  ccend = bracketend(rootbacktrack.cc);
8956    
8957  /* Calculate the local space size on the stack. */  /* Calculate the local space size on the stack. */
8958  common->ovector_start = CALL_LIMIT + sizeof(sljit_sw);  common->ovector_start = LIMIT_MATCH + sizeof(sljit_sw);
8959  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8960  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8961    return;    return;
# Line 8229  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 8245  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 8257  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 8305  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 9087  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
9087  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9088  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
9089  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
9090  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit));  OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, limit_match));
9091  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
9092  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
9093  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH, 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, -1);    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 8330  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 8342  if (common->req_char_ptr != 0) Line 9132  if (common->req_char_ptr != 0)
9132  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(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, COUNT_MATCH, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LIMIT_MATCH);
 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, -1);    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 8367  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 8395  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);