/[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 1245 by zherczeg, Sat Feb 9 11:30:51 2013 UTC revision 1282 by zherczeg, Fri Mar 15 08:01:41 2013 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2012 University of Cambridge             Copyright (c) 1997-2013 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2012                        Copyright (c) 2010-2013
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68    /* Defines for debugging purposes. */
69    
70    /* 1 - Use unoptimized capturing brackets.
71       2 - Enable capture_last_ptr (includes option 1). */
72    /* #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 159  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      int real_offset_count;
172    int offset_count;    int offset_count;
173    int call_limit;    int call_limit;
174    pcre_uint8 notbol;    pcre_uint8 notbol;
# Line 180  typedef struct jump_list { Line 190  typedef struct jump_list {
190    struct jump_list *next;    struct jump_list *next;
191  } jump_list;  } jump_list;
192    
 enum stub_types { stack_alloc };  
   
193  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   int data;  
194    struct sljit_jump *start;    struct sljit_jump *start;
195    struct sljit_label *quit;    struct sljit_label *quit;
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199    enum bytecode_flag_types {
200      flag_optimized_cbracket = 1,
201      flag_then_start = 2,
202    };
203    
204    enum frame_types {
205      no_frame = -1,
206      no_stack = -2
207    };
208    
209    enum control_types {
210      type_commit = 0,
211      type_prune = 1,
212      type_skip = 2,
213      type_skip_arg = 3,
214      type_mark = 4,
215      type_then_trap = 5
216    };
217    
218  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
219    
220  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
# Line 210  typedef struct backtrack_common { Line 235  typedef struct backtrack_common {
235  typedef struct assert_backtrack {  typedef struct assert_backtrack {
236    backtrack_common common;    backtrack_common common;
237    jump_list *condfailed;    jump_list *condfailed;
238    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
239    int framesize;    int framesize;
240    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
241    int private_data_ptr;    int private_data_ptr;
# Line 231  typedef struct bracket_backtrack { Line 256  typedef struct bracket_backtrack {
256      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
257      jump_list *condfailed;      jump_list *condfailed;
258      assert_backtrack *assert;      assert_backtrack *assert;
259      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
260      int framesize;      int framesize;
261    } u;    } u;
262    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 266  typedef struct recurse_entry { Line 291  typedef struct recurse_entry {
291    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
292    jump_list *calls;    jump_list *calls;
293    /* Points to the starting opcode. */    /* Points to the starting opcode. */
294    int start;    sljit_sw start;
295  } recurse_entry;  } recurse_entry;
296    
297  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
298    backtrack_common common;    backtrack_common common;
299      BOOL inlined_pattern;
300  } recurse_backtrack;  } recurse_backtrack;
301    
302    #define OP_THEN_TRAP OP_TABLE_LENGTH
303    
304    typedef struct then_trap_backtrack {
305      backtrack_common common;
306      /* If then_trap is not NULL, this structure contains the real
307      then_trap for the backtracking path. */
308      struct then_trap_backtrack *then_trap;
309      /* Points to the starting opcode. */
310      sljit_sw start;
311      /* Exit point for the then opcodes of this alternative. */
312      jump_list *quit;
313      /* Frame size of the current alternative. */
314      int framesize;
315    } then_trap_backtrack;
316    
317  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
318    
319  typedef struct compiler_common {  typedef struct compiler_common {
320      /* The sljit ceneric compiler. */
321    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
322      /* First byte code. */
323    pcre_uchar *start;    pcre_uchar *start;
   
324    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
325    int *private_data_ptrs;    int *private_data_ptrs;
326    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
327    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
328      /* Tells whether the starting offset is a target of then. */
329      pcre_uint8 *then_offsets;
330      /* Current position where a THEN must jump. */
331      then_trap_backtrack *then_trap;
332    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
333    int cbraptr;    int cbra_ptr;
334    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
335    int ovector_start;    int ovector_start;
336    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
337    int req_char_ptr;    int req_char_ptr;
# Line 299  typedef struct compiler_common { Line 345  typedef struct compiler_common {
345    int first_line_end;    int first_line_end;
346    /* Points to the marked string. */    /* Points to the marked string. */
347    int mark_ptr;    int mark_ptr;
348      /* Recursive control verb management chain. */
349      int control_head_ptr;
350    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
351    int capture_last_ptr;    int capture_last_ptr;
352      /* Points to the starting position of the current match. */
353      int start_ptr;
354    
355    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
356    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
357    sljit_sw lcc;    sljit_sw lcc;
358    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
359    int mode;    int mode;
360      /* \K is found in the pattern. */
361      BOOL has_set_som;
362      /* (*SKIP:arg) is found in the pattern. */
363      BOOL has_skip_arg;
364      /* (*THEN) is found in the pattern. */
365      BOOL has_then;
366      /* Needs to know the start position anytime. */
367      BOOL needs_start_ptr;
368      /* Currently in recurse or assert. */
369      BOOL local_exit;
370    /* Newline control. */    /* Newline control. */
371    int nltype;    int nltype;
372    int newline;    int newline;
373    int bsr_nltype;    int bsr_nltype;
374    /* Dollar endonly. */    /* Dollar endonly. */
375    int endonly;    int endonly;
   BOOL has_set_som;  
376    /* Tables. */    /* Tables. */
377    sljit_sw ctypes;    sljit_sw ctypes;
378    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 343  typedef struct compiler_common { Line 402  typedef struct compiler_common {
402    jump_list *vspace;    jump_list *vspace;
403    jump_list *casefulcmp;    jump_list *casefulcmp;
404    jump_list *caselesscmp;    jump_list *caselesscmp;
405      jump_list *reset_match;
406    BOOL jscript_compat;    BOOL jscript_compat;
407  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
408    BOOL utf;    BOOL utf;
# Line 395  typedef struct compare_context { Line 455  typedef struct compare_context {
455  #endif  #endif
456  } compare_context;  } compare_context;
457    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
458  /* Undefine sljit macros. */  /* Undefine sljit macros. */
459  #undef CMP  #undef CMP
460    
# Line 433  group contains the start / end character Line 487  group contains the start / end character
487  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. */
488  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
489  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
490  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
491  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
492    
493  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 464  the start pointers when the end of the c Line 518  the start pointers when the end of the c
518    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
519  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
520    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
521    #define SET_LABEL(jump, label) \
522      sljit_set_label((jump), (label))
523  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
524    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
525  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
# Line 488  return cc; Line 544  return cc;
544   set_private_data_ptrs   set_private_data_ptrs
545   get_framesize   get_framesize
546   init_frame   init_frame
547   get_private_data_length_for_copy   get_private_data_copy_length
548   copy_private_data   copy_private_data
549   compile_matchingpath   compile_matchingpath
550   compile_backtrackingpath   compile_backtrackingpath
# Line 512  switch(*cc) Line 568  switch(*cc)
568    case OP_WORDCHAR:    case OP_WORDCHAR:
569    case OP_ANY:    case OP_ANY:
570    case OP_ALLANY:    case OP_ALLANY:
571      case OP_NOTPROP:
572      case OP_PROP:
573    case OP_ANYNL:    case OP_ANYNL:
574    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
575    case OP_HSPACE:    case OP_HSPACE:
# Line 524  switch(*cc) Line 582  switch(*cc)
582    case OP_CIRCM:    case OP_CIRCM:
583    case OP_DOLL:    case OP_DOLL:
584    case OP_DOLLM:    case OP_DOLLM:
   case OP_TYPESTAR:  
   case OP_TYPEMINSTAR:  
   case OP_TYPEPLUS:  
   case OP_TYPEMINPLUS:  
   case OP_TYPEQUERY:  
   case OP_TYPEMINQUERY:  
   case OP_TYPEPOSSTAR:  
   case OP_TYPEPOSPLUS:  
   case OP_TYPEPOSQUERY:  
585    case OP_CRSTAR:    case OP_CRSTAR:
586    case OP_CRMINSTAR:    case OP_CRMINSTAR:
587    case OP_CRPLUS:    case OP_CRPLUS:
588    case OP_CRMINPLUS:    case OP_CRMINPLUS:
589    case OP_CRQUERY:    case OP_CRQUERY:
590    case OP_CRMINQUERY:    case OP_CRMINQUERY:
591      case OP_CRRANGE:
592      case OP_CRMINRANGE:
593      case OP_CLASS:
594      case OP_NCLASS:
595      case OP_REF:
596      case OP_REFI:
597      case OP_RECURSE:
598      case OP_CALLOUT:
599      case OP_ALT:
600      case OP_KET:
601      case OP_KETRMAX:
602      case OP_KETRMIN:
603      case OP_KETRPOS:
604      case OP_REVERSE:
605      case OP_ASSERT:
606      case OP_ASSERT_NOT:
607      case OP_ASSERTBACK:
608      case OP_ASSERTBACK_NOT:
609      case OP_ONCE:
610      case OP_ONCE_NC:
611      case OP_BRA:
612      case OP_BRAPOS:
613      case OP_CBRA:
614      case OP_CBRAPOS:
615      case OP_COND:
616      case OP_SBRA:
617      case OP_SBRAPOS:
618      case OP_SCBRA:
619      case OP_SCBRAPOS:
620      case OP_SCOND:
621      case OP_CREF:
622      case OP_NCREF:
623      case OP_RREF:
624      case OP_NRREF:
625    case OP_DEF:    case OP_DEF:
626    case OP_BRAZERO:    case OP_BRAZERO:
627    case OP_BRAMINZERO:    case OP_BRAMINZERO:
628    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
629      case OP_PRUNE:
630      case OP_SKIP:
631      case OP_THEN:
632    case OP_COMMIT:    case OP_COMMIT:
633    case OP_FAIL:    case OP_FAIL:
634    case OP_ACCEPT:    case OP_ACCEPT:
635    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
636      case OP_CLOSE:
637    case OP_SKIPZERO:    case OP_SKIPZERO:
638    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
639    
640    case OP_CHAR:    case OP_CHAR:
641    case OP_CHARI:    case OP_CHARI:
# Line 566  switch(*cc) Line 647  switch(*cc)
647    case OP_MINPLUS:    case OP_MINPLUS:
648    case OP_QUERY:    case OP_QUERY:
649    case OP_MINQUERY:    case OP_MINQUERY:
650      case OP_UPTO:
651      case OP_MINUPTO:
652      case OP_EXACT:
653    case OP_POSSTAR:    case OP_POSSTAR:
654    case OP_POSPLUS:    case OP_POSPLUS:
655    case OP_POSQUERY:    case OP_POSQUERY:
656      case OP_POSUPTO:
657    case OP_STARI:    case OP_STARI:
658    case OP_MINSTARI:    case OP_MINSTARI:
659    case OP_PLUSI:    case OP_PLUSI:
660    case OP_MINPLUSI:    case OP_MINPLUSI:
661    case OP_QUERYI:    case OP_QUERYI:
662    case OP_MINQUERYI:    case OP_MINQUERYI:
663      case OP_UPTOI:
664      case OP_MINUPTOI:
665      case OP_EXACTI:
666    case OP_POSSTARI:    case OP_POSSTARI:
667    case OP_POSPLUSI:    case OP_POSPLUSI:
668    case OP_POSQUERYI:    case OP_POSQUERYI:
669      case OP_POSUPTOI:
670    case OP_NOTSTAR:    case OP_NOTSTAR:
671    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
672    case OP_NOTPLUS:    case OP_NOTPLUS:
673    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
674    case OP_NOTQUERY:    case OP_NOTQUERY:
675    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
676      case OP_NOTUPTO:
677      case OP_NOTMINUPTO:
678      case OP_NOTEXACT:
679    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
680    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
681    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
682      case OP_NOTPOSUPTO:
683    case OP_NOTSTARI:    case OP_NOTSTARI:
684    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
685    case OP_NOTPLUSI:    case OP_NOTPLUSI:
686    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
687    case OP_NOTQUERYI:    case OP_NOTQUERYI:
688    case OP_NOTMINQUERYI:    case OP_NOTMINQUERYI:
   case OP_NOTPOSSTARI:  
   case OP_NOTPOSPLUSI:  
   case OP_NOTPOSQUERYI:  
   cc += 2;  
 #ifdef SUPPORT_UTF  
   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
   return cc;  
   
   case OP_UPTO:  
   case OP_MINUPTO:  
   case OP_EXACT:  
   case OP_POSUPTO:  
   case OP_UPTOI:  
   case OP_MINUPTOI:  
   case OP_EXACTI:  
   case OP_POSUPTOI:  
   case OP_NOTUPTO:  
   case OP_NOTMINUPTO:  
   case OP_NOTEXACT:  
   case OP_NOTPOSUPTO:  
689    case OP_NOTUPTOI:    case OP_NOTUPTOI:
690    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
691    case OP_NOTEXACTI:    case OP_NOTEXACTI:
692      case OP_NOTPOSSTARI:
693      case OP_NOTPOSPLUSI:
694      case OP_NOTPOSQUERYI:
695    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
696    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
697  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
698    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
699  #endif  #endif
700    return cc;    return cc;
701    
702    case OP_NOTPROP:    /* Special cases. */
703    case OP_PROP:    case OP_TYPESTAR:
704    return cc + 1 + 2;    case OP_TYPEMINSTAR:
705      case OP_TYPEPLUS:
706      case OP_TYPEMINPLUS:
707      case OP_TYPEQUERY:
708      case OP_TYPEMINQUERY:
709    case OP_TYPEUPTO:    case OP_TYPEUPTO:
710    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
711    case OP_TYPEEXACT:    case OP_TYPEEXACT:
712      case OP_TYPEPOSSTAR:
713      case OP_TYPEPOSPLUS:
714      case OP_TYPEPOSQUERY:
715    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
716    case OP_REF:    return cc + PRIV(OP_lengths)[*cc] - 1;
   case OP_REFI:  
   case OP_CREF:  
   case OP_NCREF:  
   case OP_RREF:  
   case OP_NRREF:  
   case OP_CLOSE:  
   cc += 1 + IMM2_SIZE;  
   return cc;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   return cc + 1 + 2 * IMM2_SIZE;  
717    
718    case OP_CLASS:    case OP_ANYBYTE:
719    case OP_NCLASS:  #ifdef SUPPORT_UTF
720    return cc + 1 + 32 / sizeof(pcre_uchar);    if (common->utf) return NULL;
721    #endif
722      return cc + 1;
723    
724  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
725    case OP_XCLASS:    case OP_XCLASS:
726    return cc + GET(cc, 1);    return cc + GET(cc, 1);
727  #endif  #endif
728    
   case OP_RECURSE:  
   case OP_ASSERT:  
   case OP_ASSERT_NOT:  
   case OP_ASSERTBACK:  
   case OP_ASSERTBACK_NOT:  
   case OP_REVERSE:  
   case OP_ONCE:  
   case OP_ONCE_NC:  
   case OP_BRA:  
   case OP_BRAPOS:  
   case OP_COND:  
   case OP_SBRA:  
   case OP_SBRAPOS:  
   case OP_SCOND:  
   case OP_ALT:  
   case OP_KET:  
   case OP_KETRMAX:  
   case OP_KETRMIN:  
   case OP_KETRPOS:  
   return cc + 1 + LINK_SIZE;  
   
   case OP_CBRA:  
   case OP_CBRAPOS:  
   case OP_SCBRA:  
   case OP_SCBRAPOS:  
   return cc + 1 + LINK_SIZE + IMM2_SIZE;  
   
729    case OP_MARK:    case OP_MARK:
730      case OP_PRUNE_ARG:
731      case OP_SKIP_ARG:
732      case OP_THEN_ARG:
733    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
734    
   case OP_CALLOUT:  
   return cc + 2 + 2 * LINK_SIZE;  
   
735    default:    default:
736      /* All opcodes are supported now! */
737      SLJIT_ASSERT_STOP();
738    return NULL;    return NULL;
739    }    }
740  }  }
# Line 937  while (cc < ccend) Line 983  while (cc < ccend)
983      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
984      break;      break;
985    
986        case OP_THEN_ARG:
987        common->has_then = TRUE;
988        /* Fall through. */
989    
990        case OP_PRUNE_ARG:
991        common->needs_start_ptr = TRUE;
992        common->control_head_ptr = 1;
993        /* Fall through. */
994    
995      case OP_MARK:      case OP_MARK:
996      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
997        {        {
# Line 946  while (cc < ccend) Line 1001  while (cc < ccend)
1001      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1002      break;      break;
1003    
1004        case OP_THEN:
1005        common->has_then = TRUE;
1006        /* Fall through. */
1007    
1008        case OP_PRUNE:
1009        case OP_SKIP:
1010        common->needs_start_ptr = TRUE;
1011        common->control_head_ptr = 1;
1012        cc += 1;
1013        break;
1014    
1015        case OP_SKIP_ARG:
1016        common->control_head_ptr = 1;
1017        common->has_skip_arg = TRUE;
1018        cc += 1 + 2 + cc[1];
1019        break;
1020    
1021      default:      default:
1022      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1023      if (cc == NULL)      if (cc == NULL)
# Line 1122  while (cc < ccend) Line 1194  while (cc < ccend)
1194    }    }
1195  }  }
1196    
1197  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1198  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)
1199  {  {
 pcre_uchar *ccend = bracketend(cc);  
1200  int length = 0;  int length = 0;
1201  BOOL possessive = FALSE;  int possessive = 0;
1202    BOOL stack_restore = FALSE;
1203  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1204  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1205    /* The last capture is a local variable even for recursions. */
1206    BOOL capture_last_found = FALSE;
1207    
1208    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1209    SLJIT_ASSERT(common->control_head_ptr != 0);
1210    *needs_control_head = TRUE;
1211    #else
1212    *needs_control_head = FALSE;
1213    #endif
1214    
1215  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (ccend == NULL)
1216    {    {
1217    length = 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1218    possessive = TRUE;    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1219        {
1220        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1221        /* This is correct regardless of common->capture_last_ptr. */
1222        capture_last_found = TRUE;
1223        }
1224      cc = next_opcode(common, cc);
1225    }    }
1226    
 cc = next_opcode(common, cc);  
1227  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1228  while (cc < ccend)  while (cc < ccend)
1229    switch(*cc)    switch(*cc)
1230      {      {
1231      case OP_SET_SOM:      case OP_SET_SOM:
1232      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1233        stack_restore = TRUE;
1234      if (!setsom_found)      if (!setsom_found)
1235        {        {
1236        length += 2;        length += 2;
# Line 1153  while (cc < ccend) Line 1240  while (cc < ccend)
1240      break;      break;
1241    
1242      case OP_MARK:      case OP_MARK:
1243        case OP_PRUNE_ARG:
1244        case OP_THEN_ARG:
1245      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1246        stack_restore = TRUE;
1247      if (!setmark_found)      if (!setmark_found)
1248        {        {
1249        length += 2;        length += 2;
1250        setmark_found = TRUE;        setmark_found = TRUE;
1251        }        }
1252        if (common->control_head_ptr != 0)
1253          *needs_control_head = TRUE;
1254      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1255      break;      break;
1256    
1257      case OP_RECURSE:      case OP_RECURSE:
1258        stack_restore = TRUE;
1259      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1260        {        {
1261        length += 2;        length += 2;
# Line 1173  while (cc < ccend) Line 1266  while (cc < ccend)
1266        length += 2;        length += 2;
1267        setmark_found = TRUE;        setmark_found = TRUE;
1268        }        }
1269        if (common->capture_last_ptr != 0 && !capture_last_found)
1270          {
1271          length += 2;
1272          capture_last_found = TRUE;
1273          }
1274      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1275      break;      break;
1276    
# Line 1180  while (cc < ccend) Line 1278  while (cc < ccend)
1278      case OP_CBRAPOS:      case OP_CBRAPOS:
1279      case OP_SCBRA:      case OP_SCBRA:
1280      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1281        stack_restore = TRUE;
1282        if (common->capture_last_ptr != 0 && !capture_last_found)
1283          {
1284          length += 2;
1285          capture_last_found = TRUE;
1286          }
1287      length += 3;      length += 3;
1288      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1289      break;      break;
1290    
1291        case OP_PRUNE:
1292        case OP_SKIP:
1293        case OP_SKIP_ARG:
1294        case OP_COMMIT:
1295        if (common->control_head_ptr != 0)
1296          *needs_control_head = TRUE;
1297        /* Fall through. */
1298    
1299      default:      default:
1300        stack_restore = TRUE;
1301        /* Fall through. */
1302    
1303        case OP_NOT_WORD_BOUNDARY:
1304        case OP_WORD_BOUNDARY:
1305        case OP_NOT_DIGIT:
1306        case OP_DIGIT:
1307        case OP_NOT_WHITESPACE:
1308        case OP_WHITESPACE:
1309        case OP_NOT_WORDCHAR:
1310        case OP_WORDCHAR:
1311        case OP_ANY:
1312        case OP_ALLANY:
1313        case OP_ANYBYTE:
1314        case OP_NOTPROP:
1315        case OP_PROP:
1316        case OP_ANYNL:
1317        case OP_NOT_HSPACE:
1318        case OP_HSPACE:
1319        case OP_NOT_VSPACE:
1320        case OP_VSPACE:
1321        case OP_EXTUNI:
1322        case OP_EODN:
1323        case OP_EOD:
1324        case OP_CIRC:
1325        case OP_CIRCM:
1326        case OP_DOLL:
1327        case OP_DOLLM:
1328        case OP_CHAR:
1329        case OP_CHARI:
1330        case OP_NOT:
1331        case OP_NOTI:
1332    
1333        case OP_EXACT:
1334        case OP_POSSTAR:
1335        case OP_POSPLUS:
1336        case OP_POSQUERY:
1337        case OP_POSUPTO:
1338    
1339        case OP_EXACTI:
1340        case OP_POSSTARI:
1341        case OP_POSPLUSI:
1342        case OP_POSQUERYI:
1343        case OP_POSUPTOI:
1344    
1345        case OP_NOTEXACT:
1346        case OP_NOTPOSSTAR:
1347        case OP_NOTPOSPLUS:
1348        case OP_NOTPOSQUERY:
1349        case OP_NOTPOSUPTO:
1350    
1351        case OP_NOTEXACTI:
1352        case OP_NOTPOSSTARI:
1353        case OP_NOTPOSPLUSI:
1354        case OP_NOTPOSQUERYI:
1355        case OP_NOTPOSUPTOI:
1356    
1357        case OP_TYPEEXACT:
1358        case OP_TYPEPOSSTAR:
1359        case OP_TYPEPOSPLUS:
1360        case OP_TYPEPOSQUERY:
1361        case OP_TYPEPOSUPTO:
1362    
1363        case OP_CLASS:
1364        case OP_NCLASS:
1365        case OP_XCLASS:
1366    
1367      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1368      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1369      break;      break;
1370      }      }
1371    
1372  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1373  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1374    return -1;    return stack_restore ? no_frame : no_stack;
1375    
1376  if (length > 0)  if (length > 0)
1377    return length + 1;    return length + 1;
1378  return -1;  return stack_restore ? no_frame : no_stack;
1379  }  }
1380    
1381  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)
1382  {  {
1383  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc);  
1384  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1385  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1386    /* The last capture is a local variable even for recursions. */
1387    BOOL capture_last_found = FALSE;
1388  int offset;  int offset;
1389    
1390  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1212  SLJIT_UNUSED_ARG(stacktop); Line 1392  SLJIT_UNUSED_ARG(stacktop);
1392  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1393    
1394  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1395  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1396    cc = next_opcode(common, cc);    {
1397      ccend = bracketend(cc) - (1 + LINK_SIZE);
1398      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1399        cc = next_opcode(common, cc);
1400      }
1401    
1402  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1403  while (cc < ccend)  while (cc < ccend)
1404    switch(*cc)    switch(*cc)
# Line 1223  while (cc < ccend) Line 1408  while (cc < ccend)
1408      if (!setsom_found)      if (!setsom_found)
1409        {        {
1410        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1411        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1412        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1413        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1414        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1233  while (cc < ccend) Line 1418  while (cc < ccend)
1418      break;      break;
1419    
1420      case OP_MARK:      case OP_MARK:
1421        case OP_PRUNE_ARG:
1422        case OP_THEN_ARG:
1423      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1424      if (!setmark_found)      if (!setmark_found)
1425        {        {
1426        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1427        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1428        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1429        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1430        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1250  while (cc < ccend) Line 1437  while (cc < ccend)
1437      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1438        {        {
1439        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1440        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1441        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1442        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1443        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1259  while (cc < ccend) Line 1446  while (cc < ccend)
1446      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1447        {        {
1448        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1449        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1450        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1451        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1452        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1453        setmark_found = TRUE;        setmark_found = TRUE;
1454        }        }
1455        if (common->capture_last_ptr != 0 && !capture_last_found)
1456          {
1457          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1458          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1459          stackpos += (int)sizeof(sljit_sw);
1460          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1461          stackpos += (int)sizeof(sljit_sw);
1462          capture_last_found = TRUE;
1463          }
1464      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1465      break;      break;
1466    
# Line 1272  while (cc < ccend) Line 1468  while (cc < ccend)
1468      case OP_CBRAPOS:      case OP_CBRAPOS:
1469      case OP_SCBRA:      case OP_SCBRA:
1470      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1471        if (common->capture_last_ptr != 0 && !capture_last_found)
1472          {
1473          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1474          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1475          stackpos += (int)sizeof(sljit_sw);
1476          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1477          stackpos += (int)sizeof(sljit_sw);
1478          capture_last_found = TRUE;
1479          }
1480      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1481      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1482      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
# Line 1291  while (cc < ccend) Line 1496  while (cc < ccend)
1496      break;      break;
1497      }      }
1498    
1499  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1500  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1501  }  }
1502    
1503  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)
1504  {  {
1505  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1506  int size;  int size;
1507  pcre_uchar *alternative;  pcre_uchar *alternative;
1508  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1410  return private_data_length; Line 1615  return private_data_length;
1615  }  }
1616    
1617  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,
1618    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1619  {  {
1620  DEFINE_COMPILER;  DEFINE_COMPILER;
1621  int srcw[2];  int srcw[2];
# Line 1431  stacktop = STACK(stacktop - 1); Line 1636  stacktop = STACK(stacktop - 1);
1636    
1637  if (!save)  if (!save)
1638    {    {
1639    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1640    if (stackptr < stacktop)    if (stackptr < stacktop)
1641      {      {
1642      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1447  if (!save) Line 1652  if (!save)
1652    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1653    }    }
1654    
1655  while (status != end)  do
1656    {    {
1657    count = 0;    count = 0;
1658    switch(status)    switch(status)
# Line 1456  while (status != end) Line 1661  while (status != end)
1661      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1662      count = 1;      count = 1;
1663      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1664        if (needs_control_head)
1665          {
1666          SLJIT_ASSERT(common->control_head_ptr != 0);
1667          count = 2;
1668          srcw[1] = common->control_head_ptr;
1669          }
1670      status = loop;      status = loop;
1671      break;      break;
1672    
# Line 1680  while (status != end) Line 1891  while (status != end)
1891        }        }
1892      }      }
1893    }    }
1894    while (status != end);
1895    
1896  if (save)  if (save)
1897    {    {
# Line 1713  if (save) Line 1925  if (save)
1925  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1926  }  }
1927    
1928    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1929    {
1930    pcre_uchar *end = bracketend(cc);
1931    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1932    
1933    /* Assert captures then. */
1934    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1935      current_offset = NULL;
1936    /* Conditional block does not. */
1937    if (*cc == OP_COND || *cc == OP_SCOND)
1938      has_alternatives = FALSE;
1939    
1940    cc = next_opcode(common, cc);
1941    if (has_alternatives)
1942      current_offset = common->then_offsets + (cc - common->start);
1943    
1944    while (cc < end)
1945      {
1946      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1947        cc = set_then_offsets(common, cc, current_offset);
1948      else
1949        {
1950        if (*cc == OP_ALT && has_alternatives)
1951          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1952        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1953          *current_offset = 1;
1954        cc = next_opcode(common, cc);
1955        }
1956      }
1957    
1958    return end;
1959    }
1960    
1961  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1962  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1963  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1731  while (list) Line 1976  while (list)
1976    {    {
1977    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1978    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1979    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1980    list = list->next;    list = list->next;
1981    }    }
1982  }  }
# Line 1747  if (list_item) Line 1992  if (list_item)
1992    }    }
1993  }  }
1994    
1995  static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)  static void add_stub(compiler_common *common, struct sljit_jump *start)
1996  {  {
1997  DEFINE_COMPILER;  DEFINE_COMPILER;
1998  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1999    
2000  if (list_item)  if (list_item)
2001    {    {
   list_item->type = type;  
   list_item->data = data;  
2002    list_item->start = start;    list_item->start = start;
2003    list_item->quit = LABEL();    list_item->quit = LABEL();
2004    list_item->next = common->stubs;    list_item->next = common->stubs;
# Line 1771  stub_list* list_item = common->stubs; Line 2014  stub_list* list_item = common->stubs;
2014  while (list_item)  while (list_item)
2015    {    {
2016    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
2017    switch(list_item->type)    add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
     {  
     case stack_alloc:  
     add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));  
     break;  
     }  
2018    JUMPTO(SLJIT_JUMP, list_item->quit);    JUMPTO(SLJIT_JUMP, list_item->quit);
2019    list_item = list_item->next;    list_item = list_item->next;
2020    }    }
# Line 1804  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 2042  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2042  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
2043  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2044  #endif  #endif
2045  add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));  add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
2046  }  }
2047    
2048  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
# Line 1813  DEFINE_COMPILER; Line 2051  DEFINE_COMPILER;
2051  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
2052  }  }
2053    
2054  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
2055    {
2056    DEFINE_COMPILER;
2057    struct sljit_label *loop;
2058    int i;
2059    
2060    /* At this point we can freely use all temporary registers. */
2061    SLJIT_ASSERT(length > 1);
2062    /* TMP1 returns with begin - 1. */
2063    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2064    if (length < 8)
2065      {
2066      for (i = 1; i < length; i++)
2067        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2068      }
2069    else
2070      {
2071      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2072      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2073      loop = LABEL();
2074      OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2075      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
2076      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2077      }
2078    }
2079    
2080    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2081    {
2082    DEFINE_COMPILER;
2083    struct sljit_label *loop;
2084    int i;
2085    
2086    SLJIT_ASSERT(length > 1);
2087    /* OVECTOR(1) contains the "string begin - 1" constant. */
2088    if (length > 2)
2089      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2090    if (length < 8)
2091      {
2092      for (i = 2; i < length; i++)
2093        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2094      }
2095    else
2096      {
2097      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2098      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2099      loop = LABEL();
2100      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2101      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2102      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2103      }
2104    
2105    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2106    if (common->mark_ptr != 0)
2107      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2108    SLJIT_ASSERT(common->control_head_ptr != 0);
2109    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2110    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2111    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2112    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2113    }
2114    
2115    static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2116    {
2117    sljit_sw return_value = 0;
2118    const pcre_uchar *skip_arg = NULL;
2119    
2120    SLJIT_ASSERT(current != NULL);
2121    do
2122      {
2123      switch (current[-2])
2124        {
2125        case type_commit:
2126        /* Commit overwrites all. */
2127        return -1;
2128    
2129        case type_prune:
2130        case type_then_trap:
2131        break;
2132    
2133        case type_skip:
2134        /* Overwrites prune, but not other skips. */
2135        if (return_value == 0 && skip_arg == NULL)
2136          return_value = current[-3];
2137        break;
2138    
2139        case type_skip_arg:
2140        if (return_value == 0 && skip_arg == NULL)
2141          skip_arg = (pcre_uchar *)current[-3];
2142        break;
2143    
2144        case type_mark:
2145        if (return_value == 0 && skip_arg != NULL)
2146          if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2147            return_value = current[-4];
2148        break;
2149    
2150        default:
2151        SLJIT_ASSERT_STOP();
2152        break;
2153        }
2154      current = (sljit_sw*)current[-1];
2155      }
2156    while (current != NULL);
2157    return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2158    }
2159    
2160    static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)
2161  {  {
2162  DEFINE_COMPILER;  do
 struct sljit_label *loop;  
 int i;  
 /* At this point we can freely use all temporary registers. */  
 /* TMP1 returns with begin - 1. */  
 OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  
 if (length < 8)  
   {  
   for (i = 0; i < length; i++)  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);  
   }  
 else  
2163    {    {
2164    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    switch (current[-2])
2165    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);      {
2166    loop = LABEL();      case type_commit:
2167    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);      /* Commit overwrites all. */
2168    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);      return 0;
2169    JUMPTO(SLJIT_C_NOT_ZERO, loop);  
2170        case type_then_trap:
2171        if (current[-3] == start)
2172          return (sljit_sw)current;
2173        break;
2174    
2175        case type_prune:
2176        case type_skip:
2177        case type_skip_arg:
2178        case type_mark:
2179        break;
2180    
2181        default:
2182        SLJIT_ASSERT_STOP();
2183        break;
2184        }
2185      current = (sljit_sw*)current[-1];
2186      SLJIT_ASSERT(current != NULL);
2187    }    }
2188    while (TRUE);
2189  }  }
2190    
2191  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
# Line 1890  else Line 2241  else
2241  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
2242  {  {
2243  DEFINE_COMPILER;  DEFINE_COMPILER;
2244    struct sljit_jump *jump;
2245    
2246  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);
2247  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
2248      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2249    
2250  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2251  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2252  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offset_count));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2253  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
2254    
2255  /* Store match begin and end. */  /* Store match begin and end. */
2256  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
2257  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));
2258    
2259    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2260    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);
2261    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2262    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2263    #endif
2264    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2265    JUMPHERE(jump);
2266    
2267  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
2268  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
2269  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 2078  else if (common->mode == JIT_PARTIAL_SOF Line 2440  else if (common->mode == JIT_PARTIAL_SOF
2440    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2441    
2442  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2443    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2444  else  else
2445    {    {
2446    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2091  if (jump != NULL) Line 2453  if (jump != NULL)
2453    JUMPHERE(jump);    JUMPHERE(jump);
2454  }  }
2455    
2456  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2457  {  {
2458  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2459  DEFINE_COMPILER;  DEFINE_COMPILER;
2460  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2461    
2462  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2463    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2464      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2465      return;
2466      }
2467    
2468  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2469  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2470    {    {
2471    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2472    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2473    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2474    }    }
2475  else  else
2476    {    {
2477    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2478    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2479      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2480    else    else
2481      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2482    }    }
2483  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2484  }  }
2485    
2486  static void detect_partial_match(compiler_common *common, jump_list **backtracks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
# Line 2138  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR Line 2499  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2499  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2500  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2501    {    {
2502    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2503    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2504    }    }
2505  else  else
# Line 3060  GET_LOCAL_BASE(TMP3, 0, 0); Line 3421  GET_LOCAL_BASE(TMP3, 0, 0);
3421  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3422  mainloop = LABEL();  mainloop = LABEL();
3423  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3424  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
3425    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3426    
3427  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3428  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3429  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
# Line 3068  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I Line 3431  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
3431  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3432    
3433  JUMPHERE(jump);  JUMPHERE(jump);
3434  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3435  /* End of dropping frames. */  /* End of dropping frames. */
3436  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3437    
3438  JUMPHERE(jump);  JUMPHERE(jump);
3439  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3440  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3441  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
 if (common->mark_ptr != 0)  
   {  
   jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));  
   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
   JUMPTO(SLJIT_JUMP, mainloop);  
   
   JUMPHERE(jump);  
   }  
   
 /* Unknown command. */  
3442  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3443  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3444  }  }
# Line 3101  static void check_wordboundary(compiler_ Line 3447  static void check_wordboundary(compiler_
3447  {  {
3448  DEFINE_COMPILER;  DEFINE_COMPILER;
3449  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3450    jump_list *skipread_list = NULL;
3451  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3452  struct sljit_jump *jump;  struct sljit_jump *jump;
3453  #endif  #endif
# Line 3158  else Line 3505  else
3505  JUMPHERE(skipread);  JUMPHERE(skipread);
3506    
3507  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3508  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3509  peek_char(common);  peek_char(common);
3510    
3511  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3199  else Line 3546  else
3546      JUMPHERE(jump);      JUMPHERE(jump);
3547  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3548    }    }
3549  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3550    
3551  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3552  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 3839  while (*cc != XCL_END) Line 4186  while (*cc != XCL_END)
4186        break;        break;
4187    
4188        case PT_CLIST:        case PT_CLIST:
4189          case PT_UCNC:
4190        needschar = TRUE;        needschar = TRUE;
4191        break;        break;
4192    
# Line 4040  while (*cc != XCL_END) Line 4388  while (*cc != XCL_END)
4388        case PT_WORD:        case PT_WORD:
4389        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
4390        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4391        /* ... fall through */        /* Fall through. */
4392    
4393        case PT_ALNUM:        case PT_ALNUM:
4394        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
# Line 4104  while (*cc != XCL_END) Line 4452  while (*cc != XCL_END)
4452          }          }
4453        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4454        break;        break;
4455    
4456          case PT_UCNC:
4457          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
4458          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4459          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
4460          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4461          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
4462          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4463    
4464          SET_CHAR_OFFSET(0xa0);
4465          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4466          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4467          SET_CHAR_OFFSET(0);
4468          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4469          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4470          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4471          break;
4472        }        }
4473      cc += 2;      cc += 2;
4474      }      }
# Line 4129  int length; Line 4494  int length;
4494  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4495  compare_context context;  compare_context context;
4496  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4497    jump_list *end_list;
4498  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4499  struct sljit_label *label;  struct sljit_label *label;
4500  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4197  switch(type) Line 4563  switch(type)
4563    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4564      {      {
4565      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4566        end_list = NULL;
4567      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4568        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);        add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4569      else      else
4570        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4571    
4572      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4573      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4574      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4575      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4576      }      }
4577    else    else
# Line 4264  switch(type) Line 4630  switch(type)
4630    read_char(common);    read_char(common);
4631    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
4632    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4633      end_list = NULL;
4634    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4635      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4636    else    else
4637      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4638    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4639    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4640    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4641    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4642    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4643    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4644      set_jumps(end_list, LABEL());
4645    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4646    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4647    return cc;    return cc;
4648    
4649    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 5026  DEFINE_COMPILER; Line 5393  DEFINE_COMPILER;
5393  backtrack_common *backtrack;  backtrack_common *backtrack;
5394  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5395  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5396  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5397    pcre_uchar *start_cc;
5398    BOOL needs_control_head;
5399    
5400  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5401    
5402    /* Inlining simple patterns. */
5403    if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5404      {
5405      start_cc = common->start + start;
5406      compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
5407      BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
5408      return cc + 1 + LINK_SIZE;
5409      }
5410    
5411  while (entry != NULL)  while (entry != NULL)
5412    {    {
5413    if (entry->start == start)    if (entry->start == start)
# Line 5140  allocate_stack(common, CALLOUT_ARG_SIZE Line 5519  allocate_stack(common, CALLOUT_ARG_SIZE
5519  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);
5520  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5521  SLJIT_ASSERT(common->capture_last_ptr != 0);  SLJIT_ASSERT(common->capture_last_ptr != 0);
5522  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]);
5523  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);
5524    
5525  /* These pointer sized fields temporarly stores internal variables. */  /* These pointer sized fields temporarly stores internal variables. */
5526  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 5150  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA Line 5529  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA
5529    
5530  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
5531    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));
5532  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));
5533  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));
5534  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);
5535    
5536  /* Needed to save important temporary registers. */  /* Needed to save important temporary registers. */
# Line 5180  static pcre_uchar *compile_assert_matchi Line 5559  static pcre_uchar *compile_assert_matchi
5559  {  {
5560  DEFINE_COMPILER;  DEFINE_COMPILER;
5561  int framesize;  int framesize;
5562    int extrasize;
5563    BOOL needs_control_head;
5564  int private_data_ptr;  int private_data_ptr;
5565  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5566  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5189  jump_list *tmp = NULL; Line 5570  jump_list *tmp = NULL;
5570  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5571  jump_list **found;  jump_list **found;
5572  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5573    BOOL save_local_exit = common->local_exit;
5574    then_trap_backtrack *save_then_trap = common->then_trap;
5575  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5576  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5577  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
# Line 5196  jump_list *save_accept = common->accept; Line 5579  jump_list *save_accept = common->accept;
5579  struct sljit_jump *jump;  struct sljit_jump *jump;
5580  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5581    
5582    /* Assert captures then. */
5583    common->then_trap = NULL;
5584    
5585  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5586    {    {
5587    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5204  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5590  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5590    }    }
5591  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5592  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5593  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5594  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5595  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5596  opcode = *cc;  opcode = *cc;
# Line 5223  if (bra == OP_BRAMINZERO) Line 5609  if (bra == OP_BRAMINZERO)
5609    
5610  if (framesize < 0)  if (framesize < 0)
5611    {    {
5612    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5613    allocate_stack(common, 1);    if (framesize == no_frame)
5614        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5615      allocate_stack(common, extrasize);
5616      if (needs_control_head)
5617        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5618    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5619      if (needs_control_head)
5620        {
5621        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5622        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5623        }
5624    }    }
5625  else  else
5626    {    {
5627    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5628      allocate_stack(common, framesize + extrasize);
5629    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);
5630    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));
5631    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);
5632      if (needs_control_head)
5633        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5634    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5635    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5636    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5637        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5638        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5640        }
5641      else
5642        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5643      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5644    }    }
5645    
5646  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5647    common->local_exit = TRUE;
5648  common->quit_label = NULL;  common->quit_label = NULL;
5649  common->quit = NULL;  common->quit = NULL;
5650  while (1)  while (1)
# Line 5255  while (1) Line 5661  while (1)
5661    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5662    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5663      {      {
5664        common->local_exit = save_local_exit;
5665        common->then_trap = save_then_trap;
5666      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5667      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5668      common->quit = save_quit;      common->quit = save_quit;
# Line 5267  while (1) Line 5675  while (1)
5675    
5676    /* Reset stack. */    /* Reset stack. */
5677    if (framesize < 0)    if (framesize < 0)
5678      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5679    else {      if (framesize == no_frame)
5680          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5681        else
5682          free_stack(common, extrasize);
5683        if (needs_control_head)
5684          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5685        }
5686      else
5687        {
5688      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5689        {        {
5690        /* 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. */
5691        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));
5692          if (needs_control_head)
5693            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5694        }        }
5695      else      else
5696        {        {
5697        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);
5698          if (needs_control_head)
5699            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5700        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5701        }        }
5702    }      }
5703    
5704    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5705      {      {
5706      /* 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. */
5707      if (conditional)      if (conditional)
5708        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);
5709      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5710        {        {
5711        if (framesize < 0)        if (framesize < 0)
5712          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));
5713        else        else
5714          {          {
5715          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));
5716          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));
5717          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);
5718          }          }
5719        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 5310  while (1) Line 5730  while (1)
5730    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5731    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5732      {      {
5733        common->local_exit = save_local_exit;
5734        common->then_trap = save_then_trap;
5735      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5736      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5737      common->quit = save_quit;      common->quit = save_quit;
# Line 5324  while (1) Line 5746  while (1)
5746    ccbegin = cc;    ccbegin = cc;
5747    cc += GET(cc, 1);    cc += GET(cc, 1);
5748    }    }
5749    
5750  /* None of them matched. */  /* None of them matched. */
5751  if (common->quit != NULL)  if (common->quit != NULL)
5752      {
5753      jump = JUMP(SLJIT_JUMP);
5754    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5755      SLJIT_ASSERT(framesize != no_stack);
5756      if (framesize < 0)
5757        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5758      else
5759        {
5760        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5761        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5762        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5763        }
5764      JUMPHERE(jump);
5765      }
5766    
5767    if (needs_control_head)
5768      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5769    
5770  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5771    {    {
# Line 5338  if (opcode == OP_ASSERT || opcode == OP_ Line 5777  if (opcode == OP_ASSERT || opcode == OP_
5777      {      {
5778      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5779      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5780          {
5781          if (extrasize == 2)
5782            free_stack(common, 1);
5783        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5784          }
5785      else      else
5786        free_stack(common, 1);        free_stack(common, extrasize);
5787      }      }
5788    else    else
5789      {      {
5790      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5791      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5792      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5793        {        {
5794        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5795        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5796        }        }
5797      else      else
5798        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5799      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);
5800      }      }
5801    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5364  if (opcode == OP_ASSERT || opcode == OP_ Line 5807  if (opcode == OP_ASSERT || opcode == OP_
5807    if (framesize < 0)    if (framesize < 0)
5808      {      {
5809      /* 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. */
5810      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));
5811      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5812      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5813          {
5814        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));
5815          if (extrasize == 2)
5816            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5817          }
5818      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5819        {        {
5820        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 5380  if (opcode == OP_ASSERT || opcode == OP_ Line 5827  if (opcode == OP_ASSERT || opcode == OP_
5827        {        {
5828        /* 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. */
5829        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));
5830        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));
5831        }        }
5832      else      else
5833        {        {
5834        /* 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. */
5835        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));
5836        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5837        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5838            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5839            if (bra == OP_BRAMINZERO)
5840              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5841            }
5842          else
5843            {
5844            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5845            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5846            }
5847        }        }
5848      }      }
5849    
5850    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5851      {      {
5852      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5853      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5854      }      }
5855    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5856      {      {
# Line 5416  else Line 5872  else
5872      {      {
5873      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5874      if (bra != OP_BRA)      if (bra != OP_BRA)
5875          {
5876          if (extrasize == 2)
5877            free_stack(common, 1);
5878        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5879          }
5880      else      else
5881        free_stack(common, 1);        free_stack(common, extrasize);
5882      }      }
5883    else    else
5884      {      {
5885      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5886      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5887      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5888      if (bra != OP_BRA)      if (bra != OP_BRA)
5889        {        {
5890        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5891        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5892        }        }
5893      else      else
5894        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5895      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);
5896      }      }
5897    
# Line 5451  else Line 5911  else
5911      }      }
5912    }    }
5913    
5914    common->local_exit = save_local_exit;
5915    common->then_trap = save_then_trap;
5916  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5917  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5918  common->quit = save_quit;  common->quit = save_quit;
# Line 5568  if (i < name_count) Line 6030  if (i < name_count)
6030  return condition;  return condition;
6031  }  }
6032    
6033    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)
6034    {
6035    DEFINE_COMPILER;
6036    int stacksize;
6037    
6038    if (framesize < 0)
6039      {
6040      if (framesize == no_frame)
6041        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6042      else
6043        {
6044        stacksize = needs_control_head ? 1 : 0;
6045        if (ket != OP_KET || has_alternatives)
6046          stacksize++;
6047        free_stack(common, stacksize);
6048        }
6049    
6050      if (needs_control_head)
6051        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
6052    
6053      /* TMP2 which is set here used by OP_KETRMAX below. */
6054      if (ket == OP_KETRMAX)
6055        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
6056      else if (ket == OP_KETRMIN)
6057        {
6058        /* Move the STR_PTR to the private_data_ptr. */
6059        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
6060        }
6061      }
6062    else
6063      {
6064      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
6065      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
6066      if (needs_control_head)
6067        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
6068    
6069      if (ket == OP_KETRMAX)
6070        {
6071        /* TMP2 which is set here used by OP_KETRMAX below. */
6072        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6073        }
6074      }
6075    if (needs_control_head)
6076      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6077    }
6078    
6079    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6080    {
6081    DEFINE_COMPILER;
6082    
6083    if (common->capture_last_ptr != 0)
6084      {
6085      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6086      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6087      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6088      stacksize++;
6089      }
6090    if (common->optimized_cbracket[offset >> 1] == 0)
6091      {
6092      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6093      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6094      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6095      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6096      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6097      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6098      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6099      stacksize += 2;
6100      }
6101    return stacksize;
6102    }
6103    
6104  /*  /*
6105    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6106    
# Line 5636  pcre_uchar bra = OP_BRA; Line 6169  pcre_uchar bra = OP_BRA;
6169  pcre_uchar ket;  pcre_uchar ket;
6170  assert_backtrack *assert;  assert_backtrack *assert;
6171  BOOL has_alternatives;  BOOL has_alternatives;
6172    BOOL needs_control_head = FALSE;
6173  struct sljit_jump *jump;  struct sljit_jump *jump;
6174  struct sljit_jump *skip;  struct sljit_jump *skip;
6175  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 5711  else if (opcode == OP_ONCE || opcode == Line 6245  else if (opcode == OP_ONCE || opcode ==
6245    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6246    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6247    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6248      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);
6249    }    }
6250    
6251  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6252  stacksize = 0;  stacksize = 0;
6253  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6254    stacksize++;    stacksize++;
6255  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6256    stacksize++;    stacksize++;
# Line 5725  if (stacksize > 0) Line 6259  if (stacksize > 0)
6259    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6260    
6261  stacksize = 0;  stacksize = 0;
6262  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6263    {    {
6264    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6265    stacksize++;    stacksize++;
# Line 5788  if (ket == OP_KETRMAX) Line 6322  if (ket == OP_KETRMAX)
6322  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6323  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6324    {    {
6325      stacksize = 0;
6326      if (needs_control_head)
6327        {
6328        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6329        stacksize++;
6330        }
6331    
6332    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6333      {      {
6334      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6335      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6336        {        {
6337        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6338        allocate_stack(common, 2);        if (!needs_control_head)
6339        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));  
6340        }        }
6341      else if (ket == OP_KETRMAX || has_alternatives)      else
6342        {        {
6343        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6344        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6345        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6346            stacksize++;
6347        }        }
6348      else  
6349        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6350          allocate_stack(common, stacksize);
6351    
6352        stacksize = 0;
6353        if (needs_control_head)
6354          {
6355          stacksize++;
6356          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6357          }
6358    
6359        if (ket == OP_KETRMIN)
6360          {
6361          if (needs_control_head)
6362            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6363          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6364          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6365            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));
6366          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6367          }
6368        else if (ket == OP_KETRMAX || has_alternatives)
6369          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6370      }      }
6371    else    else
6372      {      {
6373      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6374          stacksize++;
6375    
6376        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6377        allocate_stack(common, stacksize);
6378    
6379        if (needs_control_head)
6380          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6381    
6382        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6383        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6384    
6385        stacksize = needs_control_head ? 1 : 0;
6386        if (ket != OP_KET || has_alternatives)
6387        {        {
6388        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);  
6389        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);
6390        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6391        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6392        }        }
6393      else      else
6394        {        {
       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));  
6395        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);
6396        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);  
6397        }        }
6398        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6399      }      }
6400    }    }
6401  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 5964  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6531  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6531    return NULL;    return NULL;
6532    
6533  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6534    {    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));  
       }  
     }  
   }  
6535    
6536  stacksize = 0;  stacksize = 0;
6537  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6016  if (ket != OP_KET || bra != OP_BRA) Line 6560  if (ket != OP_KET || bra != OP_BRA)
6560    }    }
6561    
6562  if (offset != 0)  if (offset != 0)
6563    {    stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
   if (common->capture_last_ptr != 0)  
     {  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);  
     stacksize++;  
     }  
   if (common->optimized_cbracket[offset >> 1] == 0)  
     {  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     stacksize += 2;  
     }  
   }  
6564    
6565  if (has_alternatives)  if (has_alternatives)
6566    {    {
# Line 6106  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6631  if ((ket != OP_KET && bra != OP_BRAMINZE
6631  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6632    cc += GET(cc, 1);    cc += GET(cc, 1);
6633  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6634    
6635    /* Temporarily encoding the needs_control_head in framesize. */
6636    if (opcode == OP_ONCE)
6637      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6638  return cc;  return cc;
6639  }  }
6640    
# Line 6116  backtrack_common *backtrack; Line 6645  backtrack_common *backtrack;
6645  pcre_uchar opcode;  pcre_uchar opcode;
6646  int private_data_ptr;  int private_data_ptr;
6647  int cbraprivptr = 0;  int cbraprivptr = 0;
6648    BOOL needs_control_head;
6649  int framesize;  int framesize;
6650  int stacksize;  int stacksize;
6651  int offset = 0;  int offset = 0;
6652  BOOL zero = FALSE;  BOOL zero = FALSE;
6653  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6654  int stack;  int stack; /* Also contains the offset of control head. */
6655  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6656  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6657    
# Line 6159  switch(opcode) Line 6689  switch(opcode)
6689    break;    break;
6690    }    }
6691    
6692  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6693  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6694  if (framesize < 0)  if (framesize < 0)
6695    {    {
6696    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    if (offset != 0)
6697        {
6698        stacksize = 2;
6699        if (common->capture_last_ptr != 0)
6700          stacksize++;
6701        }
6702      else
6703        stacksize = 1;
6704    
6705      if (needs_control_head)
6706        stacksize++;
6707    if (!zero)    if (!zero)
6708      stacksize++;      stacksize++;
6709    
6710    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6711    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6712    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    if (framesize == no_frame)
6713        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6714    
6715    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    stack = 0;
6716      if (offset != 0)
6717      {      {
6718        stack = 2;
6719      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6720      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));
6721      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6722        if (common->capture_last_ptr != 0)
6723          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6724      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6725        if (needs_control_head)
6726          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6727        if (common->capture_last_ptr != 0)
6728          {
6729          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6730          stack = 3;
6731          }
6732      }      }
6733    else    else
6734        {
6735        if (needs_control_head)
6736          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6737      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6738        stack = 1;
6739        }
6740    
6741      if (needs_control_head)
6742        stack++;
6743    if (!zero)    if (!zero)
6744      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);
6745      if (needs_control_head)
6746        {
6747        stack--;
6748        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6749        }
6750    }    }
6751  else  else
6752    {    {
6753    stacksize = framesize + 1;    stacksize = framesize + 1;
6754    if (!zero)    if (!zero)
6755      stacksize++;      stacksize++;
6756    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6757        stacksize++;
6758      if (offset == 0)
6759      stacksize++;      stacksize++;
6760    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
   allocate_stack(common, stacksize);  
6761    
6762      allocate_stack(common, stacksize);
6763    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);
6764    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6765    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);
6766      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6767    
6768    stack = 0;    stack = 0;
6769    if (!zero)    if (!zero)
6770      {      {
6771      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6772        stack = 1;
6773        }
6774      if (needs_control_head)
6775        {
6776        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6777      stack++;      stack++;
6778      }      }
6779    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6780      {      {
6781      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6782      stack++;      stack++;
6783      }      }
6784    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6785    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6786      stack -= 1 + (offset == 0);
6787    }    }
6788    
6789  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)  if (offset != 0)
6790    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6791    
6792  loop = LABEL();  loop = LABEL();
# Line 6227  while (*cc != OP_KETRPOS) Line 6802  while (*cc != OP_KETRPOS)
6802    
6803    if (framesize < 0)    if (framesize < 0)
6804      {      {
6805      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      if (framesize == no_frame)
6806          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6807    
6808      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6809        {        {
6810        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6811        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);
6812        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6813          if (common->capture_last_ptr != 0)
6814            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6815        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6816        }        }
6817      else      else
# Line 6251  while (*cc != OP_KETRPOS) Line 6829  while (*cc != OP_KETRPOS)
6829      }      }
6830    else    else
6831      {      {
6832      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6833        {        {
6834        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6835        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6836        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);
6837        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6838          if (common->capture_last_ptr != 0)
6839            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6840        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6841        }        }
6842      else      else
# Line 6279  while (*cc != OP_KETRPOS) Line 6859  while (*cc != OP_KETRPOS)
6859          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6860        }        }
6861      }      }
6862    
6863      if (needs_control_head)
6864        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6865    
6866    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6867    flush_stubs(common);    flush_stubs(common);
6868    
# Line 6289  while (*cc != OP_KETRPOS) Line 6873  while (*cc != OP_KETRPOS)
6873    
6874    if (framesize < 0)    if (framesize < 0)
6875      {      {
6876      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6877        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6878      else      else
6879        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6880      }      }
6881    else    else
6882      {      {
6883      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6884        {        {
6885        /* Last alternative. */        /* Last alternative. */
6886        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
# Line 6315  while (*cc != OP_KETRPOS) Line 6899  while (*cc != OP_KETRPOS)
6899    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6900    }    }
6901    
6902    /* We don't have to restore the control head in case of a failed match. */
6903    
6904  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6905  if (!zero)  if (!zero)
6906    {    {
# Line 6443  PUSH_BACKTRACK(sizeof(iterator_backtrack Line 7029  PUSH_BACKTRACK(sizeof(iterator_backtrack
7029    
7030  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
7031    
7032  switch (type)  switch(type)
7033    {    {
7034    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
7035    case OP_DIGIT:    case OP_DIGIT:
# Line 6703  if (!optimized_cbracket) Line 7289  if (!optimized_cbracket)
7289  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7290  }  }
7291    
7292    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7293    {
7294    DEFINE_COMPILER;
7295    backtrack_common *backtrack;
7296    pcre_uchar opcode = *cc;
7297    pcre_uchar *ccend = cc + 1;
7298    
7299    SLJIT_ASSERT(common->control_head_ptr != 0 || *cc == OP_COMMIT);
7300    
7301    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7302      ccend += 2 + cc[1];
7303    
7304    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7305    
7306    if (opcode == OP_SKIP || opcode == OP_SKIP_ARG)
7307      {
7308      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7309      allocate_stack(common, 3);
7310      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7311      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg);
7312      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), (opcode == OP_SKIP) ? STR_PTR : SLJIT_IMM, (opcode == OP_SKIP) ? 0 : (sljit_sw)(cc + 2));
7313      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7314      return ccend;
7315      }
7316    
7317    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7318      {
7319      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7320      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7321      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7322      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7323      }
7324    
7325    if (common->control_head_ptr != 0 && ((opcode != OP_THEN && opcode != OP_THEN_ARG) || common->then_trap == NULL))
7326      {
7327      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7328      allocate_stack(common, 2);
7329      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7330      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);
7331      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7332      }
7333    
7334    return ccend;
7335    }
7336    
7337    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7338    
7339    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7340    {
7341    DEFINE_COMPILER;
7342    backtrack_common *backtrack;
7343    BOOL needs_control_head;
7344    int size;
7345    
7346    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7347    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7348    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7349    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7350    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7351    
7352    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7353    size = 3 + (size < 0 ? 0 : size);
7354    
7355    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7356    allocate_stack(common, size);
7357    if (size > 3)
7358      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7359    else
7360      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7361    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7362    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7363    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7364    
7365    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7366    if (size >= 0)
7367      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7368    }
7369    
7370  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)
7371  {  {
7372  DEFINE_COMPILER;  DEFINE_COMPILER;
7373  backtrack_common *backtrack;  backtrack_common *backtrack;
7374    BOOL has_then_trap = FALSE;
7375    then_trap_backtrack *save_then_trap = NULL;
7376    
7377    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7378    
7379    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7380      {
7381      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7382      has_then_trap = TRUE;
7383      save_then_trap = common->then_trap;
7384      /* Tail item on backtrack. */
7385      compile_then_trap_matchingpath(common, cc, ccend, parent);
7386      }
7387    
7388  while (cc < ccend)  while (cc < ccend)
7389    {    {
# Line 6923  while (cc < ccend) Line 7600  while (cc < ccend)
7600      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7601      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7602      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);
7603      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7604      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7605      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);
7606      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7607      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);
7608      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);
7609        if (common->has_skip_arg)
7610          {
7611          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7612          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7613          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7614          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7615          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7616          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7617          }
7618      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7619      break;      break;
7620    
7621        case OP_PRUNE:
7622        case OP_PRUNE_ARG:
7623        case OP_SKIP:
7624        case OP_SKIP_ARG:
7625        case OP_THEN:
7626        case OP_THEN_ARG:
7627      case OP_COMMIT:      case OP_COMMIT:
7628      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7629      break;      break;
7630    
7631      case OP_FAIL:      case OP_FAIL:
# Line 6958  while (cc < ccend) Line 7649  while (cc < ccend)
7649    if (cc == NULL)    if (cc == NULL)
7650      return;      return;
7651    }    }
7652    
7653    if (has_then_trap)
7654      {
7655      /* Head item on backtrack. */
7656      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7657      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7658      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7659      common->then_trap = save_then_trap;
7660      }
7661  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7662  }  }
7663    
# Line 7119  switch(opcode) Line 7819  switch(opcode)
7819    }    }
7820  }  }
7821    
7822  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)
7823  {  {
7824  DEFINE_COMPILER;  DEFINE_COMPILER;
7825  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7141  set_jumps(current->topbacktracks, LABEL( Line 7841  set_jumps(current->topbacktracks, LABEL(
7841  free_stack(common, 2);  free_stack(common, 2);
7842  }  }
7843    
7844  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)
7845  {  {
7846  DEFINE_COMPILER;  DEFINE_COMPILER;
7847    
7848    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7849      compile_backtrackingpath(common, current->top);
7850  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
7851    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7852      return;
7853    
7854  if (common->has_set_som && common->mark_ptr != 0)  if (common->has_set_som && common->mark_ptr != 0)
7855    {    {
# Line 7247  pcre_uchar bra = OP_BRA; Line 7951  pcre_uchar bra = OP_BRA;
7951  pcre_uchar ket;  pcre_uchar ket;
7952  assert_backtrack *assert;  assert_backtrack *assert;
7953  BOOL has_alternatives;  BOOL has_alternatives;
7954    BOOL needs_control_head = FALSE;
7955  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7956  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7957  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7272  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7977  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7977  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7978    opcode = OP_ONCE;    opcode = OP_ONCE;
7979    
7980    /* Decoding the needs_control_head in framesize. */
7981    if (opcode == OP_ONCE)
7982      {
7983      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7984      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7985      }
7986    
7987  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7988    {    {
7989    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7315  if (offset != 0) Line 8027  if (offset != 0)
8027    {    {
8028    if (common->capture_last_ptr != 0)    if (common->capture_last_ptr != 0)
8029      {      {
8030        SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
8031      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8032      free_stack(common, 1);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8033      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
8034        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
8035        free_stack(common, 3);
8036        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
8037        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
8038      }      }
8039    if (common->optimized_cbracket[offset >> 1] == 0)    else if (common->optimized_cbracket[offset >> 1] == 0)
8040      {      {
8041      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8042      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
# Line 7424  if (has_alternatives) Line 8141  if (has_alternatives)
8141      current->top = NULL;      current->top = NULL;
8142      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8143      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8144        /* Conditional blocks always have an additional alternative, even if it is empty. */
8145      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8146        {        {
8147        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8148        cc += GET(cc, 1);        cc += GET(cc, 1);
8149        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8150          {          {
8151          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8152            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8153              if (private_data_ptr != 0)
8154                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8155              else
8156                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8157              }
8158          else          else
8159            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));
8160          }          }
8161        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8162        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7443  if (has_alternatives) Line 8166  if (has_alternatives)
8166      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8167      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8168      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8169        {        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));  
           }  
         }  
       }  
8170    
8171      stacksize = 0;      stacksize = 0;
8172      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7480  if (has_alternatives) Line 8181  if (has_alternatives)
8181      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8182        stacksize++;        stacksize++;
8183    
8184      if (stacksize > 0) {      if (stacksize > 0)
8185          {
8186        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8187          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
8188        else        else
# Line 7489  if (has_alternatives) Line 8191  if (has_alternatives)
8191          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
8192          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));
8193          }          }
8194      }        }
8195    
8196      stacksize = 0;      stacksize = 0;
8197      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7502  if (has_alternatives) Line 8204  if (has_alternatives)
8204        }        }
8205    
8206      if (offset != 0)      if (offset != 0)
8207        {        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;  
         }  
       }  
8208    
8209      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8210        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 7555  if (has_alternatives) Line 8238  if (has_alternatives)
8238      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8239      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8240      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)
   
8241        {        {
8242        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);
8243        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7595  else if (opcode == OP_SBRA || opcode == Line 8277  else if (opcode == OP_SBRA || opcode ==
8277  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8278    {    {
8279    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8280      stacksize = needs_control_head ? 1 : 0;
8281    
8282    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8283      {      {
8284      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8285      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);  
8286      }      }
8287    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8288      {      {
8289      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8290      free_stack(common, 1);      stacksize++;
8291      }      }
8292      free_stack(common, stacksize);
8293    
8294    JUMPHERE(once);    JUMPHERE(once);
8295    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7657  else if (bra == OP_BRAZERO) Line 8341  else if (bra == OP_BRAZERO)
8341    }    }
8342  }  }
8343    
8344  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)
8345  {  {
8346  DEFINE_COMPILER;  DEFINE_COMPILER;
8347  int offset;  int offset;
# Line 7671  if (CURRENT_AS(bracketpos_backtrack)->fr Line 8355  if (CURRENT_AS(bracketpos_backtrack)->fr
8355      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8356      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8357      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
8358        if (common->capture_last_ptr != 0)
8359          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
8360      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
8361        if (common->capture_last_ptr != 0)
8362          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
8363      }      }
8364    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8365    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
# Line 7692  if (current->topbacktracks) Line 8380  if (current->topbacktracks)
8380  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));
8381  }  }
8382    
8383  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)
8384  {  {
8385  assert_backtrack backtrack;  assert_backtrack backtrack;
8386    
# Line 7716  else Line 8404  else
8404  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8405  }  }
8406    
8407    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8408    {
8409    DEFINE_COMPILER;
8410    pcre_uchar opcode = *current->cc;
8411    
8412    SLJIT_ASSERT(common->control_head_ptr != 0);
8413    
8414    if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8415      {
8416      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8417      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8418      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, common->then_trap->start);
8419      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_then_trap));
8420      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8421    
8422      OP1(SLJIT_MOV, TMP2, 0, TMP1, 0);
8423      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8424      if (common->quit_label == NULL)
8425        add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
8426      else
8427        CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->quit_label);
8428    
8429      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
8430      add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8431      return;
8432      }
8433    
8434    if (!common->local_exit)
8435      {
8436      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8437      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8438      sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8439      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8440    
8441      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8442      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8443    
8444      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8445      }
8446    
8447    /* Commit or in recurse or accept. */
8448    if (common->quit_label == NULL)
8449      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8450    else
8451      JUMPTO(SLJIT_JUMP, common->quit_label);
8452    }
8453    
8454    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8455    {
8456    DEFINE_COMPILER;
8457    struct sljit_jump *jump;
8458    int size;
8459    
8460    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8461      {
8462      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8463      return;
8464      }
8465    
8466    size = CURRENT_AS(then_trap_backtrack)->framesize;
8467    size = 3 + (size < 0 ? 0 : size);
8468    
8469    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8470    free_stack(common, size);
8471    jump = JUMP(SLJIT_JUMP);
8472    
8473    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8474    /* STACK_TOP is set by THEN. */
8475    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8476      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8477    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8478    free_stack(common, 3);
8479    
8480    JUMPHERE(jump);
8481    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8482    }
8483    
8484  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8485  {  {
8486  DEFINE_COMPILER;  DEFINE_COMPILER;
8487    then_trap_backtrack *save_then_trap = common->then_trap;
8488    
8489  while (current)  while (current)
8490    {    {
# Line 7852  while (current) Line 8618  while (current)
8618      break;      break;
8619    
8620      case OP_MARK:      case OP_MARK:
8621      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));
8622      free_stack(common, 1);      if (common->has_skip_arg)
8623          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8624        free_stack(common, common->has_skip_arg ? 5 : 1);
8625      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);
8626        if (common->has_skip_arg)
8627          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8628        break;
8629    
8630        case OP_THEN:
8631        case OP_THEN_ARG:
8632        case OP_PRUNE:
8633        case OP_PRUNE_ARG:
8634        case OP_SKIP:
8635        compile_control_verb_backtrackingpath(common, current);
8636        break;
8637    
8638        case OP_SKIP_ARG:
8639        if (!common->local_exit)
8640          {
8641          SLJIT_ASSERT(common->control_head_ptr != 0);
8642          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8643          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8644          sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8645          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8646    
8647          OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8648          add_jump(compiler, &common->reset_match, CMP(SLJIT_C_LESS, STR_PTR, 0, SLJIT_IMM, -2));
8649    
8650          /* May not find suitable mark. */
8651          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8652          if (common->quit_label == NULL)
8653            add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8654          else
8655            CMPTO(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1, common->quit_label);
8656    
8657          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8658          free_stack(common, 3);
8659          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8660          }
8661        else
8662          {
8663          /* In recurse or accept. */
8664          if (common->quit_label == NULL)
8665            add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8666          else
8667            JUMPTO(SLJIT_JUMP, common->quit_label);
8668          }
8669      break;      break;
8670    
8671      case OP_COMMIT:      case OP_COMMIT:
8672      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8673          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8674      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8675        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8676      else      else
# Line 7872  while (current) Line 8684  while (current)
8684      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8685      break;      break;
8686    
8687        case OP_THEN_TRAP:
8688        /* A virtual opcode for then traps. */
8689        compile_then_trap_backtrackingpath(common, current);
8690        break;
8691    
8692      default:      default:
8693      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8694      break;      break;
8695      }      }
8696    current = current->prev;    current = current->prev;
8697    }    }
8698    common->then_trap = save_then_trap;
8699  }  }
8700    
8701  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 7886  DEFINE_COMPILER; Line 8704  DEFINE_COMPILER;
8704  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8705  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);
8706  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8707  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8708  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8709    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8710  int alternativesize;  int alternativesize;
8711  BOOL needsframe;  BOOL needs_frame;
8712  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quit_label = common->quit_label;  
 jump_list *save_quit = common->quit;  
8713  struct sljit_jump *jump;  struct sljit_jump *jump;
8714    
8715    /* Recurse captures then. */
8716    common->then_trap = NULL;
8717    
8718  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);
8719  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8720  if (!needsframe)  if (!needs_frame)
8721    framesize = 0;    framesize = 0;
8722  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8723    
# Line 7908  set_jumps(common->currententry->calls, c Line 8728  set_jumps(common->currententry->calls, c
8728  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8729  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8730  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);
8731  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);
8732    if (needs_control_head)
8733      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8734  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);
8735  if (needsframe)  if (needs_frame)
8736    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8737    
8738  if (alternativesize > 0)  if (alternativesize > 0)
8739    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 7933  while (1) Line 8755  while (1)
8755    
8756    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8757    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;  
8758      return;      return;
     }  
8759    
8760    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8761    
8762    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8763    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;  
8764      return;      return;
     }  
8765    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8766    
8767    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 7956  while (1) Line 8770  while (1)
8770    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8771    cc += GET(cc, 1);    cc += GET(cc, 1);
8772    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8773    
8774    /* None of them matched. */
8775  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8776  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8777    
8778    if (common->quit != NULL)
8779      {
8780      set_jumps(common->quit, LABEL());
8781      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8782      if (needs_frame)
8783        {
8784        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8785        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8786        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8787        }
8788      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8789      common->quit = NULL;
8790      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8791      }
8792    
8793  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8794  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);
8795  if (needsframe)  if (needs_frame)
8796    {    {
8797    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));
8798    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7974  if (needsframe) Line 8801  if (needsframe)
8801  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8802    
8803  JUMPHERE(jump);  JUMPHERE(jump);
8804  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8805      set_jumps(common->quit, LABEL());
8806    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8807  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8808  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8809  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8810  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));
8811      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8812      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8813      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8814      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8815      }
8816    else
8817      {
8818      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8819      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8820      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8821      }
8822  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;  
8823  }  }
8824    
8825  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 8002  pcre_uchar *ccend; Line 8839  pcre_uchar *ccend;
8839  executable_functions *functions;  executable_functions *functions;
8840  void *executable_func;  void *executable_func;
8841  sljit_uw executable_size;  sljit_uw executable_size;
8842  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8843  struct sljit_label *empty_match_found;  struct sljit_label *continue_match_label;
8844  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_found_label;
8845    struct sljit_label *empty_match_backtrack_label;
8846    struct sljit_label *reset_match_label;
8847  struct sljit_jump *jump;  struct sljit_jump *jump;
8848  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
8849  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8850  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8851    struct sljit_label *quit_label;
8852    
8853  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8854  study = extra->study_data;  study = extra->study_data;
# Line 8077  common->ovector_start = CALL_LIMIT + siz Line 8917  common->ovector_start = CALL_LIMIT + siz
8917  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8918  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8919    return;    return;
8920    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
8921    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8922    #else
8923  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
8924    #endif
8925    
8926  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
8927    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
8928    common->capture_last_ptr = common->ovector_start;
8929    common->ovector_start += sizeof(sljit_sw);
8930    #endif
8931  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
8932  if (private_data_size < 0)  if (private_data_size < 0)
8933    {    {
# Line 8100  if (mode != JIT_COMPILE) Line 8948  if (mode != JIT_COMPILE)
8948    if (mode == JIT_PARTIAL_SOFT_COMPILE)    if (mode == JIT_PARTIAL_SOFT_COMPILE)
8949      {      {
8950      common->hit_start = common->ovector_start;      common->hit_start = common->ovector_start;
8951      common->ovector_start += sizeof(sljit_sw);      common->ovector_start += 2 * sizeof(sljit_sw);
8952        }
8953      else
8954        {
8955        SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
8956        common->needs_start_ptr = TRUE;
8957      }      }
8958    }    }
8959  if ((re->options & PCRE_FIRSTLINE) != 0)  if ((re->options & PCRE_FIRSTLINE) != 0)
# Line 8108  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8961  if ((re->options & PCRE_FIRSTLINE) != 0)
8961    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
8962    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8963    }    }
8964    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
8965    common->control_head_ptr = 1;
8966    #endif
8967    if (common->control_head_ptr != 0)
8968      {
8969      common->control_head_ptr = common->ovector_start;
8970      common->ovector_start += sizeof(sljit_sw);
8971      }
8972    if (common->needs_start_ptr && common->has_set_som)
8973      {
8974      /* Saving the real start pointer is necessary. */
8975      common->start_ptr = common->ovector_start;
8976      common->ovector_start += sizeof(sljit_sw);
8977      }
8978    else
8979      common->needs_start_ptr = FALSE;
8980    
8981  /* Aligning ovector to even number of sljit words. */  /* Aligning ovector to even number of sljit words. */
8982  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8983    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8984    
8985    if (common->start_ptr == 0)
8986      common->start_ptr = OVECTOR(0);
8987    
8988  /* Capturing brackets cannot be optimized if callouts are allowed. */  /* Capturing brackets cannot be optimized if callouts are allowed. */
8989  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8990    memset(common->optimized_cbracket, 0, re->top_bracket + 1);    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8991    
8992  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8993  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);
8994  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);  private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
8995  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
8996    {    {
8997    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8998    return;    return;
8999    }    }
9000    
9001  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
9002  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
9003    {    {
# Line 8132  if (!common->private_data_ptrs) Line 9005  if (!common->private_data_ptrs)
9005    return;    return;
9006    }    }
9007  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
9008  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);
9009    
9010    if (common->has_then)
9011      {
9012      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
9013      if (!common->then_offsets)
9014        {
9015        SLJIT_FREE(common->optimized_cbracket);
9016        SLJIT_FREE(common->private_data_ptrs);
9017        return;
9018        }
9019      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
9020      set_then_offsets(common, rootbacktrack.cc, NULL);
9021      }
9022    
9023  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
9024  if (!compiler)  if (!compiler)
9025    {    {
9026    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9027    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9028      if (common->has_then)
9029        SLJIT_FREE(common->then_offsets);
9030    return;    return;
9031    }    }
9032  common->compiler = compiler;  common->compiler = compiler;
# Line 8162  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM Line 9050  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM
9050  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
9051    
9052  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9053    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
9054    if (common->mark_ptr != 0)
9055      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
9056    if (common->control_head_ptr != 0)
9057      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
9058    
9059  /* Main part of the matching */  /* Main part of the matching */
9060  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9061    {    {
9062    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);
9063      continue_match_label = LABEL();
9064    /* Forward search if possible. */    /* Forward search if possible. */
9065    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
9066      {      {
# Line 8181  if ((re->options & PCRE_ANCHORED) == 0) Line 9074  if ((re->options & PCRE_ANCHORED) == 0)
9074        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);
9075      }      }
9076    }    }
9077    else
9078      continue_match_label = LABEL();
9079    
9080  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)
9081    {    {
9082    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 8194  if (common->req_char_ptr != 0) Line 9090  if (common->req_char_ptr != 0)
9090  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);
9091  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
9092  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
 if (common->mark_ptr != 0)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);  
9093  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
9094    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);
9095    
9096    if (common->needs_start_ptr)
9097      {
9098      SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
9099      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
9100      }
9101    else
9102      SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
9103    
9104  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
9105  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9106    {    {
9107    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
9108    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);
9109      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
9110    JUMPHERE(jump);    JUMPHERE(jump);
9111    }    }
9112  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
# Line 8214  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9118  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9118    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9119    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9120    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9121      if (common->has_then)
9122        SLJIT_FREE(common->then_offsets);
9123    return;    return;
9124    }    }
9125    
9126  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));
9127  empty_match_found = LABEL();  empty_match_found_label = LABEL();
9128    
9129  common->accept_label = LABEL();  common->accept_label = LABEL();
9130  if (common->accept != NULL)  if (common->accept != NULL)
# Line 8232  if (common->quit != NULL) Line 9138  if (common->quit != NULL)
9138  if (common->forced_quit != NULL)  if (common->forced_quit != NULL)
9139    set_jumps(common->forced_quit, common->forced_quit_label);    set_jumps(common->forced_quit, common->forced_quit_label);
9140  if (minlength_check_failed != NULL)  if (minlength_check_failed != NULL)
9141    sljit_set_label(minlength_check_failed, common->forced_quit_label);    SET_LABEL(minlength_check_failed, common->forced_quit_label);
9142  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
9143    
9144  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
# Line 8242  if (mode != JIT_COMPILE) Line 9148  if (mode != JIT_COMPILE)
9148    return_with_partial_match(common, common->quit_label);    return_with_partial_match(common, common->quit_label);
9149    }    }
9150    
9151  empty_match_backtrack = LABEL();  empty_match_backtrack_label = LABEL();
9152  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
9153  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9154    {    {
9155    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9156    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9157    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9158      if (common->has_then)
9159        SLJIT_FREE(common->then_offsets);
9160    return;    return;
9161    }    }
9162    
9163  SLJIT_ASSERT(rootbacktrack.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
9164    reset_match_label = LABEL();
9165    
9166  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9167    {    {
9168    /* Update hit_start only in the first time. */    /* Update hit_start only in the first time. */
9169    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
9170    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
9171    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
9172    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
# Line 8265  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 9174  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9174    }    }
9175    
9176  /* Check we have remaining characters. */  /* Check we have remaining characters. */
9177  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
9178      {
9179      SLJIT_ASSERT(common->first_line_end != 0);
9180      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
9181      }
9182    
9183    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
9184    
9185  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9186    {    {
9187    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
9188      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);  
     }  
9189    else    else
9190      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
     SLJIT_ASSERT(common->first_line_end != 0);  
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);  
       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);  
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);  
       JUMPTO(SLJIT_C_ZERO, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);  
     }  
9191    }    }
9192    
9193  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8301  if (reqbyte_notfound != NULL) Line 9195  if (reqbyte_notfound != NULL)
9195    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
9196    
9197  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9198    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
9199    
9200  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
9201  JUMPTO(SLJIT_JUMP, common->quit_label);  JUMPTO(SLJIT_JUMP, common->quit_label);
# Line 8311  flush_stubs(common); Line 9205  flush_stubs(common);
9205  JUMPHERE(empty_match);  JUMPHERE(empty_match);
9206  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9207  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty));
9208  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
9209  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, notempty_atstart));
9210  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
9211  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
9212  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
9213  JUMPTO(SLJIT_JUMP, empty_match_backtrack);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9214    
9215  common->currententry = common->entries;  common->currententry = common->entries;
9216    common->local_exit = TRUE;
9217    quit_label = common->quit_label;
9218  while (common->currententry != NULL)  while (common->currententry != NULL)
9219    {    {
9220    /* Might add new entries. */    /* Might add new entries. */
# Line 8328  while (common->currententry != NULL) Line 9224  while (common->currententry != NULL)
9224      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9225      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9226      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9227        if (common->has_then)
9228          SLJIT_FREE(common->then_offsets);
9229      return;      return;
9230      }      }
9231    flush_stubs(common);    flush_stubs(common);
9232    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
9233    }    }
9234    common->local_exit = FALSE;
9235    common->quit_label = quit_label;
9236    
9237  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
9238  /* This is a (really) rare case. */  /* This is a (really) rare case. */
# Line 8400  if (common->caselesscmp != NULL) Line 9300  if (common->caselesscmp != NULL)
9300    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
9301    do_caselesscmp(common);    do_caselesscmp(common);
9302    }    }
9303    if (common->reset_match != NULL)
9304      {
9305      set_jumps(common->reset_match, LABEL());
9306      do_reset_match(common, (re->top_bracket + 1) * 2);
9307      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
9308      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
9309      JUMPTO(SLJIT_JUMP, reset_match_label);
9310      }
9311  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9312  #ifndef COMPILE_PCRE32  #ifndef COMPILE_PCRE32
9313  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
# Line 8426  if (common->getucd != NULL) Line 9334  if (common->getucd != NULL)
9334    
9335  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9336  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9337    if (common->has_then)
9338      SLJIT_FREE(common->then_offsets);
9339    
9340  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9341  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9342  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8517  arguments.notempty = (options & PCRE_NOT Line 9428  arguments.notempty = (options & PCRE_NOT
9428  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
9429  arguments.offsets = offsets;  arguments.offsets = offsets;
9430  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
9431    arguments.real_offset_count = offset_count;
9432    
9433  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
9434  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
# Line 8607  arguments.notempty = (options & PCRE_NOT Line 9519  arguments.notempty = (options & PCRE_NOT
9519  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
9520  arguments.offsets = offsets;  arguments.offsets = offsets;
9521  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
9522    arguments.real_offset_count = offset_count;
9523    
9524  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
9525  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as

Legend:
Removed from v.1245  
changed lines
  Added in v.1282

  ViewVC Help
Powered by ViewVC 1.1.5