/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

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

revision 1221 by ph10, Sun Nov 11 20:27:03 2012 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 157  typedef struct jit_arguments { Line 166  typedef struct jit_arguments {
166    int *offsets;    int *offsets;
167    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169      void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171    int offsetcount;    int real_offset_count;
172    int calllimit;    int offset_count;
173      int call_limit;
174    pcre_uint8 notbol;    pcre_uint8 notbol;
175    pcre_uint8 noteol;    pcre_uint8 noteol;
176    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 179  typedef struct 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 209  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 230  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 265  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;
338    /* Head of the last recursion. */    /* Head of the last recursion. */
339    int recursive_head;    int recursive_head_ptr;
340    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
341    int start_used_ptr;    int start_used_ptr;
342    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 298  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. */
351      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 321  typedef struct compiler_common { Line 383  typedef struct compiler_common {
383    
384    /* Labels and jump lists. */    /* Labels and jump lists. */
385    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
386    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
387    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
388      struct sljit_label *accept_label;
389    stub_list *stubs;    stub_list *stubs;
390    recurse_entry *entries;    recurse_entry *entries;
391    recurse_entry *currententry;    recurse_entry *currententry;
392    jump_list *partialmatch;    jump_list *partialmatch;
393    jump_list *quit;    jump_list *quit;
394      jump_list *forced_quit;
395    jump_list *accept;    jump_list *accept;
396    jump_list *calllimit;    jump_list *calllimit;
397    jump_list *stackalloc;    jump_list *stackalloc;
# Line 338  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 390  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 428  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 459  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 483  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 507  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 519  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 561  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;  
717    
718    case OP_CRRANGE:    case OP_ANYBYTE:
719    case OP_CRMINRANGE:  #ifdef SUPPORT_UTF
720    return cc + 1 + 2 * IMM2_SIZE;    if (common->utf) return NULL;
721    #endif
722    case OP_CLASS:    return cc + 1;
   case OP_NCLASS:  
   return cc + 1 + 32 / sizeof(pcre_uchar);  
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    
735    default:    default:
736      /* All opcodes are supported now! */
737      SLJIT_ASSERT_STOP();
738    return NULL;    return NULL;
739    }    }
740  }  }
# Line 812  while (cc < ccend) Line 866  while (cc < ccend)
866    
867      case OP_COND:      case OP_COND:
868      case OP_SCOND:      case OP_SCOND:
869      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
870      if (bracketlen == OP_CREF)         not intend to support this case. */
871        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
872        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);        return -1;
       common->optimized_cbracket[bracketlen] = 0;  
       }  
     else if (bracketlen == OP_NCREF)  
       {  
       bracketlen = GET2(cc, 1 + LINK_SIZE + 1);  
       name = (pcre_uchar *)common->name_table;  
       alternative = name;  
       for (i = 0; i < common->name_count; i++)  
         {  
         if (GET2(name, 0) == bracketlen) break;  
         name += common->name_entry_size;  
         }  
       SLJIT_ASSERT(i != common->name_count);  
   
       for (i = 0; i < common->name_count; i++)  
         {  
         if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)  
           common->optimized_cbracket[GET2(alternative, 0)] = 0;  
         alternative += common->name_entry_size;  
         }  
       }  
873    
874      if (*cc == OP_COND)      if (*cc == OP_COND)
875        {        {
# Line 850  while (cc < ccend) Line 883  while (cc < ccend)
883      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
884      break;      break;
885    
886        case OP_CREF:
887        i = GET2(cc, 1);
888        common->optimized_cbracket[i] = 0;
889        cc += 1 + IMM2_SIZE;
890        break;
891    
892        case OP_NCREF:
893        bracketlen = GET2(cc, 1);
894        name = (pcre_uchar *)common->name_table;
895        alternative = name;
896        for (i = 0; i < common->name_count; i++)
897          {
898          if (GET2(name, 0) == bracketlen) break;
899          name += common->name_entry_size;
900          }
901        SLJIT_ASSERT(i != common->name_count);
902    
903        for (i = 0; i < common->name_count; i++)
904          {
905          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
906            common->optimized_cbracket[GET2(alternative, 0)] = 0;
907          alternative += common->name_entry_size;
908          }
909        bracketlen = 0;
910        cc += 1 + IMM2_SIZE;
911        break;
912    
913      case OP_BRA:      case OP_BRA:
914      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
915      break;      break;
# Line 906  while (cc < ccend) Line 966  while (cc < ccend)
966    
967      case OP_RECURSE:      case OP_RECURSE:
968      /* Set its value only once. */      /* Set its value only once. */
969      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
970        {        {
971        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
972        common->ovector_start += sizeof(sljit_sw);        common->ovector_start += sizeof(sljit_sw);
973        }        }
974      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
975      break;      break;
976    
977        case OP_CALLOUT:
978        if (common->capture_last_ptr == 0)
979          {
980          common->capture_last_ptr = common->ovector_start;
981          common->ovector_start += sizeof(sljit_sw);
982          }
983        cc += 2 + 2 * LINK_SIZE;
984        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 923  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 1099  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 (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #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 (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 1130  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 1150  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 1157  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 1189  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 1200  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 1210  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 1227  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 1236  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 1249  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 1268  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 1387  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 1408  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 1424  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)
1659      {      {
1660      case start:      case start:
1661      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1662      count = 1;      count = 1;
1663      srcw[0] = common->recursive_head;      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 1657  while (status != end) Line 1891  while (status != end)
1891        }        }
1892      }      }
1893    }    }
1894    while (status != end);
1895    
1896  if (save)  if (save)
1897    {    {
# Line 1690  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 1708  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 1724  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 1748  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 1781  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 1795  static SLJIT_INLINE void reset_ovector(c Line 2056  static SLJIT_INLINE void reset_ovector(c
2056  DEFINE_COMPILER;  DEFINE_COMPILER;
2057  struct sljit_label *loop;  struct sljit_label *loop;
2058  int i;  int i;
2059    
2060  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2061    SLJIT_ASSERT(length > 1);
2062  /* TMP1 returns with begin - 1. */  /* 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));  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)  if (length < 8)
2065    {    {
2066    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2067      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2068    }    }
2069  else  else
2070    {    {
2071    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2072    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2073    loop = LABEL();    loop = LABEL();
2074    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2075    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
# Line 1814  else Line 2077  else
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    do
2163      {
2164      switch (current[-2])
2165        {
2166        case type_commit:
2167        /* Commit overwrites all. */
2168        return 0;
2169    
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)
2192  {  {
2193  DEFINE_COMPILER;  DEFINE_COMPILER;
2194  struct sljit_label *loop;  struct sljit_label *loop;
2195  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
2196    
2197  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2198  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
# Line 1827  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2201  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2201  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
2202  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2203    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
2204  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
2205  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2206    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
2207  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2208  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
2209  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
2210  /* Unlikely, but possible */  /* Unlikely, but possible */
2211  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
2212  loop = LABEL();  loop = LABEL();
2213  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
2214  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 1845  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ Line 2219  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ
2219  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
2220  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
2221  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2222  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2223    
2224  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2225  if (topbracket > 1)  if (topbracket > 1)
# Line 1867  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, offsetcount));  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 2055  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 2068  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 2115  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 2573  DEFINE_COMPILER; Line 2957  DEFINE_COMPILER;
2957  struct sljit_label *start;  struct sljit_label *start;
2958  struct sljit_jump *quit;  struct sljit_jump *quit;
2959  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
2960  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2961  int location = 0;  int location = 0;
2962  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2963  int must_stop;  int must_stop;
# Line 2696  if (firstline) Line 3080  if (firstline)
3080    {    {
3081    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3082    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3083    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3084    }    }
3085  else  else
3086    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3087    
3088  start = LABEL();  start = LABEL();
3089  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 2728  JUMPHERE(quit); Line 3112  JUMPHERE(quit);
3112  if (firstline)  if (firstline)
3113    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3114  else  else
3115    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3116  return TRUE;  return TRUE;
3117  }  }
3118    
# Line 2877  if (firstline) Line 3261  if (firstline)
3261    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3262  }  }
3263    
3264    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3265    
3266  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
3267  {  {
3268  DEFINE_COMPILER;  DEFINE_COMPILER;
3269  struct sljit_label *start;  struct sljit_label *start;
3270  struct sljit_jump *quit;  struct sljit_jump *quit;
3271  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3272    jump_list *matches = NULL;
3273    pcre_uint8 inverted_start_bits[32];
3274    int i;
3275  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3276  struct sljit_jump *jump;  struct sljit_jump *jump;
3277  #endif  #endif
3278    
3279    for (i = 0; i < 32; ++i)
3280      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3281    
3282  if (firstline)  if (firstline)
3283    {    {
3284    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 2901  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P Line 3293  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
3293  if (common->utf)  if (common->utf)
3294    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3295  #endif  #endif
3296    
3297    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3298      {
3299  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3300  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3301  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3302  JUMPHERE(jump);    JUMPHERE(jump);
3303  #endif  #endif
3304  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3305  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3306  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3307  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3308  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3309  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
3310      }
3311    
3312  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3313  if (common->utf)  if (common->utf)
# Line 2939  if (common->utf) Line 3335  if (common->utf)
3335  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE[8|16] */
3336  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3337  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3338  JUMPHERE(found);  if (found != NULL)
3339      JUMPHERE(found);
3340    if (matches != NULL)
3341      set_jumps(matches, LABEL());
3342  JUMPHERE(quit);  JUMPHERE(quit);
3343    
3344  if (firstline)  if (firstline)
# Line 3022  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 3030  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 3063  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 3120  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 3161  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 3481  sljit_emit_fast_return(compiler, RETURN_ Line 3866  sljit_emit_fast_return(compiler, RETURN_
3866    
3867  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3868    
3869  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3870  {  {
3871  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3872  pcre_uint32 c1, c2;  pcre_uint32 c1, c2;
# Line 3577  do Line 3962  do
3962  #endif  #endif
3963    
3964    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3965  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3966    
3967    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3968    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3594  do Line 3979  do
3979    
3980  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3981    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3982  #elif defined COMPILE_PCRE16  #else
3983    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
 #elif defined COMPILE_PCRE32  
   if (1 /* context->ucharptr >= 1 || context->length == 0 */)  
3984  #endif  #endif
3985      {      {
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3986      if (context->length >= 4)      if (context->length >= 4)
3987        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
 #if defined COMPILE_PCRE8  
3988      else if (context->length >= 2)      else if (context->length >= 2)
3989        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3990    #if defined COMPILE_PCRE8
3991      else if (context->length >= 1)      else if (context->length >= 1)
3992        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3993  #elif defined COMPILE_PCRE16  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif /* COMPILE_PCRE[8|16] */  
 #elif defined COMPILE_PCRE32  
     OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif /* COMPILE_PCRE[8|16|32] */  
3994      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3995    
3996      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3625  do Line 4001  do
4001        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
4002        break;        break;
4003    
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
4004        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
4005        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
4006          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 3640  do Line 4015  do
4015        break;        break;
4016  #endif  #endif
4017    
 #endif /* COMPILE_PCRE[8|16] */  
   
4018        default:        default:
4019        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
4020        break;        break;
# Line 3651  do Line 4024  do
4024    
4025  #else  #else
4026    
4027    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
4028    if (context->length > 0)    if (context->length >= 1)
4029      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
4030    
4031    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
# Line 3813  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 4014  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 4078  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 4103  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 4171  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 4238  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 5000  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 5042  else if (common->has_set_som || common-> Line 5447  else if (common->has_set_som || common->
5447    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5448    }    }
5449    
5450  if (entry->entry == NULL)  if (entry->entry == NULL)
5451    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
5452    else
5453      JUMPTO(SLJIT_FAST_CALL, entry->entry);
5454    /* Leave if the match is failed. */
5455    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
5456    return cc + 1 + LINK_SIZE;
5457    }
5458    
5459    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5460    {
5461    const pcre_uchar *begin = arguments->begin;
5462    int *offset_vector = arguments->offsets;
5463    int offset_count = arguments->offset_count;
5464    int i;
5465    
5466    if (PUBL(callout) == NULL)
5467      return 0;
5468    
5469    callout_block->version = 2;
5470    callout_block->callout_data = arguments->callout_data;
5471    
5472    /* Offsets in subject. */
5473    callout_block->subject_length = arguments->end - arguments->begin;
5474    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5475    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5476    #if defined COMPILE_PCRE8
5477    callout_block->subject = (PCRE_SPTR)begin;
5478    #elif defined COMPILE_PCRE16
5479    callout_block->subject = (PCRE_SPTR16)begin;
5480    #elif defined COMPILE_PCRE32
5481    callout_block->subject = (PCRE_SPTR32)begin;
5482    #endif
5483    
5484    /* Convert and copy the JIT offset vector to the offset_vector array. */
5485    callout_block->capture_top = 0;
5486    callout_block->offset_vector = offset_vector;
5487    for (i = 2; i < offset_count; i += 2)
5488      {
5489      offset_vector[i] = jit_ovector[i] - begin;
5490      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5491      if (jit_ovector[i] >= begin)
5492        callout_block->capture_top = i;
5493      }
5494    
5495    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5496    if (offset_count > 0)
5497      offset_vector[0] = -1;
5498    if (offset_count > 1)
5499      offset_vector[1] = -1;
5500    return (*PUBL(callout))(callout_block);
5501    }
5502    
5503    /* Aligning to 8 byte. */
5504    #define CALLOUT_ARG_SIZE \
5505        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5506    
5507    #define CALLOUT_ARG_OFFSET(arg) \
5508        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5509    
5510    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5511    {
5512    DEFINE_COMPILER;
5513    backtrack_common *backtrack;
5514    
5515    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5516    
5517    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5518    
5519    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5520    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5521    SLJIT_ASSERT(common->capture_last_ptr != 0);
5522    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5523    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. */
5526    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5527    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5528    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5529    
5530    if (common->mark_ptr != 0)
5531      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5532    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5533    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);
5535    
5536    /* Needed to save important temporary registers. */
5537    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5538    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5539    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5540    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5541    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5542    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5543    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5544    
5545    /* Check return value. */
5546    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5547    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5548    if (common->forced_quit_label == NULL)
5549      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5550  else  else
5551    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5552  /* Leave if the match is failed. */  return cc + 2 + 2 * LINK_SIZE;
 add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));  
 return cc + 1 + LINK_SIZE;  
5553  }  }
5554    
5555    #undef CALLOUT_ARG_SIZE
5556    #undef CALLOUT_ARG_OFFSET
5557    
5558  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
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 5064  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  struct sljit_label *save_quitlabel = common->quitlabel;  BOOL save_local_exit = common->local_exit;
5574  struct sljit_label *save_acceptlabel = common->acceptlabel;  then_trap_backtrack *save_then_trap = common->then_trap;
5575    struct sljit_label *save_quit_label = common->quit_label;
5576    struct sljit_label *save_accept_label = common->accept_label;
5577  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5578  jump_list *save_accept = common->accept;  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 5079  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 5098  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->quitlabel = NULL;  common->local_exit = TRUE;
5648    common->quit_label = NULL;
5649  common->quit = NULL;  common->quit = NULL;
5650  while (1)  while (1)
5651    {    {
5652    common->acceptlabel = NULL;    common->accept_label = NULL;
5653    common->accept = NULL;    common->accept = NULL;
5654    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5655    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5130  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->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5665      common->acceptlabel = save_acceptlabel;      common->then_trap = save_then_trap;
5666        common->quit_label = save_quit_label;
5667        common->accept_label = save_accept_label;
5668      common->quit = save_quit;      common->quit = save_quit;
5669      common->accept = save_accept;      common->accept = save_accept;
5670      return NULL;      return NULL;
5671      }      }
5672    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5673    if (common->accept != NULL)    if (common->accept != NULL)
5674      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
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 5185  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->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5734      common->acceptlabel = save_acceptlabel;      common->then_trap = save_then_trap;
5735        common->quit_label = save_quit_label;
5736        common->accept_label = save_accept_label;
5737      common->quit = save_quit;      common->quit = save_quit;
5738      common->accept = save_accept;      common->accept = save_accept;
5739      return NULL;      return NULL;
# Line 5199  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 5213  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 5239  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 5255  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 5291  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 5326  else Line 5911  else
5911      }      }
5912    }    }
5913    
5914  common->quitlabel = save_quitlabel;  common->local_exit = save_local_exit;
5915  common->acceptlabel = save_acceptlabel;  common->then_trap = save_then_trap;
5916    common->quit_label = save_quit_label;
5917    common->accept_label = save_accept_label;
5918  common->quit = save_quit;  common->quit = save_quit;
5919  common->accept = save_accept;  common->accept = save_accept;
5920  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
# Line 5443  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 5511  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 5586  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 5600  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 5663  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)
6402    {    {
6403    /* Saving the previous values. */    /* Saving the previous values. */
6404    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
     {  
     allocate_stack(common, 3);  
     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(0), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);  
     }  
   else  
6405      {      {
6406      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
6407      allocate_stack(common, 2);      allocate_stack(common, 2);
# Line 5730  else if (opcode == OP_CBRA || opcode == Line 6411  else if (opcode == OP_CBRA || opcode ==
6411      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6412      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6413      }      }
6414      else
6415        {
6416        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6417        allocate_stack(common, 1);
6418        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
6419        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6420        }
6421    }    }
6422  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
6423    {    {
# Line 5843  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)
6538    stacksize++;    stacksize++;
6539    if (offset != 0)
6540      {
6541      if (common->capture_last_ptr != 0)
6542        stacksize++;
6543      if (common->optimized_cbracket[offset >> 1] == 0)
6544        stacksize += 2;
6545      }
6546  if (has_alternatives && opcode != OP_ONCE)  if (has_alternatives && opcode != OP_ONCE)
6547    stacksize++;    stacksize++;
6548    
# Line 5878  if (stacksize > 0) Line 6550  if (stacksize > 0)
6550    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6551    
6552  stacksize = 0;  stacksize = 0;
6553  if (ket != OP_KET)  if (ket != OP_KET || bra != OP_BRA)
   {  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);  
   stacksize++;  
   }  
 else if (bra != OP_BRA)  
6554    {    {
6555    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    if (ket != OP_KET)
6556        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6557      else
6558        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6559    stacksize++;    stacksize++;
6560    }    }
6561    
6562    if (offset != 0)
6563      stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
6564    
6565  if (has_alternatives)  if (has_alternatives)
6566    {    {
6567    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
# Line 5898  if (has_alternatives) Line 6571  if (has_alternatives)
6571    }    }
6572    
6573  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
6574  if (offset != 0)  if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
6575    {    {
6576    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
6577    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);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);  
6578    }    }
6579    
6580  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
# Line 5959  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 5969  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 6012  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 6080  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 6104  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 6132  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 6142  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 6168  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 6296  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 6498  static SLJIT_INLINE pcre_uchar *compile_ Line 7231  static SLJIT_INLINE pcre_uchar *compile_
7231  DEFINE_COMPILER;  DEFINE_COMPILER;
7232  backtrack_common *backtrack;  backtrack_common *backtrack;
7233    
7234  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7235    
7236  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
7237    {    {
# Line 6509  if (*cc == OP_FAIL) Line 7242  if (*cc == OP_FAIL)
7242  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
7243    {    {
7244    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
7245    if (common->acceptlabel == NULL)    if (common->accept_label == NULL)
7246      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7247    else    else
7248      JUMPTO(SLJIT_JUMP, common->acceptlabel);      JUMPTO(SLJIT_JUMP, common->accept_label);
7249    return cc + 1;    return cc + 1;
7250    }    }
7251    
7252  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
7253    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
7254  else  else
7255    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->accept_label);
7256  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7257  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));
7258  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
7259  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));
7260  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
7261    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
7262  else  else
7263    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
7264  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));
7265  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
7266    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
7267  else  else
7268    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
7269  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
7270  return cc + 1;  return cc + 1;
7271  }  }
7272    
7273  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_matchingpath(compiler_common *common, pcre_uchar *cc)
7274    {
7275    DEFINE_COMPILER;
7276    int offset = GET2(cc, 1);
7277    BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;
7278    
7279    /* Data will be discarded anyway... */
7280    if (common->currententry != NULL)
7281      return cc + 1 + IMM2_SIZE;
7282    
7283    if (!optimized_cbracket)
7284      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
7285    offset <<= 1;
7286    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7287    if (!optimized_cbracket)
7288      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7289    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;  DEFINE_COMPILER;
7342  int offset = GET2(cc, 1);  backtrack_common *backtrack;
7343  BOOL optimized_cbracket = common->optimized_cbracket[offset] != 0;  BOOL needs_control_head;
7344    int size;
 /* Data will be discarded anyway... */  
 if (common->currententry != NULL)  
   return cc + 1 + IMM2_SIZE;  
7345    
7346  if (!optimized_cbracket)  PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7347    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7348  offset <<= 1;  BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7349  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7350  if (!optimized_cbracket)  BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7351    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
7352  return cc + 1 + IMM2_SIZE;  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 6712  while (cc < ccend) Line 7536  while (cc < ccend)
7536      cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
7537      break;      break;
7538    
7539        case OP_CALLOUT:
7540        cc = compile_callout_matchingpath(common, cc, parent);
7541        break;
7542    
7543      case OP_ASSERT:      case OP_ASSERT:
7544      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7545      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 6772  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 6807  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 6968  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 6990  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 7096  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 7121  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 7160  else if (bra == OP_BRAZERO) Line 8023  else if (bra == OP_BRAZERO)
8023    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
8024    }    }
8025    
8026    if (offset != 0)
8027      {
8028      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));
8032        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);
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      else if (common->optimized_cbracket[offset >> 1] == 0)
8040        {
8041        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8042        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8043        free_stack(common, 2);
8044        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
8045        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
8046        }
8047      }
8048    
8049  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
8050    {    {
8051    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7255  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 7274  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;
     if (opcode != OP_ONCE)  
       stacksize++;  
8172      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
8173        stacksize++;        stacksize++;
8174        if (offset != 0)
8175          {
8176          if (common->capture_last_ptr != 0)
8177            stacksize++;
8178          if (common->optimized_cbracket[offset >> 1] == 0)
8179            stacksize += 2;
8180          }
8181        if (opcode != OP_ONCE)
8182          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 7313  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 7325  if (has_alternatives) Line 8203  if (has_alternatives)
8203        stacksize++;        stacksize++;
8204        }        }
8205    
8206        if (offset != 0)
8207          stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
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++);
8211    
8212      if (offset != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
8213        {        {
8214        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
8215          SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
8216        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);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);  
8217        }        }
8218    
8219      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
# Line 7357  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 7374  if (has_alternatives) Line 8254  if (has_alternatives)
8254  if (offset != 0)  if (offset != 0)
8255    {    {
8256    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
8257    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
8258      {      {
8259      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8260      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8261        free_stack(common, 2);
8262      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
     free_stack(common, 3);  
8263      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);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);  
8264      }      }
8265    else    else
8266      {      {
8267      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8268      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      free_stack(common, 1);
8269      free_stack(common, 2);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);  
8270      }      }
8271    }    }
8272  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
# Line 7401  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 7463  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 7477  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 7498  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 7522  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 7658  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      if (common->quitlabel == NULL)        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8674        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
8677        JUMPTO(SLJIT_JUMP, common->quitlabel);        JUMPTO(SLJIT_JUMP, common->quit_label);
8678      break;      break;
8679    
8680        case OP_CALLOUT:
8681      case OP_FAIL:      case OP_FAIL:
8682      case OP_ACCEPT:      case OP_ACCEPT:
8683      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
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 7691  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_quitlabel = common->quitlabel;  
 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    
8724  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
8725  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
8726  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
8727    
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  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  if (needs_control_head)
8733  if (needsframe)    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8734    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8735    if (needs_frame)
8736      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);
8740    
8741  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
8742  common->quitlabel = NULL;  common->quit_label = NULL;
8743  common->acceptlabel = NULL;  common->accept_label = NULL;
8744  common->quit = NULL;  common->quit = NULL;
8745  common->accept = NULL;  common->accept = NULL;
8746  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
# Line 7738  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->quitlabel = save_quitlabel;  
     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->quitlabel = save_quitlabel;  
     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 7761  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);  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 7779  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, 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->quitlabel = save_quitlabel;  
 common->quit = save_quit;  
8823  }  }
8824    
8825  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 7807  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;
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 7881  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 7904  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 7912  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. */
8989    if (common->capture_last_ptr != 0)
8990      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 7932  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;