/[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 1195 by zherczeg, Thu Nov 1 15:21:27 2012 UTC revision 1278 by zherczeg, Tue Mar 12 06:15:04 2013 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2012 University of Cambridge             Copyright (c) 1997-2013 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2012                        Copyright (c) 2010-2013
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68    /* Defines for debugging purposes. */
69    
70    /* 1 - Use unoptimized capturing brackets.
71       2 - Enable capture_last_ptr (includes option 1). */
72    /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
78  Fast, but limited size. */  Fast, but limited size. */
79  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 157  typedef struct jit_arguments { Line 166  typedef struct jit_arguments {
166    int *offsets;    int *offsets;
167    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169      void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171    int offsetcount;    int real_offset_count;
172    int calllimit;    int offset_count;
173      int call_limit;
174    pcre_uint8 notbol;    pcre_uint8 notbol;
175    pcre_uint8 noteol;    pcre_uint8 noteol;
176    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 179  typedef struct jump_list { Line 190  typedef struct jump_list {
190    struct jump_list *next;    struct jump_list *next;
191  } jump_list;  } jump_list;
192    
 enum stub_types { stack_alloc };  
   
193  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   int data;  
194    struct sljit_jump *start;    struct sljit_jump *start;
195    struct sljit_label *quit;    struct sljit_label *quit;
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199    enum frame_types {
200      no_frame = -1,
201      no_stack = -2
202    };
203    
204    enum control_types {
205      type_commit = 0,
206      type_prune = 1,
207      type_skip = 2,
208      type_skip_arg = 3,
209      type_mark = 4
210    };
211    
212  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
213    
214  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
# Line 209  typedef struct backtrack_common { Line 229  typedef struct backtrack_common {
229  typedef struct assert_backtrack {  typedef struct assert_backtrack {
230    backtrack_common common;    backtrack_common common;
231    jump_list *condfailed;    jump_list *condfailed;
232    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
233    int framesize;    int framesize;
234    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
235    int private_data_ptr;    int private_data_ptr;
# Line 230  typedef struct bracket_backtrack { Line 250  typedef struct bracket_backtrack {
250      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
251      jump_list *condfailed;      jump_list *condfailed;
252      assert_backtrack *assert;      assert_backtrack *assert;
253      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
254      int framesize;      int framesize;
255    } u;    } u;
256    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 270  typedef struct recurse_entry { Line 290  typedef struct recurse_entry {
290    
291  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
292    backtrack_common common;    backtrack_common common;
293      BOOL inlined_pattern;
294  } recurse_backtrack;  } recurse_backtrack;
295    
296  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
297    
298  typedef struct compiler_common {  typedef struct compiler_common {
299      /* The sljit ceneric compiler. */
300    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
301      /* First byte code. */
302    pcre_uchar *start;    pcre_uchar *start;
   
303    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
304    int *private_data_ptrs;    int *private_data_ptrs;
305    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
306    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
307    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
308    int cbraptr;    int cbra_ptr;
309    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
310    int ovector_start;    int ovector_start;
311    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
312    int req_char_ptr;    int req_char_ptr;
313    /* Head of the last recursion. */    /* Head of the last recursion. */
314    int recursive_head;    int recursive_head_ptr;
315    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
316    int start_used_ptr;    int start_used_ptr;
317    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 298  typedef struct compiler_common { Line 320  typedef struct compiler_common {
320    int first_line_end;    int first_line_end;
321    /* Points to the marked string. */    /* Points to the marked string. */
322    int mark_ptr;    int mark_ptr;
323      /* Recursive control verb management chain. */
324      int control_head_ptr;
325      /* Points to the last matched capture block index. */
326      int capture_last_ptr;
327      /* Points to the starting position of the current match. */
328      int start_ptr;
329    
330    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
331    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
332    sljit_sw lcc;    sljit_sw lcc;
333    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
334    int mode;    int mode;
335      /* \K is in the pattern. */
336      BOOL has_set_som;
337      /* (*SKIP:arg) is in the pattern. */
338      BOOL has_skip_arg;
339      /* Needs to know the start position anytime. */
340      BOOL needs_start_ptr;
341      /* Currently in recurse or assert. */
342      BOOL local_exit;
343    /* Newline control. */    /* Newline control. */
344    int nltype;    int nltype;
345    int newline;    int newline;
346    int bsr_nltype;    int bsr_nltype;
347    /* Dollar endonly. */    /* Dollar endonly. */
348    int endonly;    int endonly;
   BOOL has_set_som;  
349    /* Tables. */    /* Tables. */
350    sljit_sw ctypes;    sljit_sw ctypes;
351    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 321  typedef struct compiler_common { Line 356  typedef struct compiler_common {
356    
357    /* Labels and jump lists. */    /* Labels and jump lists. */
358    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
359    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
360    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
361      struct sljit_label *accept_label;
362    stub_list *stubs;    stub_list *stubs;
363    recurse_entry *entries;    recurse_entry *entries;
364    recurse_entry *currententry;    recurse_entry *currententry;
365    jump_list *partialmatch;    jump_list *partialmatch;
366    jump_list *quit;    jump_list *quit;
367      jump_list *forced_quit;
368    jump_list *accept;    jump_list *accept;
369    jump_list *calllimit;    jump_list *calllimit;
370    jump_list *stackalloc;    jump_list *stackalloc;
# Line 338  typedef struct compiler_common { Line 375  typedef struct compiler_common {
375    jump_list *vspace;    jump_list *vspace;
376    jump_list *casefulcmp;    jump_list *casefulcmp;
377    jump_list *caselesscmp;    jump_list *caselesscmp;
378      jump_list *reset_match;
379    BOOL jscript_compat;    BOOL jscript_compat;
380  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
381    BOOL utf;    BOOL utf;
# Line 390  typedef struct compare_context { Line 428  typedef struct compare_context {
428  #endif  #endif
429  } compare_context;  } compare_context;
430    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
431  /* Undefine sljit macros. */  /* Undefine sljit macros. */
432  #undef CMP  #undef CMP
433    
434  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
435  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
436    
437  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
438  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
439  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
440  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_SAVED_REG1
441  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_SAVED_REG2
442  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
443  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
444  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
445  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
# Line 428  group contains the start / end character Line 460  group contains the start / end character
460  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. */
461  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
462  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
463  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
464  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
465    
466  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 459  the start pointers when the end of the c Line 491  the start pointers when the end of the c
491    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
492  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
493    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
494    #define SET_LABEL(jump, label) \
495      sljit_set_label((jump), (label))
496  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
497    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
498  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
499    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
500  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
501    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
502  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
503    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
504    
# Line 483  return cc; Line 517  return cc;
517   set_private_data_ptrs   set_private_data_ptrs
518   get_framesize   get_framesize
519   init_frame   init_frame
520   get_private_data_length_for_copy   get_private_data_copy_length
521   copy_private_data   copy_private_data
522   compile_matchingpath   compile_matchingpath
523   compile_backtrackingpath   compile_backtrackingpath
# Line 507  switch(*cc) Line 541  switch(*cc)
541    case OP_WORDCHAR:    case OP_WORDCHAR:
542    case OP_ANY:    case OP_ANY:
543    case OP_ALLANY:    case OP_ALLANY:
544      case OP_NOTPROP:
545      case OP_PROP:
546    case OP_ANYNL:    case OP_ANYNL:
547    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
548    case OP_HSPACE:    case OP_HSPACE:
# Line 519  switch(*cc) Line 555  switch(*cc)
555    case OP_CIRCM:    case OP_CIRCM:
556    case OP_DOLL:    case OP_DOLL:
557    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:  
558    case OP_CRSTAR:    case OP_CRSTAR:
559    case OP_CRMINSTAR:    case OP_CRMINSTAR:
560    case OP_CRPLUS:    case OP_CRPLUS:
561    case OP_CRMINPLUS:    case OP_CRMINPLUS:
562    case OP_CRQUERY:    case OP_CRQUERY:
563    case OP_CRMINQUERY:    case OP_CRMINQUERY:
564      case OP_CRRANGE:
565      case OP_CRMINRANGE:
566      case OP_CLASS:
567      case OP_NCLASS:
568      case OP_REF:
569      case OP_REFI:
570      case OP_RECURSE:
571      case OP_CALLOUT:
572      case OP_ALT:
573      case OP_KET:
574      case OP_KETRMAX:
575      case OP_KETRMIN:
576      case OP_KETRPOS:
577      case OP_REVERSE:
578      case OP_ASSERT:
579      case OP_ASSERT_NOT:
580      case OP_ASSERTBACK:
581      case OP_ASSERTBACK_NOT:
582      case OP_ONCE:
583      case OP_ONCE_NC:
584      case OP_BRA:
585      case OP_BRAPOS:
586      case OP_CBRA:
587      case OP_CBRAPOS:
588      case OP_COND:
589      case OP_SBRA:
590      case OP_SBRAPOS:
591      case OP_SCBRA:
592      case OP_SCBRAPOS:
593      case OP_SCOND:
594      case OP_CREF:
595      case OP_NCREF:
596      case OP_RREF:
597      case OP_NRREF:
598    case OP_DEF:    case OP_DEF:
599    case OP_BRAZERO:    case OP_BRAZERO:
600    case OP_BRAMINZERO:    case OP_BRAMINZERO:
601    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
602      case OP_PRUNE:
603      case OP_SKIP:
604    case OP_COMMIT:    case OP_COMMIT:
605    case OP_FAIL:    case OP_FAIL:
606    case OP_ACCEPT:    case OP_ACCEPT:
607    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
608      case OP_CLOSE:
609    case OP_SKIPZERO:    case OP_SKIPZERO:
610    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
611    
612    case OP_CHAR:    case OP_CHAR:
613    case OP_CHARI:    case OP_CHARI:
# Line 561  switch(*cc) Line 619  switch(*cc)
619    case OP_MINPLUS:    case OP_MINPLUS:
620    case OP_QUERY:    case OP_QUERY:
621    case OP_MINQUERY:    case OP_MINQUERY:
622      case OP_UPTO:
623      case OP_MINUPTO:
624      case OP_EXACT:
625    case OP_POSSTAR:    case OP_POSSTAR:
626    case OP_POSPLUS:    case OP_POSPLUS:
627    case OP_POSQUERY:    case OP_POSQUERY:
628      case OP_POSUPTO:
629    case OP_STARI:    case OP_STARI:
630    case OP_MINSTARI:    case OP_MINSTARI:
631    case OP_PLUSI:    case OP_PLUSI:
632    case OP_MINPLUSI:    case OP_MINPLUSI:
633    case OP_QUERYI:    case OP_QUERYI:
634    case OP_MINQUERYI:    case OP_MINQUERYI:
635      case OP_UPTOI:
636      case OP_MINUPTOI:
637      case OP_EXACTI:
638    case OP_POSSTARI:    case OP_POSSTARI:
639    case OP_POSPLUSI:    case OP_POSPLUSI:
640    case OP_POSQUERYI:    case OP_POSQUERYI:
641      case OP_POSUPTOI:
642    case OP_NOTSTAR:    case OP_NOTSTAR:
643    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
644    case OP_NOTPLUS:    case OP_NOTPLUS:
645    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
646    case OP_NOTQUERY:    case OP_NOTQUERY:
647    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
648      case OP_NOTUPTO:
649      case OP_NOTMINUPTO:
650      case OP_NOTEXACT:
651    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
652    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
653    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
654      case OP_NOTPOSUPTO:
655    case OP_NOTSTARI:    case OP_NOTSTARI:
656    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
657    case OP_NOTPLUSI:    case OP_NOTPLUSI:
658    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
659    case OP_NOTQUERYI:    case OP_NOTQUERYI:
660    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:  
661    case OP_NOTUPTOI:    case OP_NOTUPTOI:
662    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
663    case OP_NOTEXACTI:    case OP_NOTEXACTI:
664      case OP_NOTPOSSTARI:
665      case OP_NOTPOSPLUSI:
666      case OP_NOTPOSQUERYI:
667    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
668    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
669  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
670    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
671  #endif  #endif
672    return cc;    return cc;
673    
674    case OP_NOTPROP:    /* Special cases. */
675    case OP_PROP:    case OP_TYPESTAR:
676    return cc + 1 + 2;    case OP_TYPEMINSTAR:
677      case OP_TYPEPLUS:
678      case OP_TYPEMINPLUS:
679      case OP_TYPEQUERY:
680      case OP_TYPEMINQUERY:
681    case OP_TYPEUPTO:    case OP_TYPEUPTO:
682    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
683    case OP_TYPEEXACT:    case OP_TYPEEXACT:
684      case OP_TYPEPOSSTAR:
685      case OP_TYPEPOSPLUS:
686      case OP_TYPEPOSQUERY:
687    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
688    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;  
689    
690    case OP_CLASS:    case OP_ANYBYTE:
691    case OP_NCLASS:  #ifdef SUPPORT_UTF
692    return cc + 1 + 32 / sizeof(pcre_uchar);    if (common->utf) return NULL;
693    #endif
694      return cc + 1;
695    
696  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
697    case OP_XCLASS:    case OP_XCLASS:
698    return cc + GET(cc, 1);    return cc + GET(cc, 1);
699  #endif  #endif
700    
   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;  
   
701    case OP_MARK:    case OP_MARK:
702      case OP_PRUNE_ARG:
703      case OP_SKIP_ARG:
704    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
705    
706    default:    default:
# Line 812  while (cc < ccend) Line 835  while (cc < ccend)
835    
836      case OP_COND:      case OP_COND:
837      case OP_SCOND:      case OP_SCOND:
838      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
839      if (bracketlen == OP_CREF)         not intend to support this case. */
840        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
841        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);        return -1;
       common->optimized_cbracket[bracketlen] = 0;  
       }  
     else if (bracketlen == OP_NCREF)  
       {  
       bracketlen = GET2(cc, 1 + LINK_SIZE + 1);  
       name = (pcre_uchar *)common->name_table;  
       alternative = name;  
       for (i = 0; i < common->name_count; i++)  
         {  
         if (GET2(name, 0) == bracketlen) break;  
         name += common->name_entry_size;  
         }  
       SLJIT_ASSERT(i != common->name_count);  
   
       for (i = 0; i < common->name_count; i++)  
         {  
         if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)  
           common->optimized_cbracket[GET2(alternative, 0)] = 0;  
         alternative += common->name_entry_size;  
         }  
       }  
842    
843      if (*cc == OP_COND)      if (*cc == OP_COND)
844        {        {
# Line 850  while (cc < ccend) Line 852  while (cc < ccend)
852      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
853      break;      break;
854    
855        case OP_CREF:
856        i = GET2(cc, 1);
857        common->optimized_cbracket[i] = 0;
858        cc += 1 + IMM2_SIZE;
859        break;
860    
861        case OP_NCREF:
862        bracketlen = GET2(cc, 1);
863        name = (pcre_uchar *)common->name_table;
864        alternative = name;
865        for (i = 0; i < common->name_count; i++)
866          {
867          if (GET2(name, 0) == bracketlen) break;
868          name += common->name_entry_size;
869          }
870        SLJIT_ASSERT(i != common->name_count);
871    
872        for (i = 0; i < common->name_count; i++)
873          {
874          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
875            common->optimized_cbracket[GET2(alternative, 0)] = 0;
876          alternative += common->name_entry_size;
877          }
878        bracketlen = 0;
879        cc += 1 + IMM2_SIZE;
880        break;
881    
882      case OP_BRA:      case OP_BRA:
883      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
884      break;      break;
# Line 906  while (cc < ccend) Line 935  while (cc < ccend)
935    
936      case OP_RECURSE:      case OP_RECURSE:
937      /* Set its value only once. */      /* Set its value only once. */
938      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
939        {        {
940        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
941        common->ovector_start += sizeof(sljit_sw);        common->ovector_start += sizeof(sljit_sw);
942        }        }
943      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
944      break;      break;
945    
946        case OP_CALLOUT:
947        if (common->capture_last_ptr == 0)
948          {
949          common->capture_last_ptr = common->ovector_start;
950          common->ovector_start += sizeof(sljit_sw);
951          }
952        cc += 2 + 2 * LINK_SIZE;
953        break;
954    
955        case OP_PRUNE_ARG:
956        common->needs_start_ptr = TRUE;
957        common->control_head_ptr = 1;
958        /* Fall through. */
959    
960      case OP_MARK:      case OP_MARK:
961      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
962        {        {
# Line 923  while (cc < ccend) Line 966  while (cc < ccend)
966      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
967      break;      break;
968    
969        case OP_PRUNE:
970        case OP_SKIP:
971        common->needs_start_ptr = TRUE;
972        common->control_head_ptr = 1;
973        cc += 1;
974        break;
975    
976        case OP_SKIP_ARG:
977        common->control_head_ptr = 1;
978        common->has_skip_arg = TRUE;
979        cc += 1 + 2 + cc[1];
980        break;
981    
982      default:      default:
983      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
984      if (cc == NULL)      if (cc == NULL)
# Line 1099  while (cc < ccend) Line 1155  while (cc < ccend)
1155    }    }
1156  }  }
1157    
1158  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1159  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive, BOOL* needs_control_head)
1160  {  {
1161  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1162  int length = 0;  int length = 0;
1163  BOOL possessive = FALSE;  int possessive = 0;
1164    BOOL stack_restore = FALSE;
1165  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1166  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1167    /* The last capture is a local variable even for recursions. */
1168    BOOL capture_last_found = FALSE;
1169    
1170    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1171    SLJIT_ASSERT(common->control_head_ptr != 0);
1172    *needs_control_head = TRUE;
1173    #else
1174    *needs_control_head = FALSE;
1175    #endif
1176    
1177  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1178    {    {
1179    length = 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1180    possessive = TRUE;    /* This is correct regardless of common->capture_last_ptr. */
1181      capture_last_found = TRUE;
1182    }    }
1183    
1184  cc = next_opcode(common, cc);  cc = next_opcode(common, cc);
# Line 1121  while (cc < ccend) Line 1188  while (cc < ccend)
1188      {      {
1189      case OP_SET_SOM:      case OP_SET_SOM:
1190      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1191        stack_restore = TRUE;
1192      if (!setsom_found)      if (!setsom_found)
1193        {        {
1194        length += 2;        length += 2;
# Line 1130  while (cc < ccend) Line 1198  while (cc < ccend)
1198      break;      break;
1199    
1200      case OP_MARK:      case OP_MARK:
1201        case OP_PRUNE_ARG:
1202      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1203        stack_restore = TRUE;
1204      if (!setmark_found)      if (!setmark_found)
1205        {        {
1206        length += 2;        length += 2;
1207        setmark_found = TRUE;        setmark_found = TRUE;
1208        }        }
1209        if (common->control_head_ptr != 0)
1210          *needs_control_head = TRUE;
1211      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1212      break;      break;
1213    
1214      case OP_RECURSE:      case OP_RECURSE:
1215        stack_restore = TRUE;
1216      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1217        {        {
1218        length += 2;        length += 2;
# Line 1150  while (cc < ccend) Line 1223  while (cc < ccend)
1223        length += 2;        length += 2;
1224        setmark_found = TRUE;        setmark_found = TRUE;
1225        }        }
1226        if (common->capture_last_ptr != 0 && !capture_last_found)
1227          {
1228          length += 2;
1229          capture_last_found = TRUE;
1230          }
1231      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1232      break;      break;
1233    
# Line 1157  while (cc < ccend) Line 1235  while (cc < ccend)
1235      case OP_CBRAPOS:      case OP_CBRAPOS:
1236      case OP_SCBRA:      case OP_SCBRA:
1237      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1238        stack_restore = TRUE;
1239        if (common->capture_last_ptr != 0 && !capture_last_found)
1240          {
1241          length += 2;
1242          capture_last_found = TRUE;
1243          }
1244      length += 3;      length += 3;
1245      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1246      break;      break;
1247    
1248        case OP_PRUNE:
1249        case OP_SKIP:
1250        case OP_SKIP_ARG:
1251        case OP_COMMIT:
1252        if (common->control_head_ptr != 0)
1253          *needs_control_head = TRUE;
1254        /* Fall through. */
1255    
1256      default:      default:
1257        stack_restore = TRUE;
1258        /* Fall through. */
1259    
1260        case OP_NOT_WORD_BOUNDARY:
1261        case OP_WORD_BOUNDARY:
1262        case OP_NOT_DIGIT:
1263        case OP_DIGIT:
1264        case OP_NOT_WHITESPACE:
1265        case OP_WHITESPACE:
1266        case OP_NOT_WORDCHAR:
1267        case OP_WORDCHAR:
1268        case OP_ANY:
1269        case OP_ALLANY:
1270        case OP_ANYBYTE:
1271        case OP_NOTPROP:
1272        case OP_PROP:
1273        case OP_ANYNL:
1274        case OP_NOT_HSPACE:
1275        case OP_HSPACE:
1276        case OP_NOT_VSPACE:
1277        case OP_VSPACE:
1278        case OP_EXTUNI:
1279        case OP_EODN:
1280        case OP_EOD:
1281        case OP_CIRC:
1282        case OP_CIRCM:
1283        case OP_DOLL:
1284        case OP_DOLLM:
1285        case OP_CHAR:
1286        case OP_CHARI:
1287        case OP_NOT:
1288        case OP_NOTI:
1289    
1290        case OP_EXACT:
1291        case OP_POSSTAR:
1292        case OP_POSPLUS:
1293        case OP_POSQUERY:
1294        case OP_POSUPTO:
1295    
1296        case OP_EXACTI:
1297        case OP_POSSTARI:
1298        case OP_POSPLUSI:
1299        case OP_POSQUERYI:
1300        case OP_POSUPTOI:
1301    
1302        case OP_NOTEXACT:
1303        case OP_NOTPOSSTAR:
1304        case OP_NOTPOSPLUS:
1305        case OP_NOTPOSQUERY:
1306        case OP_NOTPOSUPTO:
1307    
1308        case OP_NOTEXACTI:
1309        case OP_NOTPOSSTARI:
1310        case OP_NOTPOSPLUSI:
1311        case OP_NOTPOSQUERYI:
1312        case OP_NOTPOSUPTOI:
1313    
1314        case OP_TYPEEXACT:
1315        case OP_TYPEPOSSTAR:
1316        case OP_TYPEPOSPLUS:
1317        case OP_TYPEPOSQUERY:
1318        case OP_TYPEPOSUPTO:
1319    
1320        case OP_CLASS:
1321        case OP_NCLASS:
1322        case OP_XCLASS:
1323    
1324      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1325      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1326      break;      break;
1327      }      }
1328    
1329  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1330  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1331    return -1;    return stack_restore ? no_frame : no_stack;
1332    
1333  if (length > 0)  if (length > 0)
1334    return length + 1;    return length + 1;
1335  return -1;  return stack_restore ? no_frame : no_stack;
1336  }  }
1337    
1338  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, int stackpos, int stacktop, BOOL recursive)
1339  {  {
1340  DEFINE_COMPILER;  DEFINE_COMPILER;
1341  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1342  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1343  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1344    /* The last capture is a local variable even for recursions. */
1345    BOOL capture_last_found = FALSE;
1346  int offset;  int offset;
1347    
1348  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1200  while (cc < ccend) Line 1361  while (cc < ccend)
1361      if (!setsom_found)      if (!setsom_found)
1362        {        {
1363        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1364        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1365        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1366        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1367        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1210  while (cc < ccend) Line 1371  while (cc < ccend)
1371      break;      break;
1372    
1373      case OP_MARK:      case OP_MARK:
1374        case OP_PRUNE_ARG:
1375      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1376      if (!setmark_found)      if (!setmark_found)
1377        {        {
1378        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);
1379        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);
1380        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1381        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1382        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1227  while (cc < ccend) Line 1389  while (cc < ccend)
1389      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1390        {        {
1391        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1392        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1393        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1394        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1395        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1236  while (cc < ccend) Line 1398  while (cc < ccend)
1398      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1399        {        {
1400        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);
1401        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);
1402        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1403        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1404        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1405        setmark_found = TRUE;        setmark_found = TRUE;
1406        }        }
1407        if (common->capture_last_ptr != 0 && !capture_last_found)
1408          {
1409          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1410          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1411          stackpos += (int)sizeof(sljit_sw);
1412          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1413          stackpos += (int)sizeof(sljit_sw);
1414          capture_last_found = TRUE;
1415          }
1416      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1417      break;      break;
1418    
# Line 1249  while (cc < ccend) Line 1420  while (cc < ccend)
1420      case OP_CBRAPOS:      case OP_CBRAPOS:
1421      case OP_SCBRA:      case OP_SCBRA:
1422      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1423        if (common->capture_last_ptr != 0 && !capture_last_found)
1424          {
1425          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1426          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1427          stackpos += (int)sizeof(sljit_sw);
1428          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1429          stackpos += (int)sizeof(sljit_sw);
1430          capture_last_found = TRUE;
1431          }
1432      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1433      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1434      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
# Line 1268  while (cc < ccend) Line 1448  while (cc < ccend)
1448      break;      break;
1449      }      }
1450    
1451  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1452  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1453  }  }
1454    
1455  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)
1456  {  {
1457  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1458  int size;  int size;
1459  pcre_uchar *alternative;  pcre_uchar *alternative;
1460  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1387  return private_data_length; Line 1567  return private_data_length;
1567  }  }
1568    
1569  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,
1570    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1571  {  {
1572  DEFINE_COMPILER;  DEFINE_COMPILER;
1573  int srcw[2];  int srcw[2];
# Line 1408  stacktop = STACK(stacktop - 1); Line 1588  stacktop = STACK(stacktop - 1);
1588    
1589  if (!save)  if (!save)
1590    {    {
1591    stackptr += sizeof(sljit_sw);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1592    if (stackptr < stacktop)    if (stackptr < stacktop)
1593      {      {
1594      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
# Line 1424  if (!save) Line 1604  if (!save)
1604    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1605    }    }
1606    
1607  while (status != end)  do
1608    {    {
1609    count = 0;    count = 0;
1610    switch(status)    switch(status)
1611      {      {
1612      case start:      case start:
1613      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1614      count = 1;      count = 1;
1615      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1616        if (needs_control_head)
1617          {
1618          SLJIT_ASSERT(common->control_head_ptr != 0);
1619          count = 2;
1620          srcw[1] = common->control_head_ptr;
1621          }
1622      status = loop;      status = loop;
1623      break;      break;
1624    
# Line 1657  while (status != end) Line 1843  while (status != end)
1843        }        }
1844      }      }
1845    }    }
1846    while (status != end);
1847    
1848  if (save)  if (save)
1849    {    {
# Line 1708  while (list) Line 1895  while (list)
1895    {    {
1896    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1897    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1898    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1899    list = list->next;    list = list->next;
1900    }    }
1901  }  }
# Line 1724  if (list_item) Line 1911  if (list_item)
1911    }    }
1912  }  }
1913    
1914  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)
1915  {  {
1916  DEFINE_COMPILER;  DEFINE_COMPILER;
1917  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1918    
1919  if (list_item)  if (list_item)
1920    {    {
   list_item->type = type;  
   list_item->data = data;  
1921    list_item->start = start;    list_item->start = start;
1922    list_item->quit = LABEL();    list_item->quit = LABEL();
1923    list_item->next = common->stubs;    list_item->next = common->stubs;
# Line 1748  stub_list* list_item = common->stubs; Line 1933  stub_list* list_item = common->stubs;
1933  while (list_item)  while (list_item)
1934    {    {
1935    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
1936    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;  
     }  
1937    JUMPTO(SLJIT_JUMP, list_item->quit);    JUMPTO(SLJIT_JUMP, list_item->quit);
1938    list_item = list_item->next;    list_item = list_item->next;
1939    }    }
# Line 1781  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 1961  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1961  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
1962  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
1963  #endif  #endif
1964  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));
1965  }  }
1966    
1967  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
# Line 1795  static SLJIT_INLINE void reset_ovector(c Line 1975  static SLJIT_INLINE void reset_ovector(c
1975  DEFINE_COMPILER;  DEFINE_COMPILER;
1976  struct sljit_label *loop;  struct sljit_label *loop;
1977  int i;  int i;
1978    
1979  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1980    SLJIT_ASSERT(length > 1);
1981  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1982  OP2(SLJIT_SUB, SLJIT_TEMPORARY_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));
1983  if (length < 8)  if (length < 8)
1984    {    {
1985    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
1986      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1987    }    }
1988  else  else
1989    {    {
1990    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
1991    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
1992    loop = LABEL();    loop = LABEL();
1993    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_sw), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1994    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
1995    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1996    }    }
1997  }  }
1998    
1999    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2000    {
2001    DEFINE_COMPILER;
2002    struct sljit_label *loop;
2003    int i;
2004    
2005    SLJIT_ASSERT(length > 1);
2006    /* OVECTOR(1) contains the "string begin - 1" constant. */
2007    if (length > 2)
2008      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2009    if (length < 8)
2010      {
2011      for (i = 2; i < length; i++)
2012        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2013      }
2014    else
2015      {
2016      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2017      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2018      loop = LABEL();
2019      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2020      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2021      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2022      }
2023    
2024    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2025    if (common->mark_ptr != 0)
2026      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2027    SLJIT_ASSERT(common->control_head_ptr != 0);
2028    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2029    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2030    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2031    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2032    }
2033    
2034    static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2035    {
2036    sljit_sw return_value = 0;
2037    const pcre_uchar *skip_arg = NULL;
2038    
2039    SLJIT_ASSERT(current != NULL);
2040    do
2041      {
2042      switch (current[-2])
2043        {
2044        case type_commit:
2045        /* Commit overwrites all. */
2046        return -1;
2047    
2048        case type_prune:
2049        break;
2050    
2051        case type_skip:
2052        /* Overwrites prune, but not other skips. */
2053        if (return_value == 0 && skip_arg == NULL)
2054          return_value = current[-3];
2055        break;
2056    
2057        case type_skip_arg:
2058        if (return_value == 0 && skip_arg == NULL)
2059          skip_arg = (pcre_uchar *)current[-3];
2060        break;
2061    
2062        case type_mark:
2063        if (return_value == 0 && skip_arg != NULL)
2064          if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2065            return_value = current[-4];
2066        break;
2067    
2068        default:
2069        SLJIT_ASSERT_STOP();
2070        break;
2071        }
2072      current = (sljit_sw*)current[-1];
2073      }
2074    while (current != NULL);
2075    return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2076    }
2077    
2078  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2079  {  {
2080  DEFINE_COMPILER;  DEFINE_COMPILER;
2081  struct sljit_label *loop;  struct sljit_label *loop;
2082  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
2083    
2084  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2085  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2086  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
2087    
2088  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
2089  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2090    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
2091  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
2092  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2093    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
2094  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2095  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
2096  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
2097  /* Unlikely, but possible */  /* Unlikely, but possible */
2098  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
2099  loop = LABEL();  loop = LABEL();
2100  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
2101  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
2102  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
2103  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2104  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2105  #endif  #endif
2106  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
2107  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
2108  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2109  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2110    
2111  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2112  if (topbracket > 1)  if (topbracket > 1)
2113    {    {
2114    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
2115    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
2116    
2117    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
2118    loop = LABEL();    loop = LABEL();
2119    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));    OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
2120    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
2121    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
2122    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
2123    }    }
2124  else  else
2125    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
# Line 1867  else Line 2128  else
2128  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)
2129  {  {
2130  DEFINE_COMPILER;  DEFINE_COMPILER;
2131    struct sljit_jump *jump;
2132    
2133  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);
2134  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
2135      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2136    
2137  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2138  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2139  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2140  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
2141    
2142  /* Store match begin and end. */  /* Store match begin and end. */
2143  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
2144  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2145  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  
2146    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2147    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);
2148    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2149    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2150    #endif
2151    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2152    JUMPHERE(jump);
2153    
2154    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);
2155  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);
2156  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2157  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2158  #endif  #endif
2159  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
2160    
2161  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
2162  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2163  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2164  #endif  #endif
2165  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
2166    
2167  JUMPTO(SLJIT_JUMP, quit);  JUMPTO(SLJIT_JUMP, quit);
2168  }  }
# Line 2055  else if (common->mode == JIT_PARTIAL_SOF Line 2327  else if (common->mode == JIT_PARTIAL_SOF
2327    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);
2328    
2329  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2330    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);
2331  else  else
2332    {    {
2333    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2068  if (jump != NULL) Line 2340  if (jump != NULL)
2340    JUMPHERE(jump);    JUMPHERE(jump);
2341  }  }
2342    
2343  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2344  {  {
2345  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2346  DEFINE_COMPILER;  DEFINE_COMPILER;
2347  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2348    
2349  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2350    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2351      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2352      return;
2353      }
2354    
2355  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2356  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2357    {    {
2358    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));
2359    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);
2360    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2361    }    }
2362  else  else
2363    {    {
2364    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));
2365    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2366      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2367    else    else
2368      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2369    }    }
2370  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2371  }  }
2372    
2373  static void detect_partial_match(compiler_common *common, jump_list **backtracks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
# Line 2115  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR Line 2386  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2386  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));
2387  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2388    {    {
2389    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);
2390    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2391    }    }
2392  else  else
# Line 2206  if (common->utf) Line 2477  if (common->utf)
2477    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2478    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2479    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2480    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2481    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2482    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2483  #elif defined COMPILE_PCRE32  #elif defined COMPILE_PCRE32
# Line 2256  if (common->utf) Line 2527  if (common->utf)
2527    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2528    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2529    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2530    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2531    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2532    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2533    return;    return;
# Line 2279  if (nltype == NLTYPE_ANY) Line 2550  if (nltype == NLTYPE_ANY)
2550  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2551    {    {
2552    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
2553    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2554    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2555    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2556    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2557    }    }
2558  else  else
# Line 2509  if (newlinecheck) Line 2780  if (newlinecheck)
2780    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2781    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2782    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2783    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2784  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2785    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2786  #endif  #endif
# Line 2547  if (common->utf) Line 2818  if (common->utf)
2818    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2819    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2820    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2821    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2822    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2823    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2824    JUMPHERE(singlechar);    JUMPHERE(singlechar);
# Line 2573  DEFINE_COMPILER; Line 2844  DEFINE_COMPILER;
2844  struct sljit_label *start;  struct sljit_label *start;
2845  struct sljit_jump *quit;  struct sljit_jump *quit;
2846  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
2847  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2848  int location = 0;  int location = 0;
2849  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2850  int must_stop;  int must_stop;
# Line 2696  if (firstline) Line 2967  if (firstline)
2967    {    {
2968    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2969    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2970    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2971    }    }
2972  else  else
2973    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2974    
2975  start = LABEL();  start = LABEL();
2976  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 2728  JUMPHERE(quit); Line 2999  JUMPHERE(quit);
2999  if (firstline)  if (firstline)
3000    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3001  else  else
3002    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3003  return TRUE;  return TRUE;
3004  }  }
3005    
# Line 2775  else Line 3046  else
3046    else    else
3047      {      {
3048      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
3049      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3050      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
3051      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3052      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
3053      }      }
3054    }    }
# Line 2819  if (common->nltype == NLTYPE_FIXED && co Line 3090  if (common->nltype == NLTYPE_FIXED && co
3090    
3091    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
3092    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
3093    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
3094  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3095    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
3096  #endif  #endif
# Line 2862  if (common->nltype == NLTYPE_ANY || comm Line 3133  if (common->nltype == NLTYPE_ANY || comm
3133    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3134    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3135    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
3136    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3137  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3138    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3139  #endif  #endif
# Line 2877  if (firstline) Line 3148  if (firstline)
3148    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3149  }  }
3150    
3151    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3152    
3153  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
3154  {  {
3155  DEFINE_COMPILER;  DEFINE_COMPILER;
3156  struct sljit_label *start;  struct sljit_label *start;
3157  struct sljit_jump *quit;  struct sljit_jump *quit;
3158  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3159    jump_list *matches = NULL;
3160    pcre_uint8 inverted_start_bits[32];
3161    int i;
3162  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3163  struct sljit_jump *jump;  struct sljit_jump *jump;
3164  #endif  #endif
3165    
3166    for (i = 0; i < 32; ++i)
3167      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3168    
3169  if (firstline)  if (firstline)
3170    {    {
3171    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 2901  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P Line 3180  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
3180  if (common->utf)  if (common->utf)
3181    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3182  #endif  #endif
3183    
3184    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3185      {
3186  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3187  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3188  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3189  JUMPHERE(jump);    JUMPHERE(jump);
3190  #endif  #endif
3191  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3192  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3193  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3194  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3195  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3196  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
3197      }
3198    
3199  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3200  if (common->utf)  if (common->utf)
# Line 2932  if (common->utf) Line 3215  if (common->utf)
3215    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
3216    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3217    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3218    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3219    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3220    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3221    }    }
3222  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE[8|16] */
3223  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3224  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3225  JUMPHERE(found);  if (found != NULL)
3226      JUMPHERE(found);
3227    if (matches != NULL)
3228      set_jumps(matches, LABEL());
3229  JUMPHERE(quit);  JUMPHERE(quit);
3230    
3231  if (firstline)  if (firstline)
# Line 3022  GET_LOCAL_BASE(TMP3, 0, 0); Line 3308  GET_LOCAL_BASE(TMP3, 0, 0);
3308  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3309  mainloop = LABEL();  mainloop = LABEL();
3310  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3311  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);
3312    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3313    
3314  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3315  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));
3316  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
# Line 3030  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I Line 3318  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
3318  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3319    
3320  JUMPHERE(jump);  JUMPHERE(jump);
3321  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3322  /* End of dropping frames. */  /* End of dropping frames. */
3323  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3324    
3325  JUMPHERE(jump);  JUMPHERE(jump);
3326  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3327  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3328  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. */  
3329  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));
3330  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3331  }  }
# Line 3063  static void check_wordboundary(compiler_ Line 3334  static void check_wordboundary(compiler_
3334  {  {
3335  DEFINE_COMPILER;  DEFINE_COMPILER;
3336  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3337    jump_list *skipread_list = NULL;
3338  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3339  struct sljit_jump *jump;  struct sljit_jump *jump;
3340  #endif  #endif
# Line 3088  if (common->use_ucp) Line 3360  if (common->use_ucp)
3360    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3361    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3362    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3363    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3364    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3365    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3366    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3367    JUMPHERE(jump);    JUMPHERE(jump);
3368    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3369    }    }
# Line 3120  else Line 3392  else
3392  JUMPHERE(skipread);  JUMPHERE(skipread);
3393    
3394  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3395  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3396  peek_char(common);  peek_char(common);
3397    
3398  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3132  if (common->use_ucp) Line 3404  if (common->use_ucp)
3404    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3405    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3406    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3407    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3408    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3409    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3410    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3411    JUMPHERE(jump);    JUMPHERE(jump);
3412    }    }
3413  else  else
# Line 3161  else Line 3433  else
3433      JUMPHERE(jump);      JUMPHERE(jump);
3434  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3435    }    }
3436  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3437    
3438  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);
3439  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 3315  sljit_emit_fast_enter(compiler, RETURN_A Line 3587  sljit_emit_fast_enter(compiler, RETURN_A
3587    
3588  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3589  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3590  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3591  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3592  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3593  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3594  if (common->utf)  if (common->utf)
3595    {    {
3596  #endif  #endif
3597    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3598    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3599    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3600  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3601    }    }
3602  #endif  #endif
3603  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3604  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3605  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3606  }  }
3607    
# Line 3341  DEFINE_COMPILER; Line 3613  DEFINE_COMPILER;
3613  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3614    
3615  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3616  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3617  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3618  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3619  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3620  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3621  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3622  if (common->utf)  if (common->utf)
3623    {    {
3624  #endif  #endif
3625    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3626    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
3627    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3628    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
3629    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3630    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3631    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
3632    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3633    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
3634    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3635    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
3636    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3637    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
3638  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3639    }    }
3640  #endif  #endif
3641  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3642  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3643    
3644  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3645  }  }
# Line 3381  sljit_emit_fast_enter(compiler, RETURN_A Line 3653  sljit_emit_fast_enter(compiler, RETURN_A
3653    
3654  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3655  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3656  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3657  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3658  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3659  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3660  if (common->utf)  if (common->utf)
3661    {    {
3662  #endif  #endif
3663    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3664    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3665    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3666  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3667    }    }
3668  #endif  #endif
3669  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3670  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3671    
3672  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3673  }  }
# Line 3481  sljit_emit_fast_return(compiler, RETURN_ Line 3753  sljit_emit_fast_return(compiler, RETURN_
3753    
3754  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3755    
3756  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3757  {  {
3758  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3759  pcre_uint32 c1, c2;  pcre_uint32 c1, c2;
# Line 3532  if (caseless && char_has_othercase(commo Line 3804  if (caseless && char_has_othercase(commo
3804    othercasebit &= 0xff;    othercasebit &= 0xff;
3805  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3806    /* Note that this code only handles characters in the BMP. If there    /* Note that this code only handles characters in the BMP. If there
3807    ever are characters outside the BMP whose othercase differs in only one    ever are characters outside the BMP whose othercase differs in only one
3808    bit from itself (there currently are none), this code will need to be    bit from itself (there currently are none), this code will need to be
3809    revised for COMPILE_PCRE32. */    revised for COMPILE_PCRE32. */
3810    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
# Line 3577  do Line 3849  do
3849  #endif  #endif
3850    
3851    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3852  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3853    
3854    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3855    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3594  do Line 3866  do
3866    
3867  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3868    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3869  #elif defined COMPILE_PCRE16  #else
3870    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
 #elif defined COMPILE_PCRE32  
   if (1 /* context->ucharptr >= 1 || context->length == 0 */)  
3871  #endif  #endif
3872      {      {
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3873      if (context->length >= 4)      if (context->length >= 4)
3874        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
 #if defined COMPILE_PCRE8  
3875      else if (context->length >= 2)      else if (context->length >= 2)
3876        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3877    #if defined COMPILE_PCRE8
3878      else if (context->length >= 1)      else if (context->length >= 1)
3879        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3880  #elif defined COMPILE_PCRE16  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif /* COMPILE_PCRE[8|16] */  
 #elif defined COMPILE_PCRE32  
     OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif /* COMPILE_PCRE[8|16|32] */  
3881      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3882    
3883      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3625  do Line 3888  do
3888        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3889        break;        break;
3890    
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3891        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3892        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3893          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
# Line 3640  do Line 3902  do
3902        break;        break;
3903  #endif  #endif
3904    
 #endif /* COMPILE_PCRE[8|16] */  
   
3905        default:        default:
3906        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3907        break;        break;
# Line 3651  do Line 3911  do
3911    
3912  #else  #else
3913    
3914    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3915    if (context->length > 0)    if (context->length >= 1)
3916      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3917    
3918    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
# Line 3813  while (*cc != XCL_END) Line 4073  while (*cc != XCL_END)
4073        break;        break;
4074    
4075        case PT_CLIST:        case PT_CLIST:
4076          case PT_UCNC:
4077        needschar = TRUE;        needschar = TRUE;
4078        break;        break;
4079    
# Line 3894  while (*cc != XCL_END) Line 4155  while (*cc != XCL_END)
4155      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4156        {        {
4157        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
4158        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
4159        numberofcmps++;        numberofcmps++;
4160        }        }
4161      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4162        {        {
4163        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
4164        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4165        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4166        numberofcmps = 0;        numberofcmps = 0;
4167        }        }
# Line 3933  while (*cc != XCL_END) Line 4194  while (*cc != XCL_END)
4194      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4195        {        {
4196        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
4197        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4198        numberofcmps++;        numberofcmps++;
4199        }        }
4200      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4201        {        {
4202        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
4203        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4204        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4205        numberofcmps = 0;        numberofcmps = 0;
4206        }        }
# Line 3970  while (*cc != XCL_END) Line 4231  while (*cc != XCL_END)
4231    
4232        case PT_LAMP:        case PT_LAMP:
4233        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
4234        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4235        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
4236        COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4237        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
4238        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4239        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4240        break;        break;
4241    
# Line 4001  while (*cc != XCL_END) Line 4262  while (*cc != XCL_END)
4262          }          }
4263        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4264        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
4265        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4266        if (*cc == PT_SPACE)        if (*cc == PT_SPACE)
4267          JUMPHERE(jump);          JUMPHERE(jump);
4268    
4269        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4270        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
4271        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4272        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4273        break;        break;
4274    
4275        case PT_WORD:        case PT_WORD:
4276        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);
4277        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4278        /* ... fall through */        /* Fall through. */
4279    
4280        case PT_ALNUM:        case PT_ALNUM:
4281        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
4282        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4283        COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4284        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
4285        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4286        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4287        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4288        break;        break;
4289    
# Line 4045  while (*cc != XCL_END) Line 4306  while (*cc != XCL_END)
4306            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4307            }            }
4308          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4309          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4310          other_cases += 2;          other_cases += 2;
4311          }          }
4312        else if (is_powerof2(other_cases[2] ^ other_cases[1]))        else if (is_powerof2(other_cases[2] ^ other_cases[1]))
# Line 4058  while (*cc != XCL_END) Line 4319  while (*cc != XCL_END)
4319            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);            OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4320            }            }
4321          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4322          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4323    
4324          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4325          COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4326    
4327          other_cases += 3;          other_cases += 3;
4328          }          }
4329        else        else
4330          {          {
4331          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4332          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4333          }          }
4334    
4335        while (*other_cases != NOTACHAR)        while (*other_cases != NOTACHAR)
4336          {          {
4337          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4338          COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);          OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4339          }          }
4340        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4341        break;        break;
4342    
4343          case PT_UCNC:
4344          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
4345          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4346          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
4347          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4348          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
4349          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4350    
4351          SET_CHAR_OFFSET(0xa0);
4352          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4353          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4354          SET_CHAR_OFFSET(0);
4355          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4356          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4357          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4358          break;
4359        }        }
4360      cc += 2;      cc += 2;
4361      }      }
# Line 4103  int length; Line 4381  int length;
4381  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4382  compare_context context;  compare_context context;
4383  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4384    jump_list *end_list;
4385  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4386  struct sljit_label *label;  struct sljit_label *label;
4387  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4171  switch(type) Line 4450  switch(type)
4450    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4451      {      {
4452      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);
4453        end_list = NULL;
4454      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4455        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));
4456      else      else
4457        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4458    
4459      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4460      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));
4461      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4462      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4463      }      }
4464    else    else
# Line 4202  switch(type) Line 4481  switch(type)
4481      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4482      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4483      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4484      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4485      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4486      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4487  #endif  #endif
# Line 4238  switch(type) Line 4517  switch(type)
4517    read_char(common);    read_char(common);
4518    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);
4519    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4520      end_list = NULL;
4521    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4522      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));
4523    else    else
4524      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4525    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4526    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);
4527    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));
4528    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4529    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4530    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4531      set_jumps(end_list, LABEL());
4532    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4533    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4534    return cc;    return cc;
4535    
4536    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 4321  switch(type) Line 4601  switch(type)
4601        {        {
4602        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4603        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4604        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS);
4605        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4606        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4607        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4608        check_partial(common, TRUE);        check_partial(common, TRUE);
4609        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
# Line 4510  switch(type) Line 4790  switch(type)
4790      return cc + length;      return cc + length;
4791      }      }
4792    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4793    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4794    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4795    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4796    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4797    return cc + length;    return cc + length;
4798    
# Line 4726  if (!common->jscript_compat) Line 5006  if (!common->jscript_compat)
5006      {      {
5007      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
5008      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5009      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
5010      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5011      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
5012      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
5013      }      }
5014    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
# Line 4784  if (withchecks && !common->jscript_compa Line 5064  if (withchecks && !common->jscript_compa
5064  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5065  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5066    {    {
5067    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);
5068    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));
5069    if (withchecks)    if (withchecks)
5070      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5071    
5072    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
5073    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5074    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
5075    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
5076    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
5077    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5078    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
# Line 5001  backtrack_common *backtrack; Line 5281  backtrack_common *backtrack;
5281  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5282  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5283  int start = GET(cc, 1);  int start = GET(cc, 1);
5284    pcre_uchar *start_cc;
5285    BOOL needs_control_head;
5286    
5287  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5288    
5289    /* Inlining simple patterns. */
5290    if (get_framesize(common, common->start + start, TRUE, &needs_control_head) == no_stack)
5291      {
5292      start_cc = common->start + start;
5293      compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
5294      BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
5295      return cc + 1 + LINK_SIZE;
5296      }
5297    
5298  while (entry != NULL)  while (entry != NULL)
5299    {    {
5300    if (entry->start == start)    if (entry->start == start)
# Line 5051  add_jump(compiler, &backtrack->topbacktr Line 5343  add_jump(compiler, &backtrack->topbacktr
5343  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5344  }  }
5345    
5346    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5347    {
5348    const pcre_uchar *begin = arguments->begin;
5349    int *offset_vector = arguments->offsets;
5350    int offset_count = arguments->offset_count;
5351    int i;
5352    
5353    if (PUBL(callout) == NULL)
5354      return 0;
5355    
5356    callout_block->version = 2;
5357    callout_block->callout_data = arguments->callout_data;
5358    
5359    /* Offsets in subject. */
5360    callout_block->subject_length = arguments->end - arguments->begin;
5361    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5362    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5363    #if defined COMPILE_PCRE8
5364    callout_block->subject = (PCRE_SPTR)begin;
5365    #elif defined COMPILE_PCRE16
5366    callout_block->subject = (PCRE_SPTR16)begin;
5367    #elif defined COMPILE_PCRE32
5368    callout_block->subject = (PCRE_SPTR32)begin;
5369    #endif
5370    
5371    /* Convert and copy the JIT offset vector to the offset_vector array. */
5372    callout_block->capture_top = 0;
5373    callout_block->offset_vector = offset_vector;
5374    for (i = 2; i < offset_count; i += 2)
5375      {
5376      offset_vector[i] = jit_ovector[i] - begin;
5377      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5378      if (jit_ovector[i] >= begin)
5379        callout_block->capture_top = i;
5380      }
5381    
5382    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5383    if (offset_count > 0)
5384      offset_vector[0] = -1;
5385    if (offset_count > 1)
5386      offset_vector[1] = -1;
5387    return (*PUBL(callout))(callout_block);
5388    }
5389    
5390    /* Aligning to 8 byte. */
5391    #define CALLOUT_ARG_SIZE \
5392        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5393    
5394    #define CALLOUT_ARG_OFFSET(arg) \
5395        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5396    
5397    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5398    {
5399    DEFINE_COMPILER;
5400    backtrack_common *backtrack;
5401    
5402    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5403    
5404    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5405    
5406    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5407    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5408    SLJIT_ASSERT(common->capture_last_ptr != 0);
5409    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5410    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5411    
5412    /* These pointer sized fields temporarly stores internal variables. */
5413    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5414    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5415    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5416    
5417    if (common->mark_ptr != 0)
5418      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5419    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5420    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5421    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5422    
5423    /* Needed to save important temporary registers. */
5424    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5425    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5426    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5427    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5428    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5429    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5430    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5431    
5432    /* Check return value. */
5433    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5434    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5435    if (common->forced_quit_label == NULL)
5436      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5437    else
5438      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5439    return cc + 2 + 2 * LINK_SIZE;
5440    }
5441    
5442    #undef CALLOUT_ARG_SIZE
5443    #undef CALLOUT_ARG_OFFSET
5444    
5445  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5446  {  {
5447  DEFINE_COMPILER;  DEFINE_COMPILER;
5448  int framesize;  int framesize;
5449    int extrasize;
5450    BOOL needs_control_head;
5451  int private_data_ptr;  int private_data_ptr;
5452  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5453  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5064  jump_list *tmp = NULL; Line 5457  jump_list *tmp = NULL;
5457  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5458  jump_list **found;  jump_list **found;
5459  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5460  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
5461  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_accept_label = common->accept_label;
5462  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5463  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5464    BOOL save_local_exit = common->local_exit;
5465  struct sljit_jump *jump;  struct sljit_jump *jump;
5466  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5467    
# Line 5079  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5473  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5473    }    }
5474  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5475  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5476  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE, &needs_control_head);
5477  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5478  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5479  opcode = *cc;  opcode = *cc;
# Line 5098  if (bra == OP_BRAMINZERO) Line 5492  if (bra == OP_BRAMINZERO)
5492    
5493  if (framesize < 0)  if (framesize < 0)
5494    {    {
5495    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5496    allocate_stack(common, 1);    if (framesize == no_frame)
5497        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5498      allocate_stack(common, extrasize);
5499      if (needs_control_head)
5500        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5501    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5502      if (needs_control_head)
5503        {
5504        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5505        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5506        }
5507    }    }
5508  else  else
5509    {    {
5510    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5511      allocate_stack(common, framesize + extrasize);
5512    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);
5513    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));
5514    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);
5515      if (needs_control_head)
5516        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5517    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5518    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5519    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5520        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5521        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5522        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5523        }
5524      else
5525        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5526      init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);
5527    }    }
5528    
5529  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5530  common->quitlabel = NULL;  common->local_exit = TRUE;
5531    common->quit_label = NULL;
5532  common->quit = NULL;  common->quit = NULL;
5533  while (1)  while (1)
5534    {    {
5535    common->acceptlabel = NULL;    common->accept_label = NULL;
5536    common->accept = NULL;    common->accept = NULL;
5537    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5538    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5130  while (1) Line 5544  while (1)
5544    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5545    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5546      {      {
5547      common->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5548      common->acceptlabel = save_acceptlabel;      common->quit_label = save_quit_label;
5549        common->accept_label = save_accept_label;
5550      common->quit = save_quit;      common->quit = save_quit;
5551      common->accept = save_accept;      common->accept = save_accept;
5552      return NULL;      return NULL;
5553      }      }
5554    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5555    if (common->accept != NULL)    if (common->accept != NULL)
5556      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5557    
5558    /* Reset stack. */    /* Reset stack. */
5559    if (framesize < 0)    if (framesize < 0)
5560      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5561    else {      if (framesize == no_frame)
5562          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5563        else
5564          free_stack(common, extrasize);
5565        if (needs_control_head)
5566          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5567        }
5568      else
5569        {
5570      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5571        {        {
5572        /* 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. */
5573        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));
5574          if (needs_control_head)
5575            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5576        }        }
5577      else      else
5578        {        {
5579        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);
5580          if (needs_control_head)
5581            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5582        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5583        }        }
5584    }      }
5585    
5586    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5587      {      {
5588      /* 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. */
5589      if (conditional)      if (conditional)
5590        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);
5591      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5592        {        {
5593        if (framesize < 0)        if (framesize < 0)
5594          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));
5595        else        else
5596          {          {
5597          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));
5598          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));
5599          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);
5600          }          }
5601        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5185  while (1) Line 5612  while (1)
5612    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5613    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5614      {      {
5615      common->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5616      common->acceptlabel = save_acceptlabel;      common->quit_label = save_quit_label;
5617        common->accept_label = save_accept_label;
5618      common->quit = save_quit;      common->quit = save_quit;
5619      common->accept = save_accept;      common->accept = save_accept;
5620      return NULL;      return NULL;
# Line 5199  while (1) Line 5627  while (1)
5627    ccbegin = cc;    ccbegin = cc;
5628    cc += GET(cc, 1);    cc += GET(cc, 1);
5629    }    }
5630    
5631  /* None of them matched. */  /* None of them matched. */
5632  if (common->quit != NULL)  if (common->quit != NULL)
5633      {
5634      jump = JUMP(SLJIT_JUMP);
5635    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5636      SLJIT_ASSERT(framesize != no_stack);
5637      if (framesize < 0)
5638        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5639      else
5640        {
5641        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5642        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5643        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5644        }
5645      JUMPHERE(jump);
5646      }
5647    
5648    if (needs_control_head)
5649      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5650    
5651  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5652    {    {
# Line 5213  if (opcode == OP_ASSERT || opcode == OP_ Line 5658  if (opcode == OP_ASSERT || opcode == OP_
5658      {      {
5659      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5660      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5661          {
5662          if (extrasize == 2)
5663            free_stack(common, 1);
5664        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5665          }
5666      else      else
5667        free_stack(common, 1);        free_stack(common, extrasize);
5668      }      }
5669    else    else
5670      {      {
5671      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5672      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5673      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5674        {        {
5675        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5676        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5677        }        }
5678      else      else
5679        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5680      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);
5681      }      }
5682    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5239  if (opcode == OP_ASSERT || opcode == OP_ Line 5688  if (opcode == OP_ASSERT || opcode == OP_
5688    if (framesize < 0)    if (framesize < 0)
5689      {      {
5690      /* 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. */
5691      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));
5692      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5693      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5694          {
5695        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));
5696          if (extrasize == 2)
5697            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5698          }
5699      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5700        {        {
5701        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 5255  if (opcode == OP_ASSERT || opcode == OP_ Line 5708  if (opcode == OP_ASSERT || opcode == OP_
5708        {        {
5709        /* 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. */
5710        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));
5711        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));
5712        }        }
5713      else      else
5714        {        {
5715        /* 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. */
5716        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));
5717        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5718        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5719            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5720            if (bra == OP_BRAMINZERO)
5721              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5722            }
5723          else
5724            {
5725            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5726            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5727            }
5728        }        }
5729      }      }
5730    
5731    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5732      {      {
5733      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5734      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5735      }      }
5736    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5737      {      {
# Line 5291  else Line 5753  else
5753      {      {
5754      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5755      if (bra != OP_BRA)      if (bra != OP_BRA)
5756          {
5757          if (extrasize == 2)
5758            free_stack(common, 1);
5759        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5760          }
5761      else      else
5762        free_stack(common, 1);        free_stack(common, extrasize);
5763      }      }
5764    else    else
5765      {      {
5766      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5767      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5768      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5769      if (bra != OP_BRA)      if (bra != OP_BRA)
5770        {        {
5771        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5772        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5773        }        }
5774      else      else
5775        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5776      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);
5777      }      }
5778    
# Line 5326  else Line 5792  else
5792      }      }
5793    }    }
5794    
5795  common->quitlabel = save_quitlabel;  common->local_exit = save_local_exit;
5796  common->acceptlabel = save_acceptlabel;  common->quit_label = save_quit_label;
5797    common->accept_label = save_accept_label;
5798  common->quit = save_quit;  common->quit = save_quit;
5799  common->accept = save_accept;  common->accept = save_accept;
5800  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
# Line 5443  if (i < name_count) Line 5910  if (i < name_count)
5910  return condition;  return condition;
5911  }  }
5912    
5913    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)
5914    {
5915    DEFINE_COMPILER;
5916    int stacksize;
5917    
5918    if (framesize < 0)
5919      {
5920      if (framesize == no_frame)
5921        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5922      else
5923        {
5924        stacksize = needs_control_head ? 1 : 0;
5925        if (ket != OP_KET || has_alternatives)
5926          stacksize++;
5927        free_stack(common, stacksize);
5928        }
5929    
5930      if (needs_control_head)
5931        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (ket != OP_KET || has_alternatives) ? sizeof(sljit_sw) : 0);
5932    
5933      /* TMP2 which is set here used by OP_KETRMAX below. */
5934      if (ket == OP_KETRMAX)
5935        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5936      else if (ket == OP_KETRMIN)
5937        {
5938        /* Move the STR_PTR to the private_data_ptr. */
5939        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5940        }
5941      }
5942    else
5943      {
5944      stacksize = (ket != OP_KET || has_alternatives) ? 2 : 1;
5945      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + stacksize) * sizeof(sljit_sw));
5946      if (needs_control_head)
5947        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 0);
5948    
5949      if (ket == OP_KETRMAX)
5950        {
5951        /* TMP2 which is set here used by OP_KETRMAX below. */
5952        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5953        }
5954      }
5955    if (needs_control_head)
5956      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
5957    }
5958    
5959    static SLJIT_INLINE int match_capture_common(compiler_common *common, int stacksize, int offset, int private_data_ptr)
5960    {
5961    DEFINE_COMPILER;
5962    
5963    if (common->capture_last_ptr != 0)
5964      {
5965      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5966      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
5967      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
5968      stacksize++;
5969      }
5970    if (common->optimized_cbracket[offset >> 1] == 0)
5971      {
5972      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5973      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5974      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
5975      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5976      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
5977      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5978      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5979      stacksize += 2;
5980      }
5981    return stacksize;
5982    }
5983    
5984  /*  /*
5985    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
5986    
# Line 5511  pcre_uchar bra = OP_BRA; Line 6049  pcre_uchar bra = OP_BRA;
6049  pcre_uchar ket;  pcre_uchar ket;
6050  assert_backtrack *assert;  assert_backtrack *assert;
6051  BOOL has_alternatives;  BOOL has_alternatives;
6052    BOOL needs_control_head = FALSE;
6053  struct sljit_jump *jump;  struct sljit_jump *jump;
6054  struct sljit_jump *skip;  struct sljit_jump *skip;
6055  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
# Line 5586  else if (opcode == OP_ONCE || opcode == Line 6125  else if (opcode == OP_ONCE || opcode ==
6125    SLJIT_ASSERT(private_data_ptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
6126    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
6127    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
6128      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE, &needs_control_head);
6129    }    }
6130    
6131  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
6132  stacksize = 0;  stacksize = 0;
6133  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6134    stacksize++;    stacksize++;
6135  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
6136    stacksize++;    stacksize++;
# Line 5600  if (stacksize > 0) Line 6139  if (stacksize > 0)
6139    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6140    
6141  stacksize = 0;  stacksize = 0;
6142  if ((ket == OP_KETRMAX) || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))  if (ket == OP_KETRMAX || (ket == OP_KETRMIN && bra != OP_BRAMINZERO))
6143    {    {
6144    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6145    stacksize++;    stacksize++;
# Line 5663  if (ket == OP_KETRMAX) Line 6202  if (ket == OP_KETRMAX)
6202  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
6203  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6204    {    {
6205      stacksize = 0;
6206      if (needs_control_head)
6207        {
6208        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6209        stacksize++;
6210        }
6211    
6212    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
6213      {      {
6214      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are found in the block. */
6215      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
6216        {        {
6217        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        stacksize += 2;
6218        allocate_stack(common, 2);        if (!needs_control_head)
6219        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));  
6220        }        }
6221      else if (ket == OP_KETRMAX || has_alternatives)      else
6222        {        {
6223        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);        if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6224        allocate_stack(common, 1);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6225        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        if (ket == OP_KETRMAX || has_alternatives)
6226            stacksize++;
6227        }        }
6228      else  
6229        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);      if (stacksize > 0)
6230          allocate_stack(common, stacksize);
6231    
6232        stacksize = 0;
6233        if (needs_control_head)
6234          {
6235          stacksize++;
6236          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6237          }
6238    
6239        if (ket == OP_KETRMIN)
6240          {
6241          if (needs_control_head)
6242            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6243          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6244          if (BACKTRACK_AS(bracket_backtrack)->u.framesize == no_frame)
6245            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));
6246          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6247          }
6248        else if (ket == OP_KETRMAX || has_alternatives)
6249          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6250      }      }
6251    else    else
6252      {      {
6253      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket != OP_KET || has_alternatives)
6254          stacksize++;
6255    
6256        stacksize += BACKTRACK_AS(bracket_backtrack)->u.framesize + 1;
6257        allocate_stack(common, stacksize);
6258    
6259        if (needs_control_head)
6260          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6261    
6262        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6263        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, stacksize * sizeof(sljit_sw));
6264    
6265        stacksize = needs_control_head ? 1 : 0;
6266        if (ket != OP_KET || has_alternatives)
6267        {        {
6268        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);  
6269        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);
6270        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        stacksize++;
6271        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6272        }        }
6273      else      else
6274        {        {
       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));  
6275        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);
6276        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);  
6277        }        }
6278        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize, stacksize + 1, FALSE);
6279      }      }
6280    }    }
6281  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
6282    {    {
6283    /* Saving the previous values. */    /* Saving the previous values. */
6284    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
     {  
     allocate_stack(common, 3);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);  
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);  
     }  
   else  
6285      {      {
6286      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
6287      allocate_stack(common, 2);      allocate_stack(common, 2);
# Line 5730  else if (opcode == OP_CBRA || opcode == Line 6291  else if (opcode == OP_CBRA || opcode ==
6291      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6292      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6293      }      }
6294      else
6295        {
6296        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6297        allocate_stack(common, 1);
6298        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
6299        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6300        }
6301    }    }
6302  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
6303    {    {
# Line 5765  if (opcode == OP_COND || opcode == OP_SC Line 6333  if (opcode == OP_COND || opcode == OP_SC
6333      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
6334      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
6335      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
6336      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_sw)));
6337      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);
6338      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);
6339      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
6340      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
6341      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));
6342    
6343      JUMPHERE(jump);      JUMPHERE(jump);
6344      matchingpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
# Line 5815  if (opcode == OP_COND || opcode == OP_SC Line 6383  if (opcode == OP_COND || opcode == OP_SC
6383        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
6384        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
6385        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
6386        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, stacksize);
6387        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);        GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, 0);
6388        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, common->name_table);
6389        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
6390        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
6391        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG1, 0, SLJIT_IMM, 0));
6392        matchingpath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
6393        }        }
6394      }      }
# Line 5843  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6411  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6411    return NULL;    return NULL;
6412    
6413  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
6414    {    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));  
       }  
     }  
   }  
6415    
6416  stacksize = 0;  stacksize = 0;
6417  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6418    stacksize++;    stacksize++;
6419    if (offset != 0)
6420      {
6421      if (common->capture_last_ptr != 0)
6422        stacksize++;
6423      if (common->optimized_cbracket[offset >> 1] == 0)
6424        stacksize += 2;
6425      }
6426  if (has_alternatives && opcode != OP_ONCE)  if (has_alternatives && opcode != OP_ONCE)
6427    stacksize++;    stacksize++;
6428    
# Line 5878  if (stacksize > 0) Line 6430  if (stacksize > 0)
6430    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6431    
6432  stacksize = 0;  stacksize = 0;
6433  if (ket != OP_KET)  if (ket != OP_KET || bra != OP_BRA)
   {  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);  
   stacksize++;  
   }  
 else if (bra != OP_BRA)  
6434    {    {
6435    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    if (ket != OP_KET)
6436        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6437      else
6438        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6439    stacksize++;    stacksize++;
6440    }    }
6441    
6442    if (offset != 0)
6443      stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
6444    
6445  if (has_alternatives)  if (has_alternatives)
6446    {    {
6447    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
# Line 5898  if (has_alternatives) Line 6451  if (has_alternatives)
6451    }    }
6452    
6453  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
6454  if (offset != 0)  if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
6455    {    {
6456    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
6457    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);  
6458    }    }
6459    
6460  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
# Line 5959  if ((ket != OP_KET && bra != OP_BRAMINZE Line 6511  if ((ket != OP_KET && bra != OP_BRAMINZE
6511  while (*cc == OP_ALT)  while (*cc == OP_ALT)
6512    cc += GET(cc, 1);    cc += GET(cc, 1);
6513  cc += 1 + LINK_SIZE;  cc += 1 + LINK_SIZE;
6514    
6515    /* Temporarily encoding the needs_control_head in framesize. */
6516    if (opcode == OP_ONCE)
6517      BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0);
6518  return cc;  return cc;
6519  }  }
6520    
# Line 5969  backtrack_common *backtrack; Line 6525  backtrack_common *backtrack;
6525  pcre_uchar opcode;  pcre_uchar opcode;
6526  int private_data_ptr;  int private_data_ptr;
6527  int cbraprivptr = 0;  int cbraprivptr = 0;
6528    BOOL needs_control_head;
6529  int framesize;  int framesize;
6530  int stacksize;  int stacksize;
6531  int offset = 0;  int offset = 0;
6532  BOOL zero = FALSE;  BOOL zero = FALSE;
6533  pcre_uchar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
6534  int stack;  int stack; /* Also contains the offset of control head. */
6535  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
6536  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
6537    
# Line 6012  switch(opcode) Line 6569  switch(opcode)
6569    break;    break;
6570    }    }
6571    
6572  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE, &needs_control_head);
6573  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6574  if (framesize < 0)  if (framesize < 0)
6575    {    {
6576    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    if (offset != 0)
6577        {
6578        stacksize = 2;
6579        if (common->capture_last_ptr != 0)
6580          stacksize++;
6581        }
6582      else
6583        stacksize = 1;
6584    
6585      if (needs_control_head)
6586        stacksize++;
6587    if (!zero)    if (!zero)
6588      stacksize++;      stacksize++;
6589    
6590    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6591    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6592    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    if (framesize == no_frame)
6593        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6594    
6595    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    stack = 0;
6596      if (offset != 0)
6597      {      {
6598        stack = 2;
6599      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6600      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));
6601      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6602        if (common->capture_last_ptr != 0)
6603          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6604      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6605        if (needs_control_head)
6606          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6607        if (common->capture_last_ptr != 0)
6608          {
6609          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6610          stack = 3;
6611          }
6612      }      }
6613    else    else
6614        {
6615        if (needs_control_head)
6616          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
6617      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6618        stack = 1;
6619        }
6620    
6621      if (needs_control_head)
6622        stack++;
6623    if (!zero)    if (!zero)
6624      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);
6625      if (needs_control_head)
6626        {
6627        stack--;
6628        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6629        }
6630    }    }
6631  else  else
6632    {    {
6633    stacksize = framesize + 1;    stacksize = framesize + 1;
6634    if (!zero)    if (!zero)
6635      stacksize++;      stacksize++;
6636    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (needs_control_head)
6637        stacksize++;
6638      if (offset == 0)
6639      stacksize++;      stacksize++;
6640    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
   allocate_stack(common, stacksize);  
6641    
6642      allocate_stack(common, stacksize);
6643    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);
6644    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    if (needs_control_head)
6645    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);
6646      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6647    
6648    stack = 0;    stack = 0;
6649    if (!zero)    if (!zero)
6650      {      {
6651      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 1);
6652        stack = 1;
6653        }
6654      if (needs_control_head)
6655        {
6656        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP2, 0);
6657      stack++;      stack++;
6658      }      }
6659    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (offset == 0)
6660      {      {
6661      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), STR_PTR, 0);
6662      stack++;      stack++;
6663      }      }
6664    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stack), TMP1, 0);
6665    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
6666      stack -= 1 + (offset == 0);
6667    }    }
6668    
6669  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)  if (offset != 0)
6670    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6671    
6672  loop = LABEL();  loop = LABEL();
# Line 6080  while (*cc != OP_KETRPOS) Line 6682  while (*cc != OP_KETRPOS)
6682    
6683    if (framesize < 0)    if (framesize < 0)
6684      {      {
6685      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      if (framesize == no_frame)
6686          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6687    
6688      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6689        {        {
6690        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6691        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);
6692        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6693          if (common->capture_last_ptr != 0)
6694            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6695        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6696        }        }
6697      else      else
# Line 6104  while (*cc != OP_KETRPOS) Line 6709  while (*cc != OP_KETRPOS)
6709      }      }
6710    else    else
6711      {      {
6712      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6713        {        {
6714        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));
6715        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6716        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);
6717        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6718          if (common->capture_last_ptr != 0)
6719            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6720        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6721        }        }
6722      else      else
# Line 6132  while (*cc != OP_KETRPOS) Line 6739  while (*cc != OP_KETRPOS)
6739          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6740        }        }
6741      }      }
6742    
6743      if (needs_control_head)
6744        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(stack));
6745    
6746    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6747    flush_stubs(common);    flush_stubs(common);
6748    
# Line 6142  while (*cc != OP_KETRPOS) Line 6753  while (*cc != OP_KETRPOS)
6753    
6754    if (framesize < 0)    if (framesize < 0)
6755      {      {
6756      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6757        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6758      else      else
6759        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6760      }      }
6761    else    else
6762      {      {
6763      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6764        {        {
6765        /* Last alternative. */        /* Last alternative. */
6766        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
# Line 6168  while (*cc != OP_KETRPOS) Line 6779  while (*cc != OP_KETRPOS)
6779    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6780    }    }
6781    
6782    /* We don't have to restore the control head in case of a failed match. */
6783    
6784  backtrack->topbacktracks = NULL;  backtrack->topbacktracks = NULL;
6785  if (!zero)  if (!zero)
6786    {    {
# Line 6296  PUSH_BACKTRACK(sizeof(iterator_backtrack Line 6909  PUSH_BACKTRACK(sizeof(iterator_backtrack
6909    
6910  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6911    
6912  switch (type)  switch(type)
6913    {    {
6914    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
6915    case OP_DIGIT:    case OP_DIGIT:
# Line 6498  static SLJIT_INLINE pcre_uchar *compile_ Line 7111  static SLJIT_INLINE pcre_uchar *compile_
7111  DEFINE_COMPILER;  DEFINE_COMPILER;
7112  backtrack_common *backtrack;  backtrack_common *backtrack;
7113    
7114  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
7115    
7116  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
7117    {    {
# Line 6509  if (*cc == OP_FAIL) Line 7122  if (*cc == OP_FAIL)
7122  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
7123    {    {
7124    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
7125    if (common->acceptlabel == NULL)    if (common->accept_label == NULL)
7126      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
7127    else    else
7128      JUMPTO(SLJIT_JUMP, common->acceptlabel);      JUMPTO(SLJIT_JUMP, common->accept_label);
7129    return cc + 1;    return cc + 1;
7130    }    }
7131    
7132  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
7133    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0)));
7134  else  else
7135    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), common->accept_label);
7136  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7137  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));
7138  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
7139  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));
7140  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
7141    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0));
7142  else  else
7143    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
7144  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));
7145  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
7146    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));    add_jump(compiler, &common->accept, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0));
7147  else  else
7148    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->acceptlabel);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, common->accept_label);
7149  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
7150  return cc + 1;  return cc + 1;
7151  }  }
# Line 6712  while (cc < ccend) Line 7325  while (cc < ccend)
7325      cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
7326      break;      break;
7327    
7328        case OP_CALLOUT:
7329        cc = compile_callout_matchingpath(common, cc, parent);
7330        break;
7331    
7332      case OP_ASSERT:      case OP_ASSERT:
7333      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7334      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 6772  while (cc < ccend) Line 7389  while (cc < ccend)
7389      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7390      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
7391      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);
7392      allocate_stack(common, 1);      allocate_stack(common, common->has_skip_arg ? 5 : 1);
7393      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);      OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7394      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);
7395      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7396      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);
7397      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);
7398        if (common->has_skip_arg)
7399          {
7400          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7401          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7402          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, type_mark);
7403          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), SLJIT_IMM, (sljit_sw)(cc + 2));
7404          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), STR_PTR, 0);
7405          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
7406          }
7407      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7408      break;      break;
7409    
7410        case OP_PRUNE_ARG:
7411        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7412        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7413        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7414        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7415        /* Fall through. */
7416    
7417        case OP_PRUNE:
7418      case OP_COMMIT:      case OP_COMMIT:
7419      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7420      cc += 1;      SLJIT_ASSERT(common->control_head_ptr != 0);
7421        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7422        allocate_stack(common, 2);
7423        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7424        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_COMMIT ? type_commit : type_prune);
7425        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7426        cc += (*cc == OP_PRUNE_ARG) ? (1 + 2 + cc[1]) : 1;
7427        break;
7428    
7429        case OP_SKIP:
7430        case OP_SKIP_ARG:
7431        PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7432        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
7433        allocate_stack(common, 3);
7434        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, STACK_TOP, 0);
7435        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, *cc == OP_SKIP ? type_skip : type_skip_arg);
7436        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), *cc == OP_SKIP ? STR_PTR : SLJIT_IMM, *cc == OP_SKIP ? 0 : (sljit_sw)(cc + 2));
7437        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
7438        cc += (*cc == OP_SKIP_ARG) ? (1 + 2 + cc[1]) : 1;
7439      break;      break;
7440    
7441      case OP_FAIL:      case OP_FAIL:
# Line 6994  static void compile_recurse_backtracking Line 7646  static void compile_recurse_backtracking
7646  {  {
7647  DEFINE_COMPILER;  DEFINE_COMPILER;
7648    
7649    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7650      compile_backtrackingpath(common, current->top);
7651  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
7652    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7653      return;
7654    
7655  if (common->has_set_som && common->mark_ptr != 0)  if (common->has_set_som && common->mark_ptr != 0)
7656    {    {
# Line 7096  pcre_uchar bra = OP_BRA; Line 7752  pcre_uchar bra = OP_BRA;
7752  pcre_uchar ket;  pcre_uchar ket;
7753  assert_backtrack *assert;  assert_backtrack *assert;
7754  BOOL has_alternatives;  BOOL has_alternatives;
7755    BOOL needs_control_head = FALSE;
7756  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
7757  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
7758  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 7121  if (SLJIT_UNLIKELY(opcode == OP_COND) && Line 7778  if (SLJIT_UNLIKELY(opcode == OP_COND) &&
7778  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
7779    opcode = OP_ONCE;    opcode = OP_ONCE;
7780    
7781    /* Decoding the needs_control_head in framesize. */
7782    if (opcode == OP_ONCE)
7783      {
7784      needs_control_head = (CURRENT_AS(bracket_backtrack)->u.framesize & 0x1) != 0;
7785      CURRENT_AS(bracket_backtrack)->u.framesize >>= 1;
7786      }
7787    
7788  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
7789    {    {
7790    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 7160  else if (bra == OP_BRAZERO) Line 7824  else if (bra == OP_BRAZERO)
7824    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
7825    }    }
7826    
7827    if (offset != 0)
7828      {
7829      if (common->capture_last_ptr != 0)
7830        {
7831        SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
7832        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7833        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7834        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7835        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7836        free_stack(common, 3);
7837        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
7838        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
7839        }
7840      else if (common->optimized_cbracket[offset >> 1] == 0)
7841        {
7842        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7843        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7844        free_stack(common, 2);
7845        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7846        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7847        }
7848      }
7849    
7850  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7851    {    {
7852    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7255  if (has_alternatives) Line 7942  if (has_alternatives)
7942      current->top = NULL;      current->top = NULL;
7943      current->topbacktracks = NULL;      current->topbacktracks = NULL;
7944      current->nextbacktracks = NULL;      current->nextbacktracks = NULL;
7945        /* Conditional blocks always have an additional alternative, even if it is empty. */
7946      if (*cc == OP_ALT)      if (*cc == OP_ALT)
7947        {        {
7948        ccprev = cc + 1 + LINK_SIZE;        ccprev = cc + 1 + LINK_SIZE;
7949        cc += GET(cc, 1);        cc += GET(cc, 1);
7950        if (opcode != OP_COND && opcode != OP_SCOND)        if (opcode != OP_COND && opcode != OP_SCOND)
7951          {          {
7952          if (private_data_ptr != 0 && opcode != OP_ONCE)          if (opcode != OP_ONCE)
7953            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);            {
7954              if (private_data_ptr != 0)
7955                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7956              else
7957                OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7958              }
7959          else          else
7960            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));
7961          }          }
7962        compile_matchingpath(common, ccprev, cc, current);        compile_matchingpath(common, ccprev, cc, current);
7963        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))        if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 7274  if (has_alternatives) Line 7967  if (has_alternatives)
7967      /* Instructions after the current alternative is succesfully matched. */      /* Instructions after the current alternative is succesfully matched. */
7968      /* There is a similar code in compile_bracket_matchingpath. */      /* There is a similar code in compile_bracket_matchingpath. */
7969      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
7970        {        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));  
           }  
         }  
       }  
7971    
7972      stacksize = 0;      stacksize = 0;
     if (opcode != OP_ONCE)  
       stacksize++;  
7973      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
7974        stacksize++;        stacksize++;
7975        if (offset != 0)
7976          {
7977          if (common->capture_last_ptr != 0)
7978            stacksize++;
7979          if (common->optimized_cbracket[offset >> 1] == 0)
7980            stacksize += 2;
7981          }
7982        if (opcode != OP_ONCE)
7983          stacksize++;
7984    
7985      if (stacksize > 0) {      if (stacksize > 0)
7986          {
7987        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
7988          allocate_stack(common, stacksize);          allocate_stack(common, stacksize);
7989        else        else
# Line 7313  if (has_alternatives) Line 7992  if (has_alternatives)
7992          SLJIT_ASSERT(stacksize == 1);          SLJIT_ASSERT(stacksize == 1);
7993          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));
7994          }          }
7995      }        }
7996    
7997      stacksize = 0;      stacksize = 0;
7998      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
# Line 7325  if (has_alternatives) Line 8004  if (has_alternatives)
8004        stacksize++;        stacksize++;
8005        }        }
8006    
8007        if (offset != 0)
8008          stacksize = match_capture_common(common, stacksize, offset, private_data_ptr);
8009    
8010      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
8011        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
8012    
8013      if (offset != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
8014        {        {
8015        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        /* If ket is not OP_KETRMAX, this code path is executed after the jump to alternative_matchingpath. */
8016          SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
8017        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);  
8018        }        }
8019    
8020      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
# Line 7357  if (has_alternatives) Line 8039  if (has_alternatives)
8039      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
8040      assert = CURRENT_AS(bracket_backtrack)->u.assert;      assert = CURRENT_AS(bracket_backtrack)->u.assert;
8041      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)
   
8042        {        {
8043        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);
8044        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7374  if (has_alternatives) Line 8055  if (has_alternatives)
8055  if (offset != 0)  if (offset != 0)
8056    {    {
8057    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
8058    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
8059      {      {
8060      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8061      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8062        free_stack(common, 2);
8063      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
     free_stack(common, 3);  
8064      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);  
8065      }      }
8066    else    else
8067      {      {
8068      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8069      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      free_stack(common, 1);
8070      free_stack(common, 2);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);  
8071      }      }
8072    }    }
8073  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
# Line 7401  else if (opcode == OP_SBRA || opcode == Line 8078  else if (opcode == OP_SBRA || opcode ==
8078  else if (opcode == OP_ONCE)  else if (opcode == OP_ONCE)
8079    {    {
8080    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
8081      stacksize = needs_control_head ? 1 : 0;
8082    
8083    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
8084      {      {
8085      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
8086      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);  
8087      }      }
8088    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
8089      {      {
8090      /* The STR_PTR must be released. */      /* The STR_PTR must be released. */
8091      free_stack(common, 1);      stacksize++;
8092      }      }
8093      free_stack(common, stacksize);
8094    
8095    JUMPHERE(once);    JUMPHERE(once);
8096    /* Restore previous private_data_ptr */    /* Restore previous private_data_ptr */
# Line 7477  if (CURRENT_AS(bracketpos_backtrack)->fr Line 8156  if (CURRENT_AS(bracketpos_backtrack)->fr
8156      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8157      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
8158      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
8159        if (common->capture_last_ptr != 0)
8160          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
8161      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);
8162        if (common->capture_last_ptr != 0)
8163          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
8164      }      }
8165    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
8166    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
# Line 7658  while (current) Line 8341  while (current)
8341      break;      break;
8342    
8343      case OP_MARK:      case OP_MARK:
8344      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));
8345      free_stack(common, 1);      if (common->has_skip_arg)
8346          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8347        free_stack(common, common->has_skip_arg ? 5 : 1);
8348      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);
8349        if (common->has_skip_arg)
8350          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8351        break;
8352    
8353        case OP_PRUNE:
8354        case OP_PRUNE_ARG:
8355        case OP_SKIP:
8356        if (!common->local_exit)
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          sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8362          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8363    
8364          OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8365          add_jump(compiler, &common->reset_match, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8366    
8367          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8368          }
8369    
8370        /* Commit or in recurse or accept. */
8371        if (common->quit_label == NULL)
8372          add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8373        else
8374          JUMPTO(SLJIT_JUMP, common->quit_label);
8375        break;
8376    
8377        case OP_SKIP_ARG:
8378        if (!common->local_exit)
8379          {
8380          SLJIT_ASSERT(common->control_head_ptr != 0);
8381          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
8382          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
8383          sljit_emit_ijump(compiler, SLJIT_CALL1, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_check_control_chain));
8384          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
8385    
8386          OP1(SLJIT_MOV, STR_PTR, 0, TMP1, 0);
8387          add_jump(compiler, &common->reset_match, CMP(SLJIT_C_LESS, STR_PTR, 0, SLJIT_IMM, -2));
8388    
8389          /* May not find suitable mark. */
8390          OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8391          if (common->quit_label == NULL)
8392            add_jump(compiler, &common->quit, CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1));
8393          else
8394            CMPTO(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, -1, common->quit_label);
8395    
8396          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
8397          free_stack(common, 3);
8398          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP1, 0);
8399          }
8400        else
8401          {
8402          /* In recurse or accept. */
8403          if (common->quit_label == NULL)
8404            add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8405          else
8406            JUMPTO(SLJIT_JUMP, common->quit_label);
8407          }
8408      break;      break;
8409    
8410      case OP_COMMIT:      case OP_COMMIT:
8411      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      if (!common->local_exit)
8412      if (common->quitlabel == NULL)        OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8413        if (common->quit_label == NULL)
8414        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8415      else      else
8416        JUMPTO(SLJIT_JUMP, common->quitlabel);        JUMPTO(SLJIT_JUMP, common->quit_label);
8417      break;      break;
8418    
8419        case OP_CALLOUT:
8420      case OP_FAIL:      case OP_FAIL:
8421      case OP_ACCEPT:      case OP_ACCEPT:
8422      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 7691  DEFINE_COMPILER; Line 8437  DEFINE_COMPILER;
8437  pcre_uchar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
8438  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);
8439  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
8440  int private_data_size = get_private_data_length_for_copy(common, ccbegin, ccend);  BOOL needs_control_head;
8441  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE, &needs_control_head);
8442    int private_data_size = get_private_data_copy_length(common, ccbegin, ccend, needs_control_head);
8443  int alternativesize;  int alternativesize;
8444  BOOL needsframe;  BOOL needs_frame;
8445  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quitlabel = common->quitlabel;  
 jump_list *save_quit = common->quit;  
8446  struct sljit_jump *jump;  struct sljit_jump *jump;
8447    
8448  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);
8449  needsframe = framesize >= 0;  needs_frame = framesize >= 0;
8450  if (!needsframe)  if (!needs_frame)
8451    framesize = 0;    framesize = 0;
8452  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8453    
8454  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
8455  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
8456  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
8457    
8458  sljit_emit_fast_enter(compiler, TMP2, 0);  sljit_emit_fast_enter(compiler, TMP2, 0);
8459  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8460  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);
8461  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);
8462  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  if (needs_control_head)
8463  if (needsframe)    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
8464    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8465    if (needs_frame)
8466    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
8467    
8468  if (alternativesize > 0)  if (alternativesize > 0)
8469    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8470    
8471  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
8472  common->quitlabel = NULL;  common->quit_label = NULL;
8473  common->acceptlabel = NULL;  common->accept_label = NULL;
8474  common->quit = NULL;  common->quit = NULL;
8475  common->accept = NULL;  common->accept = NULL;
8476  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
# Line 7738  while (1) Line 8485  while (1)
8485    
8486    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8487    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quitlabel = save_quitlabel;  
     common->quit = save_quit;  
8488      return;      return;
     }  
8489    
8490    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8491    
8492    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8493    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quitlabel = save_quitlabel;  
     common->quit = save_quit;  
8494      return;      return;
     }  
8495    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8496    
8497    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 7761  while (1) Line 8500  while (1)
8500    altbacktrack.cc = cc + 1 + LINK_SIZE;    altbacktrack.cc = cc + 1 + LINK_SIZE;
8501    cc += GET(cc, 1);    cc += GET(cc, 1);
8502    }    }
 /* None of them matched. */  
 if (common->quit != NULL)  
   set_jumps(common->quit, LABEL());  
8503    
8504    /* None of them matched. */
8505  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8506  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8507    
8508    if (common->quit != NULL)
8509      {
8510      set_jumps(common->quit, LABEL());
8511      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8512      if (needs_frame)
8513        {
8514        OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8515        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
8516        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_sw));
8517        }
8518      OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8519      common->quit = NULL;
8520      add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8521      }
8522    
8523  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8524  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr);
8525  if (needsframe)  if (needs_frame)
8526    {    {
8527    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));
8528    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 7779  if (needsframe) Line 8531  if (needsframe)
8531  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
8532    
8533  JUMPHERE(jump);  JUMPHERE(jump);
8534  copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize);  if (common->quit != NULL)
8535      set_jumps(common->quit, LABEL());
8536    copy_private_data(common, ccbegin, ccend, FALSE, private_data_size + framesize + alternativesize, framesize + alternativesize, needs_control_head);
8537  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8538  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  if (needs_control_head)
8539  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    {
8540  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), 2 * sizeof(sljit_sw));
8541      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8542      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP1, 0);
8543      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8544      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, TMP2, 0);
8545      }
8546    else
8547      {
8548      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8549      OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8550      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8551      }
8552  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
   
 common->quitlabel = save_quitlabel;  
 common->quit = save_quit;  
8553  }  }
8554    
8555  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 7807  pcre_uchar *ccend; Line 8569  pcre_uchar *ccend;
8569  executable_functions *functions;  executable_functions *functions;
8570  void *executable_func;  void *executable_func;
8571  sljit_uw executable_size;  sljit_uw executable_size;
8572  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop_label = NULL;
8573  struct sljit_label *empty_match_found;  struct sljit_label *continue_match_label;
8574  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_found_label;
8575    struct sljit_label *empty_match_backtrack_label;
8576    struct sljit_label *reset_match_label;
8577  struct sljit_jump *jump;  struct sljit_jump *jump;
8578    struct sljit_jump *minlength_check_failed = NULL;
8579  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8580  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8581    struct sljit_label *quit_label;
8582    
8583  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8584  study = extra->study_data;  study = extra->study_data;
# Line 7881  common->ovector_start = CALL_LIMIT + siz Line 8647  common->ovector_start = CALL_LIMIT + siz
8647  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8648  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8649    return;    return;
8650    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
8651    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8652    #else
8653  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
8654    #endif
8655    
8656  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
8657    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
8658    common->capture_last_ptr = common->ovector_start;
8659    common->ovector_start += sizeof(sljit_sw);
8660    #endif
8661  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
8662  if (private_data_size < 0)  if (private_data_size < 0)