/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

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

revision 1245 by zherczeg, Sat Feb 9 11:30:51 2013 UTC revision 1291 by zherczeg, Sun Mar 17 05:27:48 2013 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2012 University of Cambridge             Copyright (c) 1997-2013 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2012                        Copyright (c) 2010-2013
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68    /* Defines for debugging purposes. */
69    
70    /* 1 - Use unoptimized capturing brackets.
71       2 - Enable capture_last_ptr (includes option 1). */
72    /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
78  Fast, but limited size. */  Fast, but limited size. */
79  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 159  typedef struct jit_arguments { Line 168  typedef struct jit_arguments {
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169    void *callout_data;    void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171      int real_offset_count;
172    int offset_count;    int offset_count;
173    int call_limit;    int call_limit;
174    pcre_uint8 notbol;    pcre_uint8 notbol;
# Line 180  typedef struct jump_list { Line 190  typedef struct jump_list {
190    struct jump_list *next;    struct jump_list *next;
191  } jump_list;  } jump_list;
192    
 enum stub_types { stack_alloc };  
   
193  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   int data;  
194    struct sljit_jump *start;    struct sljit_jump *start;
195    struct sljit_label *quit;    struct sljit_label *quit;
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199    enum frame_types {
200      no_frame = -1,
201      no_stack = -2
202    };
203    
204    enum control_types {
205      type_mark = 0,
206      type_then_trap = 1
207    };
208    
209  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
210    
211  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
# Line 210  typedef struct backtrack_common { Line 226  typedef struct backtrack_common {
226  typedef struct assert_backtrack {  typedef struct assert_backtrack {
227    backtrack_common common;    backtrack_common common;
228    jump_list *condfailed;    jump_list *condfailed;
229    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
230    int framesize;    int framesize;
231    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
232    int private_data_ptr;    int private_data_ptr;
# Line 231  typedef struct bracket_backtrack { Line 247  typedef struct bracket_backtrack {
247      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
248      jump_list *condfailed;      jump_list *condfailed;
249      assert_backtrack *assert;      assert_backtrack *assert;
250      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
251      int framesize;      int framesize;
252    } u;    } u;
253    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 266  typedef struct recurse_entry { Line 282  typedef struct recurse_entry {
282    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
283    jump_list *calls;    jump_list *calls;
284    /* Points to the starting opcode. */    /* Points to the starting opcode. */
285    int start;    sljit_sw start;
286  } recurse_entry;  } recurse_entry;
287    
288  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
289    backtrack_common common;    backtrack_common common;
290      BOOL inlined_pattern;
291  } recurse_backtrack;  } recurse_backtrack;
292    
293    #define OP_THEN_TRAP OP_TABLE_LENGTH
294    
295    typedef struct then_trap_backtrack {
296      backtrack_common common;
297      /* If then_trap is not NULL, this structure contains the real
298      then_trap for the backtracking path. */
299      struct then_trap_backtrack *then_trap;
300      /* Points to the starting opcode. */
301      sljit_sw start;
302      /* Exit point for the then opcodes of this alternative. */
303      jump_list *quit;
304      /* Frame size of the current alternative. */
305      int framesize;
306    } then_trap_backtrack;
307    
308  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
309    
310  typedef struct compiler_common {  typedef struct compiler_common {
311      /* The sljit ceneric compiler. */
312    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
313      /* First byte code. */
314    pcre_uchar *start;    pcre_uchar *start;
   
315    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
316    int *private_data_ptrs;    int *private_data_ptrs;
317    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
318    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
319      /* Tells whether the starting offset is a target of then. */
320      pcre_uint8 *then_offsets;
321      /* Current position where a THEN must jump. */
322      then_trap_backtrack *then_trap;
323    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
324    int cbraptr;    int cbra_ptr;
325    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
326    int ovector_start;    int ovector_start;
327    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
328    int req_char_ptr;    int req_char_ptr;
# Line 299  typedef struct compiler_common { Line 336  typedef struct compiler_common {
336    int first_line_end;    int first_line_end;
337    /* Points to the marked string. */    /* Points to the marked string. */
338    int mark_ptr;    int mark_ptr;
339      /* Recursive control verb management chain. */
340      int control_head_ptr;
341    /* Points to the last matched capture block index. */    /* Points to the last matched capture block index. */
342    int capture_last_ptr;    int capture_last_ptr;
343      /* Points to the starting position of the current match. */
344      int start_ptr;
345    
346    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
347    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
348    sljit_sw lcc;    sljit_sw lcc;
349    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
350    int mode;    int mode;
351      /* \K is found in the pattern. */
352      BOOL has_set_som;
353      /* (*SKIP:arg) is found in the pattern. */
354      BOOL has_skip_arg;
355      /* (*THEN) is found in the pattern. */
356      BOOL has_then;
357      /* Needs to know the start position anytime. */
358      BOOL needs_start_ptr;
359      /* Currently in recurse or assert. */
360      BOOL local_exit;
361    /* Newline control. */    /* Newline control. */
362    int nltype;    int nltype;
363    int newline;    int newline;
364    int bsr_nltype;    int bsr_nltype;
365    /* Dollar endonly. */    /* Dollar endonly. */
366    int endonly;    int endonly;
   BOOL has_set_som;  
367    /* Tables. */    /* Tables. */
368    sljit_sw ctypes;    sljit_sw ctypes;
369    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 343  typedef struct compiler_common { Line 393  typedef struct compiler_common {
393    jump_list *vspace;    jump_list *vspace;
394    jump_list *casefulcmp;    jump_list *casefulcmp;
395    jump_list *caselesscmp;    jump_list *caselesscmp;
396      jump_list *reset_match;
397    BOOL jscript_compat;    BOOL jscript_compat;
398  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
399    BOOL utf;    BOOL utf;
# Line 395  typedef struct compare_context { Line 446  typedef struct compare_context {
446  #endif  #endif
447  } compare_context;  } compare_context;
448    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
449  /* Undefine sljit macros. */  /* Undefine sljit macros. */
450  #undef CMP  #undef CMP
451    
# Line 433  group contains the start / end character Line 478  group contains the start / end character
478  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. */
479  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
480  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
481  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
482  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
483    
484  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 464  the start pointers when the end of the c Line 509  the start pointers when the end of the c
509    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
510  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
511    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
512    #define SET_LABEL(jump, label) \
513      sljit_set_label((jump), (label))
514  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
515    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
516  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
# Line 488  return cc; Line 535  return cc;
535   set_private_data_ptrs   set_private_data_ptrs
536   get_framesize   get_framesize
537   init_frame   init_frame
538   get_private_data_length_for_copy   get_private_data_copy_length
539   copy_private_data   copy_private_data
540   compile_matchingpath   compile_matchingpath
541   compile_backtrackingpath   compile_backtrackingpath
# Line 512  switch(*cc) Line 559  switch(*cc)
559    case OP_WORDCHAR:    case OP_WORDCHAR:
560    case OP_ANY:    case OP_ANY:
561    case OP_ALLANY:    case OP_ALLANY:
562      case OP_NOTPROP:
563      case OP_PROP:
564    case OP_ANYNL:    case OP_ANYNL:
565    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
566    case OP_HSPACE:    case OP_HSPACE:
# Line 524  switch(*cc) Line 573  switch(*cc)
573    case OP_CIRCM:    case OP_CIRCM:
574    case OP_DOLL:    case OP_DOLL:
575    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:  
576    case OP_CRSTAR:    case OP_CRSTAR:
577    case OP_CRMINSTAR:    case OP_CRMINSTAR:
578    case OP_CRPLUS:    case OP_CRPLUS:
579    case OP_CRMINPLUS:    case OP_CRMINPLUS:
580    case OP_CRQUERY:    case OP_CRQUERY:
581    case OP_CRMINQUERY:    case OP_CRMINQUERY:
582      case OP_CRRANGE:
583      case OP_CRMINRANGE:
584      case OP_CLASS:
585      case OP_NCLASS:
586      case OP_REF:
587      case OP_REFI:
588      case OP_RECURSE:
589      case OP_CALLOUT:
590      case OP_ALT:
591      case OP_KET:
592      case OP_KETRMAX:
593      case OP_KETRMIN:
594      case OP_KETRPOS:
595      case OP_REVERSE:
596      case OP_ASSERT:
597      case OP_ASSERT_NOT:
598      case OP_ASSERTBACK:
599      case OP_ASSERTBACK_NOT:
600      case OP_ONCE:
601      case OP_ONCE_NC:
602      case OP_BRA:
603      case OP_BRAPOS:
604      case OP_CBRA:
605      case OP_CBRAPOS:
606      case OP_COND:
607      case OP_SBRA:
608      case OP_SBRAPOS:
609      case OP_SCBRA:
610      case OP_SCBRAPOS:
611      case OP_SCOND:
612      case OP_CREF:
613      case OP_NCREF:
614      case OP_RREF:
615      case OP_NRREF:
616    case OP_DEF:    case OP_DEF:
617    case OP_BRAZERO:    case OP_BRAZERO:
618    case OP_BRAMINZERO:    case OP_BRAMINZERO:
619    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
620      case OP_PRUNE:
621      case OP_SKIP:
622      case OP_THEN:
623    case OP_COMMIT:    case OP_COMMIT:
624    case OP_FAIL:    case OP_FAIL:
625    case OP_ACCEPT:    case OP_ACCEPT:
626    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
627      case OP_CLOSE:
628    case OP_SKIPZERO:    case OP_SKIPZERO:
629    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
630    
631    case OP_CHAR:    case OP_CHAR:
632    case OP_CHARI:    case OP_CHARI:
# Line 566  switch(*cc) Line 638  switch(*cc)
638    case OP_MINPLUS:    case OP_MINPLUS:
639    case OP_QUERY:    case OP_QUERY:
640    case OP_MINQUERY:    case OP_MINQUERY:
641      case OP_UPTO:
642      case OP_MINUPTO:
643      case OP_EXACT:
644    case OP_POSSTAR:    case OP_POSSTAR:
645    case OP_POSPLUS:    case OP_POSPLUS:
646    case OP_POSQUERY:    case OP_POSQUERY:
647      case OP_POSUPTO:
648    case OP_STARI:    case OP_STARI:
649    case OP_MINSTARI:    case OP_MINSTARI:
650    case OP_PLUSI:    case OP_PLUSI:
651    case OP_MINPLUSI:    case OP_MINPLUSI:
652    case OP_QUERYI:    case OP_QUERYI:
653    case OP_MINQUERYI:    case OP_MINQUERYI:
654      case OP_UPTOI:
655      case OP_MINUPTOI:
656      case OP_EXACTI:
657    case OP_POSSTARI:    case OP_POSSTARI:
658    case OP_POSPLUSI:    case OP_POSPLUSI:
659    case OP_POSQUERYI:    case OP_POSQUERYI:
660      case OP_POSUPTOI:
661    case OP_NOTSTAR:    case OP_NOTSTAR:
662    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
663    case OP_NOTPLUS:    case OP_NOTPLUS:
664    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
665    case OP_NOTQUERY:    case OP_NOTQUERY:
666    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
667      case OP_NOTUPTO:
668      case OP_NOTMINUPTO:
669      case OP_NOTEXACT:
670    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
671    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
672    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
673      case OP_NOTPOSUPTO:
674    case OP_NOTSTARI:    case OP_NOTSTARI:
675    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
676    case OP_NOTPLUSI:    case OP_NOTPLUSI:
677    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
678    case OP_NOTQUERYI:    case OP_NOTQUERYI:
679    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:  
680    case OP_NOTUPTOI:    case OP_NOTUPTOI:
681    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
682    case OP_NOTEXACTI:    case OP_NOTEXACTI:
683      case OP_NOTPOSSTARI:
684      case OP_NOTPOSPLUSI:
685      case OP_NOTPOSQUERYI:
686    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
687    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
688  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
689    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
690  #endif  #endif
691    return cc;    return cc;
692    
693    case OP_NOTPROP:    /* Special cases. */
694    case OP_PROP:    case OP_TYPESTAR:
695    return cc + 1 + 2;    case OP_TYPEMINSTAR:
696      case OP_TYPEPLUS:
697      case OP_TYPEMINPLUS:
698      case OP_TYPEQUERY:
699      case OP_TYPEMINQUERY:
700    case OP_TYPEUPTO:    case OP_TYPEUPTO:
701    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
702    case OP_TYPEEXACT:    case OP_TYPEEXACT:
703      case OP_TYPEPOSSTAR:
704      case OP_TYPEPOSPLUS:
705      case OP_TYPEPOSQUERY:
706    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
707    case OP_REF:    return cc + PRIV(OP_lengths)[*cc] - 1;
   case OP_REFI:  
   case OP_CREF:  
   case OP_NCREF:  
   case OP_RREF:  
   case OP_NRREF:  
   case OP_CLOSE:  
   cc += 1 + IMM2_SIZE;  
   return cc;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   return cc + 1 + 2 * IMM2_SIZE;  
708    
709    case OP_CLASS:    case OP_ANYBYTE:
710    case OP_NCLASS:  #ifdef SUPPORT_UTF
711    return cc + 1 + 32 / sizeof(pcre_uchar);    if (common->utf) return NULL;
712    #endif
713      return cc + 1;
714    
715  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
716    case OP_XCLASS:    case OP_XCLASS:
717    return cc + GET(cc, 1);    return cc + GET(cc, 1);
718  #endif  #endif
719    
   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;  
   
720    case OP_MARK:    case OP_MARK:
721      case OP_PRUNE_ARG:
722      case OP_SKIP_ARG:
723      case OP_THEN_ARG:
724    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
725    
   case OP_CALLOUT:  
   return cc + 2 + 2 * LINK_SIZE;  
   
726    default:    default:
727      /* All opcodes are supported now! */
728      SLJIT_ASSERT_STOP();
729    return NULL;    return NULL;
730    }    }
731  }  }
# Line 937  while (cc < ccend) Line 974  while (cc < ccend)
974      cc += 2 + 2 * LINK_SIZE;      cc += 2 + 2 * LINK_SIZE;
975      break;      break;
976    
977        case OP_THEN_ARG:
978        common->has_then = TRUE;
979        common->control_head_ptr = 1;
980        /* Fall through. */
981    
982        case OP_PRUNE_ARG:
983        common->needs_start_ptr = TRUE;
984        /* Fall through. */
985    
986      case OP_MARK:      case OP_MARK:
987      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
988        {        {
# Line 946  while (cc < ccend) Line 992  while (cc < ccend)
992      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
993      break;      break;
994    
995        case OP_THEN:
996        common->has_then = TRUE;
997        common->control_head_ptr = 1;
998        /* Fall through. */
999    
1000        case OP_PRUNE:
1001        case OP_SKIP:
1002        common->needs_start_ptr = TRUE;
1003        cc += 1;
1004        break;
1005    
1006        case OP_SKIP_ARG:
1007        common->control_head_ptr = 1;
1008        common->has_skip_arg = TRUE;
1009        cc += 1 + 2 + cc[1];
1010        break;
1011    
1012      default:      default:
1013      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1014      if (cc == NULL)      if (cc == NULL)
# Line 1122  while (cc < ccend) Line 1185  while (cc < ccend)
1185    }    }
1186  }  }
1187    
1188  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1189  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)
1190  {  {
 pcre_uchar *ccend = bracketend(cc);  
1191  int length = 0;  int length = 0;
1192  BOOL possessive = FALSE;  int possessive = 0;
1193    BOOL stack_restore = FALSE;
1194  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1195  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1196    /* The last capture is a local variable even for recursions. */
1197    BOOL capture_last_found = FALSE;
1198    
1199  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1200    SLJIT_ASSERT(common->control_head_ptr != 0);
1201    *needs_control_head = TRUE;
1202    #else
1203    *needs_control_head = FALSE;
1204    #endif
1205    
1206    if (ccend == NULL)
1207    {    {
1208    length = 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1209    possessive = TRUE;    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1210        {
1211        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1212        /* This is correct regardless of common->capture_last_ptr. */
1213        capture_last_found = TRUE;
1214        }
1215      cc = next_opcode(common, cc);
1216    }    }
1217    
 cc = next_opcode(common, cc);  
1218  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1219  while (cc < ccend)  while (cc < ccend)
1220    switch(*cc)    switch(*cc)
1221      {      {
1222      case OP_SET_SOM:      case OP_SET_SOM:
1223      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1224        stack_restore = TRUE;
1225      if (!setsom_found)      if (!setsom_found)
1226        {        {
1227        length += 2;        length += 2;
# Line 1153  while (cc < ccend) Line 1231  while (cc < ccend)
1231      break;      break;
1232    
1233      case OP_MARK:      case OP_MARK:
1234        case OP_PRUNE_ARG:
1235        case OP_THEN_ARG:
1236      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1237        stack_restore = TRUE;
1238      if (!setmark_found)      if (!setmark_found)
1239        {        {
1240        length += 2;        length += 2;
1241        setmark_found = TRUE;        setmark_found = TRUE;
1242        }        }
1243        if (common->control_head_ptr != 0)
1244          *needs_control_head = TRUE;
1245      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1246      break;      break;
1247    
1248      case OP_RECURSE:      case OP_RECURSE:
1249        stack_restore = TRUE;
1250      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1251        {        {
1252        length += 2;        length += 2;
# Line 1173  while (cc < ccend) Line 1257  while (cc < ccend)
1257        length += 2;        length += 2;
1258        setmark_found = TRUE;        setmark_found = TRUE;
1259        }        }
1260        if (common->capture_last_ptr != 0 && !capture_last_found)
1261          {
1262          length += 2;
1263          capture_last_found = TRUE;
1264          }
1265      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1266      break;      break;
1267    
# Line 1180  while (cc < ccend) Line 1269  while (cc < ccend)
1269      case OP_CBRAPOS:      case OP_CBRAPOS:
1270      case OP_SCBRA:      case OP_SCBRA:
1271      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1272        stack_restore = TRUE;
1273        if (common->capture_last_ptr != 0 && !capture_last_found)
1274          {
1275          length += 2;
1276          capture_last_found = TRUE;
1277          }
1278      length += 3;      length += 3;
1279      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1280      break;      break;
1281    
1282      default:      default:
1283        stack_restore = TRUE;
1284        /* Fall through. */
1285    
1286        case OP_NOT_WORD_BOUNDARY:
1287        case OP_WORD_BOUNDARY:
1288        case OP_NOT_DIGIT:
1289        case OP_DIGIT:
1290        case OP_NOT_WHITESPACE:
1291        case OP_WHITESPACE:
1292        case OP_NOT_WORDCHAR:
1293        case OP_WORDCHAR:
1294        case OP_ANY:
1295        case OP_ALLANY:
1296        case OP_ANYBYTE:
1297        case OP_NOTPROP:
1298        case OP_PROP:
1299        case OP_ANYNL:
1300        case OP_NOT_HSPACE:
1301        case OP_HSPACE:
1302        case OP_NOT_VSPACE:
1303        case OP_VSPACE:
1304        case OP_EXTUNI:
1305        case OP_EODN:
1306        case OP_EOD:
1307        case OP_CIRC:
1308        case OP_CIRCM:
1309        case OP_DOLL:
1310        case OP_DOLLM:
1311        case OP_CHAR:
1312        case OP_CHARI:
1313        case OP_NOT:
1314        case OP_NOTI:
1315    
1316        case OP_EXACT:
1317        case OP_POSSTAR:
1318        case OP_POSPLUS:
1319        case OP_POSQUERY:
1320        case OP_POSUPTO:
1321    
1322        case OP_EXACTI:
1323        case OP_POSSTARI:
1324        case OP_POSPLUSI:
1325        case OP_POSQUERYI:
1326        case OP_POSUPTOI:
1327    
1328        case OP_NOTEXACT:
1329        case OP_NOTPOSSTAR:
1330        case OP_NOTPOSPLUS:
1331        case OP_NOTPOSQUERY:
1332        case OP_NOTPOSUPTO:
1333    
1334        case OP_NOTEXACTI:
1335        case OP_NOTPOSSTARI:
1336        case OP_NOTPOSPLUSI:
1337        case OP_NOTPOSQUERYI:
1338        case OP_NOTPOSUPTOI:
1339    
1340        case OP_TYPEEXACT:
1341        case OP_TYPEPOSSTAR:
1342        case OP_TYPEPOSPLUS:
1343        case OP_TYPEPOSQUERY:
1344        case OP_TYPEPOSUPTO:
1345    
1346        case OP_CLASS:
1347        case OP_NCLASS:
1348        case OP_XCLASS:
1349    
1350      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1351      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1352      break;      break;
1353      }      }
1354    
1355  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1356  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1357    return -1;    return stack_restore ? no_frame : no_stack;
1358    
1359  if (length > 0)  if (length > 0)
1360    return length + 1;    return length + 1;
1361  return -1;  return stack_restore ? no_frame : no_stack;
1362  }  }
1363    
1364  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)
1365  {  {
1366  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc);  
1367  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1368  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1369    /* The last capture is a local variable even for recursions. */
1370    BOOL capture_last_found = FALSE;
1371  int offset;  int offset;
1372    
1373  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1212  SLJIT_UNUSED_ARG(stacktop); Line 1375  SLJIT_UNUSED_ARG(stacktop);
1375  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1376    
1377  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1378  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1379    cc = next_opcode(common, cc);    {
1380      ccend = bracketend(cc) - (1 + LINK_SIZE);
1381      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1382        cc = next_opcode(common, cc);
1383      }
1384    
1385  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1386  while (cc < ccend)  while (cc < ccend)
1387    switch(*cc)    switch(*cc)
# Line 1223  while (cc < ccend) Line 1391  while (cc < ccend)
1391      if (!setsom_found)      if (!setsom_found)
1392        {        {
1393        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1394        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1395        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1396        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1397        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1233  while (cc < ccend) Line 1401  while (cc < ccend)
1401      break;      break;
1402    
1403      case OP_MARK:      case OP_MARK:
1404        case OP_PRUNE_ARG:
1405        case OP_THEN_ARG:
1406      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1407      if (!setmark_found)      if (!setmark_found)
1408        {        {
1409        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);
1410        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);
1411        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1412        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1413        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1250  while (cc < ccend) Line 1420  while (cc < ccend)
1420      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1421        {        {
1422        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1423        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1424        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1425        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1426        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1259  while (cc < ccend) Line 1429  while (cc < ccend)
1429      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1430        {        {
1431        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);
1432        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);
1433        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1434        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1435        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1436        setmark_found = TRUE;        setmark_found = TRUE;
1437        }        }
1438        if (common->capture_last_ptr != 0 && !capture_last_found)
1439          {
1440          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1441          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1442          stackpos += (int)sizeof(sljit_sw);
1443          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1444          stackpos += (int)sizeof(sljit_sw);
1445          capture_last_found = TRUE;
1446          }
1447      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1448      break;      break;
1449    
# Line 1272  while (cc < ccend) Line 1451  while (cc < ccend)
1451      case OP_CBRAPOS:      case OP_CBRAPOS:
1452      case OP_SCBRA:      case OP_SCBRA:
1453      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1454        if (common->capture_last_ptr != 0 && !capture_last_found)
1455          {
1456          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1457          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1458          stackpos += (int)sizeof(sljit_sw);
1459          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1460          stackpos += (int)sizeof(sljit_sw);
1461          capture_last_found = TRUE;
1462          }
1463      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1464      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1465      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
# Line 1291  while (cc < ccend) Line 1479  while (cc < ccend)
1479      break;      break;
1480      }      }
1481    
1482  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1483  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1484  }  }
1485    
1486  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)
1487  {  {
1488  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1489  int size;  int size;
1490  pcre_uchar *alternative;  pcre_uchar *alternative;
1491  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1410  return private_data_length; Line 1598  return private_data_length;
1598  }  }
1599    
1600  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,
1601    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1602  {  {
1603  DEFINE_COMPILER;  DEFINE_COMPILER;
1604  int srcw[2];  int srcw[2];
# Line 1431  stacktop = STACK(stacktop - 1); Line 1619  stacktop = STACK(stacktop - 1);
1619    
1620  if (!save)  if (!save)
1621    {    {
1622    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1623    if (stackptr < stacktop)    if (stackptr < stacktop)
1624      {      {
1625      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1447  if (!save) Line 1635  if (!save)
1635    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1636    }    }
1637    
1638  while (status != end)  do
1639    {    {
1640    count = 0;    count = 0;
1641    switch(status)    switch(status)
# Line 1456  while (status != end) Line 1644  while (status != end)
1644      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1645      count = 1;      count = 1;
1646      srcw[0] = common->recursive_head_ptr;      srcw[0] = common->recursive_head_ptr;
1647        if (needs_control_head)
1648          {
1649          SLJIT_ASSERT(common->control_head_ptr != 0);
1650          count = 2;
1651          srcw[1] = common->control_head_ptr;
1652          }
1653      status = loop;      status = loop;
1654      break;      break;
1655    
# Line 1680  while (status != end) Line 1874  while (status != end)
1874        }        }
1875      }      }
1876    }    }
1877    while (status != end);
1878    
1879  if (save)  if (save)
1880    {    {
# Line 1710  if (save) Line 1905  if (save)
1905        }        }
1906      }      }
1907    }    }
1908  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1909    }
1910    
1911    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1912    {
1913    pcre_uchar *end = bracketend(cc);
1914    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1915    
1916    /* Assert captures then. */
1917    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1918      current_offset = NULL;
1919    /* Conditional block does not. */
1920    if (*cc == OP_COND || *cc == OP_SCOND)
1921      has_alternatives = FALSE;
1922    
1923    cc = next_opcode(common, cc);
1924    if (has_alternatives)
1925      current_offset = common->then_offsets + (cc - common->start);
1926    
1927    while (cc < end)
1928      {
1929      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1930        cc = set_then_offsets(common, cc, current_offset);
1931      else
1932        {
1933        if (*cc == OP_ALT && has_alternatives)
1934          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1935        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1936          *current_offset = 1;
1937        cc = next_opcode(common, cc);
1938        }
1939      }
1940    
1941    return end;
1942  }  }
1943    
1944  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
# Line 1731  while (list) Line 1959  while (list)
1959    {    {
1960    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1961    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1962    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1963    list = list->next;    list = list->next;
1964    }    }
1965  }  }
# Line 1747  if (list_item) Line 1975  if (list_item)
1975    }    }
1976  }  }
1977    
1978  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)
1979  {  {
1980  DEFINE_COMPILER;  DEFINE_COMPILER;
1981  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1982    
1983  if (list_item)  if (list_item)
1984    {    {
   list_item->type = type;  
   list_item->data = data;  
1985    list_item->start = start;    list_item->start = start;
1986    list_item->quit = LABEL();    list_item->quit = LABEL();
1987    list_item->next = common->stubs;    list_item->next = common->stubs;
# Line 1771  stub_list* list_item = common->stubs; Line 1997  stub_list* list_item = common->stubs;
1997  while (list_item)  while (list_item)
1998    {    {
1999    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
2000    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;  
     }  
2001    JUMPTO(SLJIT_JUMP, list_item->quit);    JUMPTO(SLJIT_JUMP, list_item->quit);
2002    list_item = list_item->next;    list_item = list_item->next;
2003    }    }
# Line 1804  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 2025  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2025  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
2026  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2027  #endif  #endif
2028  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));
2029  }  }
2030    
2031  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
# Line 1818  static SLJIT_INLINE void reset_ovector(c Line 2039  static SLJIT_INLINE void reset_ovector(c
2039  DEFINE_COMPILER;  DEFINE_COMPILER;
2040  struct sljit_label *loop;  struct sljit_label *loop;
2041  int i;  int i;
2042    
2043  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2044    SLJIT_ASSERT(length > 1);
2045  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2046  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));
2047  if (length < 8)  if (length < 8)
2048    {    {
2049    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2050      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);
2051    }    }
2052  else  else
2053    {    {
2054    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2055    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2056    loop = LABEL();    loop = LABEL();
2057    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);
2058    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 1837  else Line 2060  else
2060    }    }
2061  }  }
2062    
2063    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2064    {
2065    DEFINE_COMPILER;
2066    struct sljit_label *loop;
2067    int i;
2068    
2069    SLJIT_ASSERT(length > 1);
2070    /* OVECTOR(1) contains the "string begin - 1" constant. */
2071    if (length > 2)
2072      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2073    if (length < 8)
2074      {
2075      for (i = 2; i < length; i++)
2076        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2077      }
2078    else
2079      {
2080      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2081      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2082      loop = LABEL();
2083      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2084      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2085      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2086      }
2087    
2088    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2089    if (common->mark_ptr != 0)
2090      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2091    if (common->control_head_ptr != 0)
2092      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2093    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2094    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2095    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2096    }
2097    
2098    static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2099    {
2100    while (current != NULL)
2101      {
2102      switch (current[-2])
2103        {
2104        case type_then_trap:
2105        break;
2106    
2107        case type_mark:
2108        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2109          return current[-4];
2110        break;
2111    
2112        default:
2113        SLJIT_ASSERT_STOP();
2114        break;
2115        }
2116      current = (sljit_sw*)current[-1];
2117      }
2118    return -1;
2119    }
2120    
2121  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2122  {  {
2123  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1890  else Line 2171  else
2171  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)
2172  {  {
2173  DEFINE_COMPILER;  DEFINE_COMPILER;
2174    struct sljit_jump *jump;
2175    
2176  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);
2177  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
2178      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2179    
2180  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2181  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2182  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offset_count));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2183  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);
2184    
2185  /* Store match begin and end. */  /* Store match begin and end. */
2186  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));
2187  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));
2188    
2189    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2190    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);
2191    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2192    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2193    #endif
2194    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2195    JUMPHERE(jump);
2196    
2197  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);
2198  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);
2199  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 2078  else if (common->mode == JIT_PARTIAL_SOF Line 2370  else if (common->mode == JIT_PARTIAL_SOF
2370    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);
2371    
2372  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2373    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);
2374  else  else
2375    {    {
2376    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2091  if (jump != NULL) Line 2383  if (jump != NULL)
2383    JUMPHERE(jump);    JUMPHERE(jump);
2384  }  }
2385    
2386  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2387  {  {
2388  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2389  DEFINE_COMPILER;  DEFINE_COMPILER;
2390  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2391    
2392  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2393    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2394      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2395      return;
2396      }
2397    
2398  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2399  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2400    {    {
2401    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));
2402    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);
2403    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2404    }    }
2405  else  else
2406    {    {
2407    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));
2408    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2409      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2410    else    else
2411      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2412    }    }
2413  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2414  }  }
2415    
2416  static void detect_partial_match(compiler_common *common, jump_list **backtracks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
# Line 2138  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR Line 2429  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2429  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));
2430  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2431    {    {
2432    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);
2433    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2434    }    }
2435  else  else
# Line 3060  GET_LOCAL_BASE(TMP3, 0, 0); Line 3351  GET_LOCAL_BASE(TMP3, 0, 0);
3351  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3352  mainloop = LABEL();  mainloop = LABEL();
3353  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3354  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);
3355    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3356    
3357  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3358  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));
3359  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
# Line 3068  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I Line 3361  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
3361  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3362    
3363  JUMPHERE(jump);  JUMPHERE(jump);
3364  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3365  /* End of dropping frames. */  /* End of dropping frames. */
3366  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3367    
3368  JUMPHERE(jump);  JUMPHERE(jump);
3369  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3370  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3371  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. */  
3372  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));
3373  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3374  }  }
# Line 3101  static void check_wordboundary(compiler_ Line 3377  static void check_wordboundary(compiler_
3377  {  {
3378  DEFINE_COMPILER;  DEFINE_COMPILER;
3379  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3380    jump_list *skipread_list = NULL;
3381  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3382  struct sljit_jump *jump;  struct sljit_jump *jump;
3383  #endif  #endif
# Line 3158  else Line 3435  else
3435  JUMPHERE(skipread);  JUMPHERE(skipread);
3436    
3437  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3438  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3439  peek_char(common);  peek_char(common);
3440    
3441  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3199  else Line 3476  else
3476      JUMPHERE(jump);      JUMPHERE(jump);
3477  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3478    }    }
3479  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3480    
3481  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);
3482  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 3839  while (*cc != XCL_END) Line 4116  while (*cc != XCL_END)
4116        break;        break;
4117    
4118        case PT_CLIST:        case PT_CLIST:
4119          case PT_UCNC:
4120        needschar = TRUE;        needschar = TRUE;
4121        break;        break;
4122    
# Line 4040  while (*cc != XCL_END) Line 4318  while (*cc != XCL_END)
4318        case PT_WORD:        case PT_WORD:
4319        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);
4320        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4321        /* ... fall through */        /* Fall through. */
4322    
4323        case PT_ALNUM:        case PT_ALNUM:
4324        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
# Line 4104  while (*cc != XCL_END) Line 4382  while (*cc != XCL_END)
4382          }          }
4383        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4384        break;        break;
4385    
4386          case PT_UCNC:
4387          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
4388          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4389          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
4390          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4391          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
4392          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4393    
4394          SET_CHAR_OFFSET(0xa0);
4395          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4396          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4397          SET_CHAR_OFFSET(0);
4398          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4399          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4400          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4401          break;
4402        }        }
4403      cc += 2;      cc += 2;
4404      }      }
# Line 4129  int length; Line 4424  int length;
4424  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4425  compare_context context;  compare_context context;
4426  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4427    jump_list *end_list;
4428  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4429  struct sljit_label *label;  struct sljit_label *label;
4430  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4197  switch(type) Line 4493  switch(type)
4493    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4494      {      {
4495      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);
4496        end_list = NULL;
4497      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4498        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));
4499      else      else
4500        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4501    
4502      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4503      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));
4504      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4505      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4506      }      }
4507    else    else
# Line 4264  switch(type) Line 4560  switch(type)
4560    read_char(common);    read_char(common);
4561    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);
4562    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4563      end_list = NULL;
4564    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4565      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));
4566    else    else
4567      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4568    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4569    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);
4570    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));
4571    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4572    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4573    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4574      set_jumps(end_list, LABEL());
4575    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4576    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4577    return cc;    return cc;
4578    
4579    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 5026  DEFINE_COMPILER; Line 5323  DEFINE_COMPILER;
5323  backtrack_common *backtrack;  backtrack_common *backtrack;
5324  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5325  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5326  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5327    pcre_uchar *start_cc;
5328    BOOL needs_control_head;
5329    
5330  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5331    
5332    /* Inlining simple patterns. */
5333    if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5334      {
5335      start_cc = common->start + start;
5336      compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
5337      BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
5338      return cc + 1 + LINK_SIZE;
5339      }
5340    
5341  while (entry != NULL)  while (entry != NULL)
5342    {    {
5343    if (entry->start == start)    if (entry->start == start)
# Line 5140  allocate_stack(common, CALLOUT_ARG_SIZE Line 5449  allocate_stack(common, CALLOUT_ARG_SIZE
5449  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5450  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5451  SLJIT_ASSERT(common->capture_last_ptr != 0);  SLJIT_ASSERT(common->capture_last_ptr != 0);
5452  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5453  OP1(SLJIT_MOV_UI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5454    
5455  /* These pointer sized fields temporarly stores internal variables. */  /* These pointer sized fields temporarly stores internal variables. */
5456  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 5150  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA Line 5459  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CA
5459    
5460  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
5461    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5462  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5463  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));  OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5464  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5465    
5466  /* Needed to save important temporary registers. */  /* Needed to save important temporary registers. */
# Line 5180  static pcre_uchar *compile_assert_matchi Line 5489  static pcre_uchar *compile_assert_matchi
5489  {  {
5490  DEFINE_COMPILER;  DEFINE_COMPILER;
5491  int framesize;  int framesize;
5492    int extrasize;
5493    BOOL needs_control_head;
5494  int private_data_ptr;  int private_data_ptr;
5495  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5496  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5189  jump_list *tmp = NULL; Line 5500  jump_list *tmp = NULL;
5500  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5501  jump_list **found;  jump_list **found;
5502  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5503    BOOL save_local_exit = common->local_exit;
5504    then_trap_backtrack *save_then_trap = common->then_trap;
5505  struct sljit_label *save_quit_label = common->quit_label;  struct sljit_label *save_quit_label = common->quit_label;
5506  struct sljit_label *save_accept_label = common->accept_label;  struct sljit_label *save_accept_label = common->accept_label;
5507  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
# Line 5196  jump_list *save_accept = common->accept; Line 5509  jump_list *save_accept = common->accept;
5509  struct sljit_jump *jump;  struct sljit_jump *jump;
5510  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5511    
5512    /* Assert captures then. */
5513    common->then_trap = NULL;
5514    
5515  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5516    {    {
5517    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5204  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5520  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5520    }    }
5521  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5522  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5523  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5524  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5525  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5526  opcode = *cc;  opcode = *cc;
# Line 5223  if (bra == OP_BRAMINZERO) Line 5539  if (bra == OP_BRAMINZERO)
5539    
5540  if (framesize < 0)  if (framesize < 0)
5541    {    {
5542    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5543    allocate_stack(common, 1);    if (framesize == no_frame)
5544        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5545      allocate_stack(common, extrasize);
5546      if (needs_control_head)
5547        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5548    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5549      if (needs_control_head)
5550        {
5551        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5552        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5553        }
5554    }    }
5555  else  else
5556    {    {
5557    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5558      allocate_stack(common, framesize + extrasize);
5559    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);
5560    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));
5561    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);
5562      if (needs_control_head)
5563        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5564    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5565    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5566    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5567        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5568        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5569        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5570        }
5571      else
5572        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5573      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5574    }    }
5575    
5576  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5577    common->local_exit = TRUE;
5578  common->quit_label = NULL;  common->quit_label = NULL;
5579  common->quit = NULL;  common->quit = NULL;
5580  while (1)  while (1)
# Line 5255  while (1) Line 5591  while (1)
5591    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5592    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5593      {      {
5594        common->local_exit = save_local_exit;
5595        common->then_trap = save_then_trap;
5596      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5597      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5598      common->quit = save_quit;      common->quit = save_quit;
# Line 5267  while (1) Line 5605  while (1)
5605    
5606    /* Reset stack. */    /* Reset stack. */
5607    if (framesize < 0)    if (framesize < 0)
5608      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5609    else {      if (framesize == no_frame)
5610          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5611        else
5612          free_stack(common, extrasize);
5613        if (needs_control_head)
5614          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5615        }
5616      else
5617        {
5618      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5619        {        {
5620        /* 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. */
5621        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));
5622          if (needs_control_head)
5623            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5624        }        }
5625      else      else
5626        {        {
5627        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);
5628          if (needs_control_head)
5629            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5630        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5631        }        }
5632    }      }
5633    
5634    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5635      {      {
5636      /* 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. */
5637      if (conditional)      if (conditional)
5638        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);
5639      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5640        {        {
5641        if (framesize < 0)        if (framesize < 0)
5642          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));
5643        else        else
5644          {          {
5645          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));
5646          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));
5647          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);
5648          }          }
5649        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5310  while (1) Line 5660  while (1)
5660    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5661    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5662      {      {
5663        common->local_exit = save_local_exit;
5664        common->then_trap = save_then_trap;
5665      common->quit_label = save_quit_label;      common->quit_label = save_quit_label;
5666      common->accept_label = save_accept_label;      common->accept_label = save_accept_label;
5667      common->quit = save_quit;      common->quit = save_quit;
# Line 5324  while (1) Line 5676  while (1)
5676    ccbegin = cc;    ccbegin = cc;
5677    cc += GET(cc, 1);    cc += GET(cc, 1);
5678    }    }
5679    
5680  /* None of them matched. */  /* None of them matched. */
5681  if (common->quit != NULL)  if (common->quit != NULL)
5682      {
5683      jump = JUMP(SLJIT_JUMP);
5684    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5685      SLJIT_ASSERT(framesize != no_stack);
5686      if (framesize < 0)
5687        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5688      else
5689        {
5690        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5691        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5692        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5693        }
5694      JUMPHERE(jump);
5695      }
5696    
5697    if (needs_control_head)
5698      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5699    
5700  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5701    {    {
# Line 5338  if (opcode == OP_ASSERT || opcode == OP_ Line 5707  if (opcode == OP_ASSERT || opcode == OP_
5707      {      {
5708      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5709      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5710          {
5711          if (extrasize == 2)
5712            free_stack(common, 1);
5713        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5714          }
5715      else      else
5716        free_stack(common, 1);        free_stack(common, extrasize);
5717      }      }
5718    else    else
5719      {      {
5720      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5721      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5722      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5723        {        {
5724        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5725        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5726        }        }
5727      else      else
5728        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5729      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);
5730      }      }
5731    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5364  if (opcode == OP_ASSERT || opcode == OP_ Line 5737  if (opcode == OP_ASSERT || opcode == OP_
5737    if (framesize < 0)    if (framesize < 0)
5738      {      {
5739      /* 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. */
5740      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));
5741      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5742      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5743          {
5744        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));
5745          if (extrasize == 2)
5746            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5747          }
5748      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5749        {        {
5750        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5380  if (opcode == OP_ASSERT || opcode == OP_ Line 5757  if (opcode == OP_ASSERT || opcode == OP_
5757        {        {
5758        /* 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. */
5759        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));
5760        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));
5761        }        }
5762      else      else
5763        {        {
5764        /* 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. */
5765        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));
5766        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5767        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5768            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5769            if (bra == OP_BRAMINZERO)
5770              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5771            }
5772          else
5773            {
5774            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5775            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5776            }
5777        }        }
5778      }      }
5779    
5780    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5781      {      {
5782      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5783      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5784      }      }
5785    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5786      {      {
# Line 5416  else Line 5802  else
5802      {      {
5803      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5804      if (bra != OP_BRA)      if (bra != OP_BRA)
5805          {
5806          if (extrasize == 2)
5807            free_stack(common, 1);
5808        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5809          }
5810      else      else
5811        free_stack(common, 1);        free_stack(common, extrasize);
5812      }      }
5813    else    else
5814      {      {
5815      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5816      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5817      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5818      if (bra != OP_BRA)      if (bra != OP_BRA)
5819        {        {
5820        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5821        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5822        }        }
5823      else      else
5824        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5825      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);
5826      }      }
5827    
# Line 5451  else Line 5841  else
5841      }      }
5842    }    }
5843    
5844    common->local_exit = save_local_exit;
5845    common->then_trap = save_then_trap;
5846  common->quit_label = save_quit_label;  common->quit_label = save_quit_label;
5847  common->accept_label = save_accept_label;  common->accept_label = save_accept_label;
5848  common->quit = save_quit;  common->quit = save_quit;
# Line 5568  if (i < name_count) Line 5960  if (i < name_count)
5960  return condition;  return condition;
5961  }  }
5962    
5963    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)
5964    {
5965    DEFINE_COMPILER;
5966    int stacksize;
5967    
5968    if (framesize < 0)
5969      {
5970      if (framesize == no_frame)
5971        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5972      else
5973        {
5974        stacksize = needs_control_head ? 1 : 0;
5975        if (ket != OP_KET || has_alternatives)
5976          stacksize++;
5977        free_stack(common, stacksize);
5978        }
5979    
5980      if (needs_control_head)
5981        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
5982    
5983      /* TMP2 which is set here used by OP_KETRMAX below. */
5984      if (ket == OP_KETRMAX)
5985        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5986      else if (ket == OP_KETRMIN)
5987        {
5988        /* Move the STR_PTR to the private_data_ptr. */
5989        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5990        }
5991      }
5992    else
5993      {
5994      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
5995      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
5996      if (needs_control_head)
5997        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
5998    
5999      if (ket == OP_KETRMAX)
6000        {
6001        /* TMP2 which is set here used by OP_KETRMAX below. */
6002        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6003        }
6004      }
6005    if (needs_control_head)
6006      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
6007    }
6008    
6009    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
6010    {
6011    DEFINE_COMPILER;
6012    
6013    if (common->capture_last_ptr != 0)
6014      {
6015      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6016      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6017      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6018      stacksize++;
6019      }
6020    if (common->optimized_cbracket[offset >> 1] == 0)
6021      {
6022      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6023      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6024      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6025      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6026      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6027      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6028      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6029      stacksize += 2;
6030      }
6031    return stacksize;
6032    }
6033    
6034  /*  /*
6035    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
6036    
# Line 5636  pcre_uchar bra = OP_BRA; Line 6099  pcre_uchar bra = OP_BRA;
6099  pcre_uchar ket;  pcre_uchar ket;
6100  assert_backtrack *assert;  assert_backtrack *assert;
6101  BOOL has_alternatives;  BOOL has_alternatives;
6102    BOOL needs_control_head = FALSE;
6103  struct sljit_jump *jump;  struct sljit_jump *jump;
6104  struct sljit_jump *skip;  struct sljit_jump *skip;
6105  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 5711  else if (opcode == OP_ONCE || opcode == Line 6175  else if (opcode == OP_ONCE || opcode ==
6175    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6176    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6177    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6178      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);
6179    }    }
6180    
6181  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6182  stacksize = 0;  stacksize = 0;
6183  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6184    stacksize++;    stacksize++;
6185  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6186    stacksize++;    stacksize++;
# Line 5725  if (stacksize > 0) Line 6189  if (stacksize > 0)
6189    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6190    
6191  stacksize = 0;  stacksize = 0;
6192  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6193    {    {
6194    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6195    stacksize++;    stacksize++;
# Line 5788  if (ket == OP_KETRMAX) Line 6252  if (ket == OP_KETRMAX)
6252  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6253  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6254    {    {
6255      stacksize = 0;
6256      if (needs_control_head)
6257        {
6258        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6259        stacksize++;
6260        }
6261    
6262    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6263      {      {
6264      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6265      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6266        {        {
6267        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6268        allocate_stack(common, 2);        if (!needs_control_head)
6269        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));  
6270        }        }
6271      else if (ket == OP_KETRMAX || has_alternatives)      else
6272        {        {
6273        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6274        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6275        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6276            stacksize++;
6277        }        }
6278      else  
6279        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6280          allocate_stack(common, stacksize);
6281    
6282        stacksize = 0;
6283        if (needs_control_head)
6284          {
6285          stacksize++;
6286          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6287          }
6288    
6289        if (ket == OP_KETRMIN)
6290          {
6291          if (needs_control_head)
6292            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6293          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6294          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6295            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));
6296          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6297          }
6298        else if (ket == OP_KETRMAX || has_alternatives)
6299          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6300      }      }
6301    else    else
6302      {      {
6303      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6304          stacksize++;
6305    
6306        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6307        allocate_stack(common, stacksize);
6308    
6309        if (needs_control_head)
6310          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6311    
6312        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6313        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6314    
6315        stacksize = needs_control_head ? 1 : 0;
6316        if (ket != OP_KET || has_alternatives)
6317        {        {
6318        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);  
6319        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);
6320        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6321        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6322        }        }
6323      else      else
6324        {        {
       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));  
6325        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);
6326        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);  
6327        }        }
6328        init_frame(common, ccbegin, NULL, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6329      }      }
6330    }    }
6331  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
# Line 5964  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6461  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6461    return NULL;    return NULL;
6462    
6463  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6464    {    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));  
       }  
     }  
   }  
6465    
6466  stacksize = 0;  stacksize = 0;
6467  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
# Line 6016  if (ket != OP_KET || bra != OP_BRA) Line 6490  if (ket != OP_KET || bra != OP_BRA)
6490    }    }
6491    
6492  if (offset != 0)  if (offset != 0)
6493    {    stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
   if (common->capture_last_ptr != 0)  
     {  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);  
     stacksize++;  
     }  
   if (common->optimized_cbracket[offset >> 1] == 0)  
     {  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     stacksize += 2;  
     }  
   }  
6494    
6495  if (has_alternatives)  if (has_alternatives)
6496    {    {
# Line 6106  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6561  if ((ket != OP_KET && bra != OP_BRAMINZE
6561  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6562    cc += GET(cc, 1);    cc += GET(cc, 1);
6563  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6564    
6565    /* Temporarily encoding the needs_control_head in framesize. */
6566    if (opcode == OP_ONCE)
6567      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6568  return cc;  return cc;
6569  }  }
6570    
# Line 6116  backtrack_common *backtrack; Line 6575  backtrack_common *backtrack;
6575  pcre_uchar opcode;  pcre_uchar opcode;
6576  int private_data_ptr;  int private_data_ptr;
6577  int cbraprivptr = 0;  int cbraprivptr = 0;
6578    BOOL needs_control_head;
6579  int framesize;  int framesize;
6580  int stacksize;  int stacksize;
6581  int offset = 0;  int offset = 0;
6582  BOOL zero = FALSE;  BOOL zero = FALSE;
6583  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6584  int stack;  int stack; /* Also contains the offset of control head. */
6585  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6586  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6587    
# Line 6159  switch(opcode) Line 6619  switch(opcode)
6619    break;    break;
6620    }    }
6621    
6622  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
6623  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6624  if (framesize < 0)  if (framesize < 0)
6625    {    {
6626    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    if (offset != 0)
6627        {
6628        stacksize = 2;
6629        if (common->capture_last_ptr != 0)
6630          stacksize++;
6631        }
6632      else
6633        stacksize = 1;
6634    
6635      if (needs_control_head)
6636        stacksize++;
6637    if (!zero)    if (!zero)
6638      stacksize++;      stacksize++;
6639    
6640    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6641    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6642    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    if (framesize == no_frame)
6643        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6644    
6645    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    stack = 0;
6646      if (offset != 0)
6647      {      {
6648        stack = 2;
6649      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6650      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));
6651      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6652        if (common->capture_last_ptr != 0)
6653          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6654      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6655        if (needs_control_head)
6656          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6657        if (common->capture_last_ptr != 0)
6658          {
6659          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6660          stack = 3;
6661          }
6662      }      }
6663    else    else
6664        {
6665        if (needs_control_head)
6666          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6667      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6668        stack = 1;
6669        }
6670    
6671      if (needs_control_head)
6672        stack++;
6673    if (!zero)    if (!zero)
6674      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);
6675      if (needs_control_head)
6676        {
6677        stack--;
6678        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6679        }
6680    }    }
6681  else  else
6682    {    {
6683    stacksize = framesize + 1;    stacksize = framesize + 1;
6684    if (!zero)    if (!zero)
6685      stacksize++;      stacksize++;
6686    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6687        stacksize++;
6688      if (offset == 0)
6689      stacksize++;      stacksize++;
6690    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
   allocate_stack(common, stacksize);  
6691    
6692      allocate_stack(common, stacksize);
6693    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);
6694    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6695    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);
6696      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6697    
6698    stack = 0;    stack = 0;
6699    if (!zero)    if (!zero)
6700      {      {
6701      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6702        stack = 1;
6703        }
6704      if (needs_control_head)
6705        {
6706        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6707      stack++;      stack++;
6708      }      }
6709    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6710      {      {
6711      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6712      stack++;      stack++;
6713      }      }
6714    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6715    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, NULL, stacksize - 1, stacksize - framesize, FALSE);
6716      stack -= 1 + (offset == 0);
6717    }    }
6718    
6719  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)  if (offset != 0)
6720    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6721    
6722  loop = LABEL();  loop = LABEL();
# Line 6227  while (*cc != OP_KETRPOS) Line 6732  while (*cc != OP_KETRPOS)
6732    
6733    if (framesize < 0)    if (framesize < 0)
6734      {      {
6735      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      if (framesize == no_frame)
6736          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6737    
6738      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6739        {        {
6740        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6741        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);
6742        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6743          if (common->capture_last_ptr != 0)
6744            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6745        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6746        }        }
6747      else      else
# Line 6251  while (*cc != OP_KETRPOS) Line 6759  while (*cc != OP_KETRPOS)
6759      }      }
6760    else    else
6761      {      {
6762      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6763        {        {
6764        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));
6765        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6766        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);
6767        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6768          if (common->capture_last_ptr != 0)
6769            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6770        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6771        }        }
6772      else      else
# Line 6279  while (*cc != OP_KETRPOS) Line 6789  while (*cc != OP_KETRPOS)
6789          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6790        }        }
6791      }      }
6792    
6793      if (needs_control_head)
6794        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6795    
6796    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6797    flush_stubs(common);    flush_stubs(common);
6798    
# Line 6289  while (*cc != OP_KETRPOS) Line 6803  while (*cc != OP_KETRPOS)
6803    
6804    if (framesize < 0)    if (framesize < 0)
6805      {      {
6806      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6807        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6808      else      else
6809        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6810      }      }
6811    else    else
6812      {      {
6813      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6814        {        {
6815        /* Last alternative. */        /* Last alternative. */
6816        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
# Line 6315  while (*cc != OP_KETRPOS) Line 6829  while (*cc != OP_KETRPOS)
6829    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6830    }    }
6831    
6832    /* We don't have to restore the control head in case of a failed match. */
6833    
6834  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6835  if (!zero)  if (!zero)
6836    {    {
# Line 6443  PUSH_BACKTRACK(sizeof(iterator_backtrack Line 6959  PUSH_BACKTRACK(sizeof(iterator_backtrack
6959    
6960  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6961    
6962  switch (type)  switch(type)
6963    {    {
6964    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
6965    case OP_DIGIT:    case OP_DIGIT:
# Line 6703  if (!optimized_cbracket) Line 7219  if (!optimized_cbracket)
7219  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
7220  }  }
7221    
7222    static SLJIT_INLINE pcre_uchar *compile_control_verb_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
7223    {
7224    DEFINE_COMPILER;
7225    backtrack_common *backtrack;
7226    pcre_uchar opcode = *cc;
7227    pcre_uchar *ccend = cc + 1;
7228    
7229    if (opcode == OP_PRUNE_ARG || opcode == OP_SKIP_ARG || opcode == OP_THEN_ARG)
7230      ccend += 2 + cc[1];
7231    
7232    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7233    
7234    if (opcode == OP_SKIP)
7235      {
7236      allocate_stack(common, 1);
7237      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
7238      return ccend;
7239      }
7240    
7241    if (opcode == OP_PRUNE_ARG || opcode == OP_THEN_ARG)
7242      {
7243      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7244      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7245      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7246      OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7247      }
7248    
7249    return ccend;
7250    }
7251    
7252    static pcre_uchar then_trap_opcode[1] = { OP_THEN_TRAP };
7253    
7254    static SLJIT_INLINE void compile_then_trap_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, backtrack_common *parent)
7255    {
7256    DEFINE_COMPILER;
7257    backtrack_common *backtrack;
7258    BOOL needs_control_head;
7259    int size;
7260    
7261    PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7262    common->then_trap = BACKTRACK_AS(then_trap_backtrack);
7263    BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7264    BACKTRACK_AS(then_trap_backtrack)->start = (sljit_sw)(cc - common->start);
7265    BACKTRACK_AS(then_trap_backtrack)->framesize = get_framesize(common, cc, ccend, FALSE, &needs_control_head);
7266    
7267    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7268    size = 3 + (size < 0 ? 0 : size);
7269    
7270    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7271    allocate_stack(common, size);
7272    if (size > 3)
7273      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0, SLJIT_IMM, (size - 3) * sizeof(sljit_sw));
7274    else
7275      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7276    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 1), SLJIT_IMM, BACKTRACK_AS(then_trap_backtrack)->start);
7277    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 2), SLJIT_IMM, type_then_trap);
7278    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(size - 3), TMP2, 0);
7279    
7280    size = BACKTRACK_AS(then_trap_backtrack)->framesize;
7281    if (size >= 0)
7282      init_frame(common, cc, ccend, size - 1, 0, FALSE);
7283    }
7284    
7285  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)
7286  {  {
7287  DEFINE_COMPILER;  DEFINE_COMPILER;
7288  backtrack_common *backtrack;  backtrack_common *backtrack;
7289    BOOL has_then_trap = FALSE;
7290    then_trap_backtrack *save_then_trap = NULL;
7291    
7292    SLJIT_ASSERT(*ccend == OP_END || (*ccend >= OP_ALT && *ccend <= OP_KETRPOS));
7293    
7294    if (common->has_then && common->then_offsets[cc - common->start] != 0)
7295      {
7296      SLJIT_ASSERT(*ccend != OP_END && common->control_head_ptr != 0);
7297      has_then_trap = TRUE;
7298      save_then_trap = common->then_trap;
7299      /* Tail item on backtrack. */
7300      compile_then_trap_matchingpath(common, cc, ccend, parent);
7301      }
7302    
7303  while (cc < ccend)  while (cc < ccend)
7304    {    {
# Line 6923  while (cc < ccend) Line 7515  while (cc < ccend)
7515      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7516      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7517      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);
7518      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7519      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7520      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);
7521      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7522      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);
7523      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);
7524        if (common->has_skip_arg)
7525          {
7526          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7527          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7528          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7529          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7530          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7531          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7532          }
7533      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7534      break;      break;
7535    
7536        case OP_PRUNE:
7537        case OP_PRUNE_ARG:
7538        case OP_SKIP:
7539        case OP_SKIP_ARG:
7540        case OP_THEN:
7541        case OP_THEN_ARG:
7542      case OP_COMMIT:      case OP_COMMIT:
7543      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      cc = compile_control_verb_matchingpath(common, cc, parent);
     cc += 1;  
7544      break;      break;
7545    
7546      case OP_FAIL:      case OP_FAIL:
# Line 6958  while (cc < ccend) Line 7564  while (cc < ccend)
7564    if (cc == NULL)    if (cc == NULL)
7565      return;      return;
7566    }    }
7567    
7568    if (has_then_trap)
7569      {
7570      /* Head item on backtrack. */
7571      PUSH_BACKTRACK_NOVALUE(sizeof(then_trap_backtrack), cc);
7572      BACKTRACK_AS(then_trap_backtrack)->common.cc = then_trap_opcode;
7573      BACKTRACK_AS(then_trap_backtrack)->then_trap = common->then_trap;
7574      common->then_trap = save_then_trap;
7575      }
7576  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
7577  }  }
7578    
# Line 7119  switch(opcode) Line 7734  switch(opcode)
7734    }    }
7735  }  }
7736    
7737  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)
7738  {  {
7739  DEFINE_COMPILER;  DEFINE_COMPILER;
7740  pcre_uchar *cc = current->cc;  pcre_uchar *cc = current->cc;
# Line 7141  set_jumps(current->topbacktracks, LABEL( Line 7756  set_jumps(current->topbacktracks, LABEL(
7756  free_stack(common, 2);  free_stack(common, 2);
7757  }  }
7758    
7759  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)
7760  {  {
7761  DEFINE_COMPILER;  DEFINE_COMPILER;
7762    
7763    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7764      compile_backtrackingpath(common, current->top);
7765  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
7766    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7767      return;
7768    
7769  if (common->has_set_som && common->mark_ptr != 0)  if (common->has_set_som && common->mark_ptr != 0)
7770    {    {
# Line 7247  pcre_uchar bra = OP_BRA; Line 7866  pcre_uchar bra = OP_BRA;
7866  pcre_uchar ket;  pcre_uchar ket;
7867  assert_backtrack *assert;  assert_backtrack *assert;
7868  BOOL has_alternatives;  BOOL has_alternatives;
7869    BOOL needs_control_head = FALSE;
7870  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7871  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7872  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7272  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7892  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7892  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7893    opcode = OP_ONCE;    opcode = OP_ONCE;
7894    
7895    /* Decoding the needs_control_head in framesize. */
7896    if (opcode == OP_ONCE)
7897      {
7898      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7899      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7900      }
7901    
7902  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7903    {    {
7904    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7315  if (offset != 0) Line 7942  if (offset != 0)
7942    {    {
7943    if (common->capture_last_ptr != 0)    if (common->capture_last_ptr != 0)
7944      {      {
7945        SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
7946      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7947      free_stack(common, 1);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7948      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7949        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7950        free_stack(common, 3);
7951        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
7952        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
7953      }      }
7954    if (common->optimized_cbracket[offset >> 1] == 0)    else if (common->optimized_cbracket[offset >> 1] == 0)
7955      {      {
7956      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7957      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
# Line 7424  if (has_alternatives) Line 8056  if (has_alternatives)
8056      current->top = NULL;      current->top = NULL;
8057      current->topbacktracks = NULL;      current->topbacktracks = NULL;
8058      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
8059        /* Conditional blocks always have an additional alternative, even if it is empty. */
8060      if (*cc == OP_ALT)      if (*cc == OP_ALT)
8061        {        {
8062        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
8063        cc += GET(cc, 1);        cc += GET(cc, 1);
8064        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
8065          {          {
8066          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
8067            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
8068              if (private_data_ptr != 0)
8069                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
8070              else
8071                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8072              }
8073          else          else
8074            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));
8075          }          }
8076        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
8077        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7443  if (has_alternatives) Line 8081  if (has_alternatives)
8081      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
8082      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
8083      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
8084        {        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));  
           }  
         }  
       }  
8085    
8086      stacksize = 0;      stacksize = 0;
8087      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7480  if (has_alternatives) Line 8096  if (has_alternatives)
8096      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8097        stacksize++;        stacksize++;
8098    
8099      if (stacksize > 0) {      if (stacksize > 0)
8100          {
8101        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8102          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
8103        else        else
# Line 7489  if (has_alternatives) Line 8106  if (has_alternatives)
8106          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
8107          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));
8108          }          }
8109      }        }
8110    
8111      stacksize = 0;      stacksize = 0;
8112      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7502  if (has_alternatives) Line 8119  if (has_alternatives)
8119        }        }
8120    
8121      if (offset != 0)      if (offset != 0)
8122        {        stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
       if (common->capture_last_ptr != 0)  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);  
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
         stacksize++;  
         }  
       if (common->optimized_cbracket[offset >> 1] == 0)  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
         OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
         stacksize += 2;  
         }  
       }  
8123    
8124      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8125        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
# Line 7555  if (has_alternatives) Line 8153  if (has_alternatives)
8153      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8154      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8155      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)
   
8156        {        {
8157        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);
8158        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7595  else if (opcode == OP_SBRA || opcode == Line 8192  else if (opcode == OP_SBRA || opcode ==
8192  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8193    {    {
8194    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8195      stacksize = needs_control_head ? 1 : 0;
8196    
8197    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8198      {      {
8199      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8200      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);  
8201      }      }
8202    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8203      {      {
8204      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8205      free_stack(common, 1);      stacksize++;
8206      }      }
8207      free_stack(common, stacksize);
8208    
8209    JUMPHERE(once);    JUMPHERE(once);
8210    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7657  else if (bra == OP_BRAZERO) Line 8256  else if (bra == OP_BRAZERO)
8256    }    }
8257  }  }
8258    
8259  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)
8260  {  {
8261  DEFINE_COMPILER;  DEFINE_COMPILER;
8262  int offset;  int offset;
# Line 7671  if (CURRENT_AS(bracketpos_backtrack)->fr Line 8270  if (CURRENT_AS(bracketpos_backtrack)->fr
8270      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8271      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8272      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
8273        if (common->capture_last_ptr != 0)
8274          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
8275      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);
8276        if (common->capture_last_ptr != 0)
8277          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
8278      }      }
8279    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8280    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
# Line 7692  if (current->topbacktracks) Line 8295  if (current->topbacktracks)
8295  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));
8296  }  }
8297    
8298  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)
8299  {  {
8300  assert_backtrack backtrack;  assert_backtrack backtrack;
8301    
# Line 7716  else Line 8319  else
8319  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);  SLJIT_ASSERT(!current->nextbacktracks && !current->topbacktracks);
8320  }  }
8321    
8322    static SLJIT_INLINE void compile_control_verb_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8323    {
8324    DEFINE_COMPILER;
8325    pcre_uchar opcode = *current->cc;
8326    struct sljit_label *loop;
8327    struct sljit_jump *jump;
8328    
8329    if ((opcode == OP_THEN || opcode == OP_THEN_ARG) && common->then_trap != NULL)
8330      {
8331      SLJIT_ASSERT(common->control_head_ptr != 0);
8332    
8333      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8334      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, type_then_trap);
8335      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, common->then_trap->start);
8336      jump = JUMP(SLJIT_JUMP);
8337    
8338      loop = LABEL();
8339      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), -(int)sizeof(sljit_sw));
8340      JUMPHERE(jump);
8341      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(2 * sizeof(sljit_sw)), TMP1, 0, loop);
8342      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), -(int)(3 * sizeof(sljit_sw)), TMP2, 0, loop);
8343      add_jump(compiler, &common->then_trap->quit, JUMP(SLJIT_JUMP));
8344      return;
8345      }
8346    
8347    if (common->local_exit)
8348      {
8349      if (common->quit_label == NULL)
8350        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8351      else
8352        JUMPTO(SLJIT_JUMP, common->quit_label);
8353      return;
8354      }
8355    
8356    if (opcode == OP_SKIP_ARG)
8357      {
8358      SLJIT_ASSERT(common->control_head_ptr != 0);
8359      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8360      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8361      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, (sljit_sw)(current->cc + 2));
8362      sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_search_mark));
8363      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8364    
8365      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8366      add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8367      return;
8368      }
8369    
8370    if (opcode == OP_SKIP)
8371      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8372    else
8373      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, 0);
8374    add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8375    }
8376    
8377    static SLJIT_INLINE void compile_then_trap_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8378    {
8379    DEFINE_COMPILER;
8380    struct sljit_jump *jump;
8381    int size;
8382    
8383    if (CURRENT_AS(then_trap_backtrack)->then_trap)
8384      {
8385      common->then_trap = CURRENT_AS(then_trap_backtrack)->then_trap;
8386      return;
8387      }
8388    
8389    size = CURRENT_AS(then_trap_backtrack)->framesize;
8390    size = 3 + (size < 0 ? 0 : size);
8391    
8392    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(size - 3));
8393    free_stack(common, size);
8394    jump = JUMP(SLJIT_JUMP);
8395    
8396    set_jumps(CURRENT_AS(then_trap_backtrack)->quit, LABEL());
8397    /* STACK_TOP is set by THEN. */
8398    if (CURRENT_AS(then_trap_backtrack)->framesize >= 0)
8399      add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8400    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8401    free_stack(common, 3);
8402    
8403    JUMPHERE(jump);
8404    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8405    }
8406    
8407  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)  static void compile_backtrackingpath(compiler_common *common, struct backtrack_common *current)
8408  {  {
8409  DEFINE_COMPILER;  DEFINE_COMPILER;
8410    then_trap_backtrack *save_then_trap = common->then_trap;
8411    
8412  while (current)  while (current)
8413    {    {
# Line 7852  while (current) Line 8541  while (current)
8541      break;      break;
8542    
8543      case OP_MARK:      case OP_MARK:
8544      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));
8545      free_stack(common, 1);      if (common->has_skip_arg)
8546          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8547        free_stack(common, common->has_skip_arg ? 5 : 1);
8548      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);
8549        if (common->has_skip_arg)
8550          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8551        break;
8552    
8553        case OP_THEN:
8554        case OP_THEN_ARG:
8555        case OP_PRUNE:
8556        case OP_PRUNE_ARG:
8557        case OP_SKIP:
8558        case OP_SKIP_ARG:
8559        compile_control_verb_backtrackingpath(common, current);
8560      break;      break;
8561    
8562      case OP_COMMIT:      case OP_COMMIT:
8563      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8564          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8565      if (common->quit_label == NULL)      if (common->quit_label == NULL)
8566        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8567      else      else
# Line 7872  while (current) Line 8575  while (current)
8575      set_jumps(current->topbacktracks, LABEL());      set_jumps(current->topbacktracks, LABEL());
8576      break;      break;
8577    
8578        case OP_THEN_TRAP:
8579        /* A virtual opcode for then traps. */
8580        compile_then_trap_backtrackingpath(common, current);
8581        break;
8582    
8583      default:      default:
8584      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
8585      break;      break;
8586      }      }
8587    current = current->prev;    current = current->prev;
8588    }    }
8589    common->then_trap = save_then_trap;
8590  }  }
8591    
8592  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
# Line 7886  DEFINE_COMPILER; Line 8595  DEFINE_COMPILER;
8595  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8596  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);
8597  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8598  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8599  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, NULL, TRUE, &needs_control_head);
8600    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8601  int alternativesize;  int alternativesize;
8602  BOOL needsframe;  BOOL needs_frame;
8603  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quit_label = common->quit_label;  
 jump_list *save_quit = common->quit;  
8604  struct sljit_jump *jump;  struct sljit_jump *jump;
8605    
8606    /* Recurse captures then. */
8607    common->then_trap = NULL;
8608    
8609  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);
8610  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8611  if (!needsframe)  if (!needs_frame)
8612    framesize = 0;    framesize = 0;
8613  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8614    
# Line 7908  set_jumps(common->currententry->calls, c Line 8619  set_jumps(common->currententry->calls, c
8619  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8620  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8621  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);
8622  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);
8623    if (needs_control_head)
8624      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8625  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8626  if (needsframe)  if (needs_frame)
8627    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, NULL, framesize + alternativesize - 1, alternativesize, TRUE);
8628    
8629  if (alternativesize > 0)  if (alternativesize > 0)
8630    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 7933  while (1) Line 8646  while (1)
8646    
8647    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8648    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quit_label = save_quit_label;  
     common->quit = save_quit;  
8649      return;      return;
     }  
8650    
8651    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8652    
8653    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8654    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quit_label = save_quit_label;  
     common->quit = save_quit;  
8655      return;      return;
     }  
8656    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8657    
8658    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 7956  while (1) Line 8661  while (1)
8661    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8662    cc += GET(cc, 1);    cc += GET(cc, 1);
8663    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8664    
8665    /* None of them matched. */
8666  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8667  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8668    
8669    if (common->quit != NULL)
8670      {
8671      set_jumps(common->quit, LABEL());
8672      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8673      if (needs_frame)
8674        {
8675        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8676        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8677        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8678        }
8679      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8680      common->quit = NULL;
8681      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8682      }
8683    
8684  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8685  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8686  if (needsframe)  if (needs_frame)
8687    {    {
8688    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));
8689    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7974  if (needsframe) Line 8692  if (needsframe)
8692  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8693    
8694  JUMPHERE(jump);  JUMPHERE(jump);
8695  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8696      set_jumps(common->quit, LABEL());
8697    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8698  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8699  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8700  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8701  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8702      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8703      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8704      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8705      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8706      }
8707    else
8708      {
8709      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8710      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8711      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8712      }
8713  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
   
 common->quit_label = save_quit_label;  
 common->quit = save_quit;  
8714  }  }
8715    
8716  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 8002  pcre_uchar *ccend; Line 8730  pcre_uchar *ccend;
8730  executable_functions *functions;  executable_functions *functions;
8731  void *executable_func;  void *executable_func;
8732  sljit_uw executable_size;  sljit_uw executable_size;
8733  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8734  struct sljit_label *empty_match_found;  struct sljit_label *continue_match_label;
8735  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_found_label;
8736    struct sljit_label *empty_match_backtrack_label;
8737    struct sljit_label *reset_match_label;
8738  struct sljit_jump *jump;  struct sljit_jump *jump;
8739  struct sljit_jump *minlength_check_failed = NULL;  struct sljit_jump *minlength_check_failed = NULL;
8740  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8741  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8742    struct sljit_label *quit_label;
8743    
8744  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8745  study = extra->study_data;  study = extra->study_data;
# Line 8077  common->ovector_start = CALL_LIMIT + siz Line 8808  common->ovector_start = CALL_LIMIT + siz
8808  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8809  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8810    return;    return;
8811    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
8812    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8813    #else
8814  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
8815    #endif
8816    
8817  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
8818    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
8819    common->capture_last_ptr = common->ovector_start;
8820    common->ovector_start += sizeof(sljit_sw);
8821    #endif
8822  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
8823  if (private_data_size < 0)  if (private_data_size < 0)
8824    {    {
# Line 8100  if (mode != JIT_COMPILE) Line 8839  if (mode != JIT_COMPILE)
8839    if (mode == JIT_PARTIAL_SOFT_COMPILE)    if (mode == JIT_PARTIAL_SOFT_COMPILE)
8840      {      {
8841      common->hit_start = common->ovector_start;      common->hit_start = common->ovector_start;
8842      common->ovector_start += sizeof(sljit_sw);      common->ovector_start += 2 * sizeof(sljit_sw);
8843        }
8844      else
8845        {
8846        SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
8847        common->needs_start_ptr = TRUE;
8848      }      }
8849    }    }
8850  if ((re->options & PCRE_FIRSTLINE) != 0)  if ((re->options & PCRE_FIRSTLINE) != 0)
# Line 8108  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8852  if ((re->options & PCRE_FIRSTLINE) != 0)
8852    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
8853    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8854    }    }
8855    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
8856    common->control_head_ptr = 1;
8857    #endif
8858    if (common->control_head_ptr != 0)
8859      {
8860      common->control_head_ptr = common->ovector_start;
8861      common->ovector_start += sizeof(sljit_sw);
8862      }
8863    if (common->needs_start_ptr && common->has_set_som)
8864      {
8865      /* Saving the real start pointer is necessary. */
8866      common->start_ptr = common->ovector_start;
8867      common->ovector_start += sizeof(sljit_sw);
8868      }
8869    else
8870      common->needs_start_ptr = FALSE;
8871    
8872  /* Aligning ovector to even number of sljit words. */  /* Aligning ovector to even number of sljit words. */
8873  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8874    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8875    
8876    if (common->start_ptr == 0)
8877      common->start_ptr = OVECTOR(0);
8878    
8879  /* Capturing brackets cannot be optimized if callouts are allowed. */  /* Capturing brackets cannot be optimized if callouts are allowed. */
8880  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8881    memset(common->optimized_cbracket, 0, re->top_bracket + 1);    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8882    
8883  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8884  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);
8885  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);
8886  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
8887    {    {
8888    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8889    return;    return;
8890    }    }
8891    
8892  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));  common->private_data_ptrs = (int *)SLJIT_MALLOC((ccend - rootbacktrack.cc) * sizeof(int));
8893  if (!common->private_data_ptrs)  if (!common->private_data_ptrs)
8894    {    {
# Line 8132  if (!common->private_data_ptrs) Line 8896  if (!common->private_data_ptrs)
8896    return;    return;
8897    }    }
8898  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8899  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);
8900    
8901    if (common->has_then)
8902      {
8903      common->then_offsets = (pcre_uint8 *)SLJIT_MALLOC(ccend - rootbacktrack.cc);
8904      if (!common->then_offsets)
8905        {
8906        SLJIT_FREE(common->optimized_cbracket);
8907        SLJIT_FREE(common->private_data_ptrs);
8908        return;
8909        }
8910      memset(common->then_offsets, 0, ccend - rootbacktrack.cc);
8911      set_then_offsets(common, rootbacktrack.cc, NULL);
8912      }
8913    
8914  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
8915  if (!compiler)  if (!compiler)
8916    {    {
8917    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
8918    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
8919      if (common->has_then)
8920        SLJIT_FREE(common->then_offsets);
8921    return;    return;
8922    }    }
8923  common->compiler = compiler;  common->compiler = compiler;
# Line 8162  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM Line 8941  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM
8941  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
8942    
8943  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8944    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
8945    if (common->mark_ptr != 0)
8946      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
8947    if (common->control_head_ptr != 0)
8948      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8949    
8950  /* Main part of the matching */  /* Main part of the matching */
8951  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
8952    {    {
8953    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop_label = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
8954      continue_match_label = LABEL();
8955    /* Forward search if possible. */    /* Forward search if possible. */
8956    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)    if ((re->options & PCRE_NO_START_OPTIMIZE) == 0)
8957      {      {
# Line 8181  if ((re->options & PCRE_ANCHORED) == 0) Line 8965  if ((re->options & PCRE_ANCHORED) == 0)
8965        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
8966      }      }
8967    }    }
8968    else
8969      continue_match_label = LABEL();
8970    
8971  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
8972    {    {
8973    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
# Line 8194  if (common->req_char_ptr != 0) Line 8981  if (common->req_char_ptr != 0)
8981  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
8982  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
8983  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
 if (common->mark_ptr != 0)  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);  
8984  if (common->capture_last_ptr != 0)  if (common->capture_last_ptr != 0)
8985    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
8986    
8987    if (common->needs_start_ptr)
8988      {
8989      SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
8990      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
8991      }
8992    else
8993      SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
8994    
8995  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
8996  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8997    {    {
8998    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
8999    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
9000      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
9001    JUMPHERE(jump);    JUMPHERE(jump);
9002    }    }
9003  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
# Line 8214  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 9009  if (SLJIT_UNLIKELY(sljit_get_compiler_er
9009    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9010    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9011    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9012      if (common->has_then)
9013        SLJIT_FREE(common->then_offsets);
9014    return;    return;
9015    }    }
9016    
9017  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
9018  empty_match_found = LABEL();  empty_match_found_label = LABEL();
9019    
9020  common->accept_label = LABEL();  common->accept_label = LABEL();
9021  if (common->accept != NULL)  if (common->accept != NULL)
# Line 8232  if (common->quit != NULL) Line 9029  if (common->quit != NULL)
9029  if (common->forced_quit != NULL)  if (common->forced_quit != NULL)
9030    set_jumps(common->forced_quit, common->forced_quit_label);    set_jumps(common->forced_quit, common->forced_quit_label);
9031  if (minlength_check_failed != NULL)  if (minlength_check_failed != NULL)
9032    sljit_set_label(minlength_check_failed, common->forced_quit_label);    SET_LABEL(minlength_check_failed, common->forced_quit_label);
9033  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
9034    
9035  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
# Line 8242  if (mode != JIT_COMPILE) Line 9039  if (mode != JIT_COMPILE)
9039    return_with_partial_match(common, common->quit_label);    return_with_partial_match(common, common->quit_label);
9040    }    }
9041    
9042  empty_match_backtrack = LABEL();  empty_match_backtrack_label = LABEL();
9043  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
9044  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
9045    {    {
9046    sljit_free_compiler(compiler);    sljit_free_compiler(compiler);
9047    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
9048    SLJIT_FREE(common->private_data_ptrs);    SLJIT_FREE(common->private_data_ptrs);
9049      if (common->has_then)
9050        SLJIT_FREE(common->then_offsets);
9051    return;    return;
9052    }    }
9053    
9054  SLJIT_ASSERT(rootbacktrack.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
9055    reset_match_label = LABEL();
9056    
9057  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9058    {    {
9059    /* Update hit_start only in the first time. */    /* Update hit_start only in the first time. */
9060    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
9061    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
9062    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
9063    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
# Line 8265  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 9065  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9065    }    }
9066    
9067  /* Check we have remaining characters. */  /* Check we have remaining characters. */
9068  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
9069      {
9070      SLJIT_ASSERT(common->first_line_end != 0);
9071      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
9072      }
9073    
9074    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
9075    
9076  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
9077    {    {
9078    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
9079      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop_label);
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);  
     }  
9080    else    else
9081      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop_label);
     SLJIT_ASSERT(common->first_line_end != 0);  
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);  
       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);  
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);  
       JUMPTO(SLJIT_C_ZERO, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);  
     }  
9082    }    }
9083    
9084  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8301  if (reqbyte_notfound != NULL) Line 9086  if (reqbyte_notfound != NULL)
9086    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
9087    
9088  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
9089    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
9090    
9091  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
9092  JUMPTO(SLJIT_JUMP, common->quit_label);  JUMPTO(SLJIT_JUMP, common->quit_label);
# Line 8311  flush_stubs(common); Line 9096  flush_stubs(common);
9096  JUMPHERE(empty_match);  JUMPHERE(empty_match);
9097  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
9098  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));
9099  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
9100  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));
9101  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
9102  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));
9103  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
9104  JUMPTO(SLJIT_JUMP, empty_match_backtrack);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
9105    
9106  common->currententry = common->entries;  common->currententry = common->entries;
9107    common->local_exit = TRUE;
9108    quit_label = common->quit_label;
9109  while (common->currententry != NULL)  while (common->currententry != NULL)
9110    {    {
9111    /* Might add new entries. */    /* Might add new entries. */
# Line 8328  while (common->currententry != NULL) Line 9115  while (common->currententry != NULL)
9115      sljit_free_compiler(compiler);      sljit_free_compiler(compiler);
9116      SLJIT_FREE(common->optimized_cbracket);      SLJIT_FREE(common->optimized_cbracket);
9117      SLJIT_FREE(common->private_data_ptrs);      SLJIT_FREE(common->private_data_ptrs);
9118        if (common->has_then)
9119          SLJIT_FREE(common->then_offsets);
9120      return;      return;
9121      }      }
9122    flush_stubs(common);    flush_stubs(common);
9123    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
9124    }    }
9125    common->local_exit = FALSE;
9126    common->quit_label = quit_label;
9127    
9128  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
9129  /* This is a (really) rare case. */  /* This is a (really) rare case. */
# Line 8400  if (common->caselesscmp != NULL) Line 9191  if (common->caselesscmp != NULL)
9191    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
9192    do_caselesscmp(common);    do_caselesscmp(common);
9193    }    }
9194    if (common->reset_match != NULL)
9195      {
9196      set_jumps(common->reset_match, LABEL());
9197      do_reset_match(common, (re->top_bracket + 1) * 2);
9198      CMPTO(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0, continue_match_label);
9199      OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
9200      JUMPTO(SLJIT_JUMP, reset_match_label);
9201      }
9202  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
9203  #ifndef COMPILE_PCRE32  #ifndef COMPILE_PCRE32
9204  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
# Line 8426  if (common->getucd != NULL) Line 9225  if (common->getucd != NULL)
9225    
9226  SLJIT_FREE(common->optimized_cbracket);  SLJIT_FREE(common->optimized_cbracket);
9227  SLJIT_FREE(common->private_data_ptrs);  SLJIT_FREE(common->private_data_ptrs);
9228    if (common->has_then)
9229      SLJIT_FREE(common->then_offsets);
9230    
9231  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
9232  executable_size = sljit_get_generated_code_size(compiler);  executable_size = sljit_get_generated_code_size(compiler);
9233  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
# Line 8517  arguments.notempty = (options & PCRE_NOT Line 9319  arguments.notempty = (options & PCRE_NOT
9319  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
9320  arguments.offsets = offsets;  arguments.offsets = offsets;
9321  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
9322    arguments.real_offset_count = offset_count;
9323    
9324  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
9325  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
# Line 8607  arguments.notempty = (options & PCRE_NOT Line 9410  arguments.notempty = (options & PCRE_NOT
9410  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
9411  arguments.offsets = offsets;  arguments.offsets = offsets;
9412  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;  arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
9413    arguments.real_offset_count = offset_count;
9414    
9415  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
9416  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as

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

  ViewVC Help
Powered by ViewVC 1.1.5