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

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

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

revision 1221 by ph10, Sun Nov 11 20:27:03 2012 UTC revision 1272 by zherczeg, Thu Mar 7 11:30:01 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  /* Allocate memory for the regex stack on the real machine stack.  /* Allocate memory for the regex stack on the real machine stack.
75  Fast, but limited size. */  Fast, but limited size. */
76  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 157  typedef struct jit_arguments { Line 163  typedef struct jit_arguments {
163    int *offsets;    int *offsets;
164    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
165    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
166      void *callout_data;
167    /* Everything else after. */    /* Everything else after. */
168    int offsetcount;    int real_offset_count;
169    int calllimit;    int offset_count;
170      int call_limit;
171    pcre_uint8 notbol;    pcre_uint8 notbol;
172    pcre_uint8 noteol;    pcre_uint8 noteol;
173    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 179  typedef struct jump_list { Line 187  typedef struct jump_list {
187    struct jump_list *next;    struct jump_list *next;
188  } jump_list;  } jump_list;
189    
 enum stub_types { stack_alloc };  
   
190  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   int data;  
191    struct sljit_jump *start;    struct sljit_jump *start;
192    struct sljit_label *quit;    struct sljit_label *quit;
193    struct stub_list *next;    struct stub_list *next;
194  } stub_list;  } stub_list;
195    
196    enum frame_types { no_frame = -1, no_stack = -2 };
197    
198  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
199    
200  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
# Line 270  typedef struct recurse_entry { Line 276  typedef struct recurse_entry {
276    
277  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
278    backtrack_common common;    backtrack_common common;
279      BOOL inlined_pattern;
280  } recurse_backtrack;  } recurse_backtrack;
281    
282  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
283    
284  typedef struct compiler_common {  typedef struct compiler_common {
285      /* The sljit ceneric compiler. */
286    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
287      /* First byte code. */
288    pcre_uchar *start;    pcre_uchar *start;
   
289    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
290    int *private_data_ptrs;    int *private_data_ptrs;
291    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
292    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
293    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
294    int cbraptr;    int cbra_ptr;
295    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
296    int ovector_start;    int ovector_start;
297    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
298    int req_char_ptr;    int req_char_ptr;
299    /* Head of the last recursion. */    /* Head of the last recursion. */
300    int recursive_head;    int recursive_head_ptr;
301    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
302    int start_used_ptr;    int start_used_ptr;
303    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 298  typedef struct compiler_common { Line 306  typedef struct compiler_common {
306    int first_line_end;    int first_line_end;
307    /* Points to the marked string. */    /* Points to the marked string. */
308    int mark_ptr;    int mark_ptr;
309      /* Points to the last matched capture block index. */
310      int capture_last_ptr;
311      /* Points to the starting position of the current match. */
312      int start_ptr;
313    
314    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
315    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
316    sljit_sw lcc;    sljit_sw lcc;
317    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
318    int mode;    int mode;
319      /* \K is in the pattern. */
320      BOOL has_set_som;
321      /* Needs to know the start position anytime. */
322      BOOL needs_start_ptr;
323      /* Currently in compile_recurse. */
324      BOOL in_recurse;
325    /* Newline control. */    /* Newline control. */
326    int nltype;    int nltype;
327    int newline;    int newline;
328    int bsr_nltype;    int bsr_nltype;
329    /* Dollar endonly. */    /* Dollar endonly. */
330    int endonly;    int endonly;
   BOOL has_set_som;  
331    /* Tables. */    /* Tables. */
332    sljit_sw ctypes;    sljit_sw ctypes;
333    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
# Line 321  typedef struct compiler_common { Line 338  typedef struct compiler_common {
338    
339    /* Labels and jump lists. */    /* Labels and jump lists. */
340    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
341    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
342    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
343      struct sljit_label *accept_label;
344    stub_list *stubs;    stub_list *stubs;
345    recurse_entry *entries;    recurse_entry *entries;
346    recurse_entry *currententry;    recurse_entry *currententry;
347    jump_list *partialmatch;    jump_list *partialmatch;
348    jump_list *quit;    jump_list *quit;
349      jump_list *forced_quit;
350    jump_list *accept;    jump_list *accept;
351    jump_list *calllimit;    jump_list *calllimit;
352    jump_list *stackalloc;    jump_list *stackalloc;
# Line 338  typedef struct compiler_common { Line 357  typedef struct compiler_common {
357    jump_list *vspace;    jump_list *vspace;
358    jump_list *casefulcmp;    jump_list *casefulcmp;
359    jump_list *caselesscmp;    jump_list *caselesscmp;
360      jump_list *reset_match;
361    BOOL jscript_compat;    BOOL jscript_compat;
362  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
363    BOOL utf;    BOOL utf;
# Line 390  typedef struct compare_context { Line 410  typedef struct compare_context {
410  #endif  #endif
411  } compare_context;  } compare_context;
412    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
413  /* Undefine sljit macros. */  /* Undefine sljit macros. */
414  #undef CMP  #undef CMP
415    
# Line 428  group contains the start / end character Line 442  group contains the start / end character
442  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. */
443  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
444  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
445  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
446  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
447    
448  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
# Line 459  the start pointers when the end of the c Line 473  the start pointers when the end of the c
473    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
474  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
475    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
476    #define SET_LABEL(jump, label) \
477      sljit_set_label((jump), (label))
478  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
479    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
480  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
# Line 507  switch(*cc) Line 523  switch(*cc)
523    case OP_WORDCHAR:    case OP_WORDCHAR:
524    case OP_ANY:    case OP_ANY:
525    case OP_ALLANY:    case OP_ALLANY:
526      case OP_NOTPROP:
527      case OP_PROP:
528    case OP_ANYNL:    case OP_ANYNL:
529    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
530    case OP_HSPACE:    case OP_HSPACE:
# Line 519  switch(*cc) Line 537  switch(*cc)
537    case OP_CIRCM:    case OP_CIRCM:
538    case OP_DOLL:    case OP_DOLL:
539    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:  
540    case OP_CRSTAR:    case OP_CRSTAR:
541    case OP_CRMINSTAR:    case OP_CRMINSTAR:
542    case OP_CRPLUS:    case OP_CRPLUS:
543    case OP_CRMINPLUS:    case OP_CRMINPLUS:
544    case OP_CRQUERY:    case OP_CRQUERY:
545    case OP_CRMINQUERY:    case OP_CRMINQUERY:
546      case OP_CRRANGE:
547      case OP_CRMINRANGE:
548      case OP_CLASS:
549      case OP_NCLASS:
550      case OP_REF:
551      case OP_REFI:
552      case OP_RECURSE:
553      case OP_CALLOUT:
554      case OP_ALT:
555      case OP_KET:
556      case OP_KETRMAX:
557      case OP_KETRMIN:
558      case OP_KETRPOS:
559      case OP_REVERSE:
560      case OP_ASSERT:
561      case OP_ASSERT_NOT:
562      case OP_ASSERTBACK:
563      case OP_ASSERTBACK_NOT:
564      case OP_ONCE:
565      case OP_ONCE_NC:
566      case OP_BRA:
567      case OP_BRAPOS:
568      case OP_CBRA:
569      case OP_CBRAPOS:
570      case OP_COND:
571      case OP_SBRA:
572      case OP_SBRAPOS:
573      case OP_SCBRA:
574      case OP_SCBRAPOS:
575      case OP_SCOND:
576      case OP_CREF:
577      case OP_NCREF:
578      case OP_RREF:
579      case OP_NRREF:
580    case OP_DEF:    case OP_DEF:
581    case OP_BRAZERO:    case OP_BRAZERO:
582    case OP_BRAMINZERO:    case OP_BRAMINZERO:
583    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
584      case OP_PRUNE:
585    case OP_COMMIT:    case OP_COMMIT:
586    case OP_FAIL:    case OP_FAIL:
587    case OP_ACCEPT:    case OP_ACCEPT:
588    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
589      case OP_CLOSE:
590    case OP_SKIPZERO:    case OP_SKIPZERO:
591    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
592    
593    case OP_CHAR:    case OP_CHAR:
594    case OP_CHARI:    case OP_CHARI:
# Line 561  switch(*cc) Line 600  switch(*cc)
600    case OP_MINPLUS:    case OP_MINPLUS:
601    case OP_QUERY:    case OP_QUERY:
602    case OP_MINQUERY:    case OP_MINQUERY:
603      case OP_UPTO:
604      case OP_MINUPTO:
605      case OP_EXACT:
606    case OP_POSSTAR:    case OP_POSSTAR:
607    case OP_POSPLUS:    case OP_POSPLUS:
608    case OP_POSQUERY:    case OP_POSQUERY:
609      case OP_POSUPTO:
610    case OP_STARI:    case OP_STARI:
611    case OP_MINSTARI:    case OP_MINSTARI:
612    case OP_PLUSI:    case OP_PLUSI:
613    case OP_MINPLUSI:    case OP_MINPLUSI:
614    case OP_QUERYI:    case OP_QUERYI:
615    case OP_MINQUERYI:    case OP_MINQUERYI:
616      case OP_UPTOI:
617      case OP_MINUPTOI:
618      case OP_EXACTI:
619    case OP_POSSTARI:    case OP_POSSTARI:
620    case OP_POSPLUSI:    case OP_POSPLUSI:
621    case OP_POSQUERYI:    case OP_POSQUERYI:
622      case OP_POSUPTOI:
623    case OP_NOTSTAR:    case OP_NOTSTAR:
624    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
625    case OP_NOTPLUS:    case OP_NOTPLUS:
626    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
627    case OP_NOTQUERY:    case OP_NOTQUERY:
628    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
629      case OP_NOTUPTO:
630      case OP_NOTMINUPTO:
631      case OP_NOTEXACT:
632    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
633    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
634    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
635      case OP_NOTPOSUPTO:
636    case OP_NOTSTARI:    case OP_NOTSTARI:
637    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
638    case OP_NOTPLUSI:    case OP_NOTPLUSI:
639    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
640    case OP_NOTQUERYI:    case OP_NOTQUERYI:
641    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:  
642    case OP_NOTUPTOI:    case OP_NOTUPTOI:
643    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
644    case OP_NOTEXACTI:    case OP_NOTEXACTI:
645      case OP_NOTPOSSTARI:
646      case OP_NOTPOSPLUSI:
647      case OP_NOTPOSQUERYI:
648    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
649    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
650  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
651    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
652  #endif  #endif
653    return cc;    return cc;
654    
655    case OP_NOTPROP:    /* Special cases. */
656    case OP_PROP:    case OP_TYPESTAR:
657    return cc + 1 + 2;    case OP_TYPEMINSTAR:
658      case OP_TYPEPLUS:
659      case OP_TYPEMINPLUS:
660      case OP_TYPEQUERY:
661      case OP_TYPEMINQUERY:
662    case OP_TYPEUPTO:    case OP_TYPEUPTO:
663    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
664    case OP_TYPEEXACT:    case OP_TYPEEXACT:
665      case OP_TYPEPOSSTAR:
666      case OP_TYPEPOSPLUS:
667      case OP_TYPEPOSQUERY:
668    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
669    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;  
670    
671    case OP_CRRANGE:    case OP_ANYBYTE:
672    case OP_CRMINRANGE:  #ifdef SUPPORT_UTF
673    return cc + 1 + 2 * IMM2_SIZE;    if (common->utf) return NULL;
674    #endif
675    case OP_CLASS:    return cc + 1;
   case OP_NCLASS:  
   return cc + 1 + 32 / sizeof(pcre_uchar);  
676    
677  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
678    case OP_XCLASS:    case OP_XCLASS:
679    return cc + GET(cc, 1);    return cc + GET(cc, 1);
680  #endif  #endif
681    
   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;  
   
682    case OP_MARK:    case OP_MARK:
683      case OP_PRUNE_ARG:
684    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
685    
686    default:    default:
# Line 812  while (cc < ccend) Line 815  while (cc < ccend)
815    
816      case OP_COND:      case OP_COND:
817      case OP_SCOND:      case OP_SCOND:
818      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
819      if (bracketlen == OP_CREF)         not intend to support this case. */
820        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
821        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;  
         }  
       }  
822    
823      if (*cc == OP_COND)      if (*cc == OP_COND)
824        {        {
# Line 850  while (cc < ccend) Line 832  while (cc < ccend)
832      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
833      break;      break;
834    
835        case OP_CREF:
836        i = GET2(cc, 1);
837        common->optimized_cbracket[i] = 0;
838        cc += 1 + IMM2_SIZE;
839        break;
840    
841        case OP_NCREF:
842        bracketlen = GET2(cc, 1);
843        name = (pcre_uchar *)common->name_table;
844        alternative = name;
845        for (i = 0; i < common->name_count; i++)
846          {
847          if (GET2(name, 0) == bracketlen) break;
848          name += common->name_entry_size;
849          }
850        SLJIT_ASSERT(i != common->name_count);
851    
852        for (i = 0; i < common->name_count; i++)
853          {
854          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
855            common->optimized_cbracket[GET2(alternative, 0)] = 0;
856          alternative += common->name_entry_size;
857          }
858        bracketlen = 0;
859        cc += 1 + IMM2_SIZE;
860        break;
861    
862      case OP_BRA:      case OP_BRA:
863      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
864      break;      break;
# Line 906  while (cc < ccend) Line 915  while (cc < ccend)
915    
916      case OP_RECURSE:      case OP_RECURSE:
917      /* Set its value only once. */      /* Set its value only once. */
918      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
919        {        {
920        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
921        common->ovector_start += sizeof(sljit_sw);        common->ovector_start += sizeof(sljit_sw);
922        }        }
923      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
924      break;      break;
925    
926        case OP_CALLOUT:
927        if (common->capture_last_ptr == 0)
928          {
929          common->capture_last_ptr = common->ovector_start;
930          common->ovector_start += sizeof(sljit_sw);
931          }
932        cc += 2 + 2 * LINK_SIZE;
933        break;
934    
935        case OP_PRUNE_ARG:
936        common->needs_start_ptr = TRUE;
937        /* Fall through. */
938    
939      case OP_MARK:      case OP_MARK:
940      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
941        {        {
# Line 923  while (cc < ccend) Line 945  while (cc < ccend)
945      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
946      break;      break;
947    
948        case OP_PRUNE:
949        common->needs_start_ptr = TRUE;
950        cc += 1;
951        break;
952    
953      default:      default:
954      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
955      if (cc == NULL)      if (cc == NULL)
# Line 1099  while (cc < ccend) Line 1126  while (cc < ccend)
1126    }    }
1127  }  }
1128    
1129  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1130  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1131  {  {
1132  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1133  int length = 0;  int length = 0;
1134  BOOL possessive = FALSE;  int possessive = 0;
1135    BOOL stack_restore = FALSE;
1136  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1137  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1138    /* The last capture is a local variable even for recursions. */
1139    BOOL capture_last_found = FALSE;
1140    
1141  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1142    {    {
1143    length = 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1144    possessive = TRUE;    /* This is correct regardless of common->capture_last_ptr. */
1145      capture_last_found = TRUE;
1146    }    }
1147    
1148  cc = next_opcode(common, cc);  cc = next_opcode(common, cc);
# Line 1121  while (cc < ccend) Line 1152  while (cc < ccend)
1152      {      {
1153      case OP_SET_SOM:      case OP_SET_SOM:
1154      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1155        stack_restore = TRUE;
1156      if (!setsom_found)      if (!setsom_found)
1157        {        {
1158        length += 2;        length += 2;
# Line 1130  while (cc < ccend) Line 1162  while (cc < ccend)
1162      break;      break;
1163    
1164      case OP_MARK:      case OP_MARK:
1165        case OP_PRUNE_ARG:
1166      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1167        stack_restore = TRUE;
1168      if (!setmark_found)      if (!setmark_found)
1169        {        {
1170        length += 2;        length += 2;
# Line 1140  while (cc < ccend) Line 1174  while (cc < ccend)
1174      break;      break;
1175    
1176      case OP_RECURSE:      case OP_RECURSE:
1177        stack_restore = TRUE;
1178      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1179        {        {
1180        length += 2;        length += 2;
# Line 1150  while (cc < ccend) Line 1185  while (cc < ccend)
1185        length += 2;        length += 2;
1186        setmark_found = TRUE;        setmark_found = TRUE;
1187        }        }
1188        if (common->capture_last_ptr != 0 && !capture_last_found)
1189          {
1190          length += 2;
1191          capture_last_found = TRUE;
1192          }
1193      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1194      break;      break;
1195    
# Line 1157  while (cc < ccend) Line 1197  while (cc < ccend)
1197      case OP_CBRAPOS:      case OP_CBRAPOS:
1198      case OP_SCBRA:      case OP_SCBRA:
1199      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1200        stack_restore = TRUE;
1201        if (common->capture_last_ptr != 0 && !capture_last_found)
1202          {
1203          length += 2;
1204          capture_last_found = TRUE;
1205          }
1206      length += 3;      length += 3;
1207      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1208      break;      break;
1209    
1210      default:      default:
1211        stack_restore = TRUE;
1212        /* Fall through. */
1213    
1214        case OP_NOT_WORD_BOUNDARY:
1215        case OP_WORD_BOUNDARY:
1216        case OP_NOT_DIGIT:
1217        case OP_DIGIT:
1218        case OP_NOT_WHITESPACE:
1219        case OP_WHITESPACE:
1220        case OP_NOT_WORDCHAR:
1221        case OP_WORDCHAR:
1222        case OP_ANY:
1223        case OP_ALLANY:
1224        case OP_ANYBYTE:
1225        case OP_NOTPROP:
1226        case OP_PROP:
1227        case OP_ANYNL:
1228        case OP_NOT_HSPACE:
1229        case OP_HSPACE:
1230        case OP_NOT_VSPACE:
1231        case OP_VSPACE:
1232        case OP_EXTUNI:
1233        case OP_EODN:
1234        case OP_EOD:
1235        case OP_CIRC:
1236        case OP_CIRCM:
1237        case OP_DOLL:
1238        case OP_DOLLM:
1239        case OP_CHAR:
1240        case OP_CHARI:
1241        case OP_NOT:
1242        case OP_NOTI:
1243    
1244        case OP_EXACT:
1245        case OP_POSSTAR:
1246        case OP_POSPLUS:
1247        case OP_POSQUERY:
1248        case OP_POSUPTO:
1249    
1250        case OP_EXACTI:
1251        case OP_POSSTARI:
1252        case OP_POSPLUSI:
1253        case OP_POSQUERYI:
1254        case OP_POSUPTOI:
1255    
1256        case OP_NOTEXACT:
1257        case OP_NOTPOSSTAR:
1258        case OP_NOTPOSPLUS:
1259        case OP_NOTPOSQUERY:
1260        case OP_NOTPOSUPTO:
1261    
1262        case OP_NOTEXACTI:
1263        case OP_NOTPOSSTARI:
1264        case OP_NOTPOSPLUSI:
1265        case OP_NOTPOSQUERYI:
1266        case OP_NOTPOSUPTOI:
1267    
1268        case OP_TYPEEXACT:
1269        case OP_TYPEPOSSTAR:
1270        case OP_TYPEPOSPLUS:
1271        case OP_TYPEPOSQUERY:
1272        case OP_TYPEPOSUPTO:
1273    
1274        case OP_CLASS:
1275        case OP_NCLASS:
1276        case OP_XCLASS:
1277    
1278      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1279      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1280      break;      break;
1281      }      }
1282    
1283  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1284  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1285    return -1;    return stack_restore ? no_frame : no_stack;
1286    
1287  if (length > 0)  if (length > 0)
1288    return length + 1;    return length + 1;
1289  return -1;  return stack_restore ? no_frame : no_stack;
1290  }  }
1291    
1292  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)
1293  {  {
1294  DEFINE_COMPILER;  DEFINE_COMPILER;
1295  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1296  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1297  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1298    /* The last capture is a local variable even for recursions. */
1299    BOOL capture_last_found = FALSE;
1300  int offset;  int offset;
1301    
1302  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1200  while (cc < ccend) Line 1315  while (cc < ccend)
1315      if (!setsom_found)      if (!setsom_found)
1316        {        {
1317        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1318        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1319        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1320        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1321        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1210  while (cc < ccend) Line 1325  while (cc < ccend)
1325      break;      break;
1326    
1327      case OP_MARK:      case OP_MARK:
1328        case OP_PRUNE_ARG:
1329      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1330      if (!setmark_found)      if (!setmark_found)
1331        {        {
1332        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);
1333        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);
1334        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1335        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1336        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1227  while (cc < ccend) Line 1343  while (cc < ccend)
1343      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1344        {        {
1345        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1346        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1347        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1348        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1349        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
# Line 1236  while (cc < ccend) Line 1352  while (cc < ccend)
1352      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1353        {        {
1354        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);
1355        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);
1356        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1357        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1358        stackpos += (int)sizeof(sljit_sw);        stackpos += (int)sizeof(sljit_sw);
1359        setmark_found = TRUE;        setmark_found = TRUE;
1360        }        }
1361        if (common->capture_last_ptr != 0 && !capture_last_found)
1362          {
1363          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1364          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1365          stackpos += (int)sizeof(sljit_sw);
1366          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1367          stackpos += (int)sizeof(sljit_sw);
1368          capture_last_found = TRUE;
1369          }
1370      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1371      break;      break;
1372    
# Line 1249  while (cc < ccend) Line 1374  while (cc < ccend)
1374      case OP_CBRAPOS:      case OP_CBRAPOS:
1375      case OP_SCBRA:      case OP_SCBRA:
1376      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1377        if (common->capture_last_ptr != 0 && !capture_last_found)
1378          {
1379          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1380          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1381          stackpos += (int)sizeof(sljit_sw);
1382          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1383          stackpos += (int)sizeof(sljit_sw);
1384          capture_last_found = TRUE;
1385          }
1386      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1387      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1388      stackpos += (int)sizeof(sljit_sw);      stackpos += (int)sizeof(sljit_sw);
# Line 1268  while (cc < ccend) Line 1402  while (cc < ccend)
1402      break;      break;
1403      }      }
1404    
1405  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1406  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1407  }  }
1408    
# Line 1430  while (status != end) Line 1564  while (status != end)
1564    switch(status)    switch(status)
1565      {      {
1566      case start:      case start:
1567      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1568      count = 1;      count = 1;
1569      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1570      status = loop;      status = loop;
1571      break;      break;
1572    
# Line 1708  while (list) Line 1842  while (list)
1842    {    {
1843    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1844    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1845    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1846    list = list->next;    list = list->next;
1847    }    }
1848  }  }
# Line 1724  if (list_item) Line 1858  if (list_item)
1858    }    }
1859  }  }
1860    
1861  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)
1862  {  {
1863  DEFINE_COMPILER;  DEFINE_COMPILER;
1864  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1865    
1866  if (list_item)  if (list_item)
1867    {    {
   list_item->type = type;  
   list_item->data = data;  
1868    list_item->start = start;    list_item->start = start;
1869    list_item->quit = LABEL();    list_item->quit = LABEL();
1870    list_item->next = common->stubs;    list_item->next = common->stubs;
# Line 1748  stub_list* list_item = common->stubs; Line 1880  stub_list* list_item = common->stubs;
1880  while (list_item)  while (list_item)
1881    {    {
1882    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
1883    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;  
     }  
1884    JUMPTO(SLJIT_JUMP, list_item->quit);    JUMPTO(SLJIT_JUMP, list_item->quit);
1885    list_item = list_item->next;    list_item = list_item->next;
1886    }    }
# Line 1781  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 1908  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1908  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
1909  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
1910  #endif  #endif
1911  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));
1912  }  }
1913    
1914  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 1922  static SLJIT_INLINE void reset_ovector(c
1922  DEFINE_COMPILER;  DEFINE_COMPILER;
1923  struct sljit_label *loop;  struct sljit_label *loop;
1924  int i;  int i;
1925    
1926  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1927    SLJIT_ASSERT(length > 1);
1928  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1929  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1930  if (length < 8)  if (length < 8)
1931    {    {
1932    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
1933      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1934    }    }
1935  else  else
1936    {    {
1937    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
1938    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
1939    loop = LABEL();    loop = LABEL();
1940    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1941    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
# Line 1814  else Line 1943  else
1943    }    }
1944  }  }
1945    
1946    static void do_reset_match(compiler_common *common, int length)
1947    {
1948    DEFINE_COMPILER;
1949    struct sljit_label *loop;
1950    int i;
1951    
1952    SLJIT_ASSERT(length > 1);
1953    /* OVECTOR(1) contains the "string begin - 1" constant. */
1954    if (length > 2)
1955      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1956    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
1957    if (length < 8)
1958      {
1959      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
1960      for (i = 2; i < length; i++)
1961        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
1962      }
1963    else
1964      {
1965      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
1966      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_IMM, length - 2);
1967      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
1968      loop = LABEL();
1969      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
1970      OP2(SLJIT_SUB | SLJIT_SET_E, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);
1971      JUMPTO(SLJIT_C_NOT_ZERO, loop);
1972      }
1973    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
1974    }
1975    
1976  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1977  {  {
1978  DEFINE_COMPILER;  DEFINE_COMPILER;
1979  struct sljit_label *loop;  struct sljit_label *loop;
1980  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
1981    
1982  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1983  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
# Line 1827  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 1986  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
1986  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1987  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1988    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1989  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
1990  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1991    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
1992  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1993  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1994  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1995  /* Unlikely, but possible */  /* Unlikely, but possible */
1996  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
1997  loop = LABEL();  loop = LABEL();
1998  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
1999  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
# Line 1845  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ Line 2004  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJ
2004  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
2005  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
2006  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2007  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2008    
2009  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2010  if (topbracket > 1)  if (topbracket > 1)
# Line 1867  else Line 2026  else
2026  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)
2027  {  {
2028  DEFINE_COMPILER;  DEFINE_COMPILER;
2029    struct sljit_jump *jump;
2030    
2031  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);
2032  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
2033      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2034    
2035  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2036  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2037  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2038  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
2039    
2040  /* Store match begin and end. */  /* Store match begin and end. */
2041  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
2042  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2043    
2044    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2045    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);
2046    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2047    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2048    #endif
2049    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2050    JUMPHERE(jump);
2051    
2052  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
2053  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);
2054  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
# Line 2055  else if (common->mode == JIT_PARTIAL_SOF Line 2225  else if (common->mode == JIT_PARTIAL_SOF
2225    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);
2226    
2227  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2228    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);
2229  else  else
2230    {    {
2231    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2068  if (jump != NULL) Line 2238  if (jump != NULL)
2238    JUMPHERE(jump);    JUMPHERE(jump);
2239  }  }
2240    
2241  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2242  {  {
2243  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2244  DEFINE_COMPILER;  DEFINE_COMPILER;
2245  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2246    
2247  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2248    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2249      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2250      return;
2251      }
2252    
2253  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2254  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2255    {    {
2256    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));
2257    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);
2258    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2259    }    }
2260  else  else
2261    {    {
2262    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));
2263    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2264      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2265    else    else
2266      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2267    }    }
2268  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2269  }  }
2270    
2271  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 2284  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2284  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));
2285  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2286    {    {
2287    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);
2288    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2289    }    }
2290  else  else
# Line 2573  DEFINE_COMPILER; Line 2742  DEFINE_COMPILER;
2742  struct sljit_label *start;  struct sljit_label *start;
2743  struct sljit_jump *quit;  struct sljit_jump *quit;
2744  pcre_uint32 chars[MAX_N_CHARS * 2];  pcre_uint32 chars[MAX_N_CHARS * 2];
2745  pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2746  int location = 0;  int location = 0;
2747  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2748  int must_stop;  int must_stop;
# Line 2696  if (firstline) Line 2865  if (firstline)
2865    {    {
2866    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2867    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2868    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));
2869    }    }
2870  else  else
2871    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));
2872    
2873  start = LABEL();  start = LABEL();
2874  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 2897  JUMPHERE(quit);
2897  if (firstline)  if (firstline)
2898    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2899  else  else
2900    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));
2901  return TRUE;  return TRUE;
2902  }  }
2903    
# Line 2877  if (firstline) Line 3046  if (firstline)
3046    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3047  }  }
3048    
3049    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3050    
3051  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)
3052  {  {
3053  DEFINE_COMPILER;  DEFINE_COMPILER;
3054  struct sljit_label *start;  struct sljit_label *start;
3055  struct sljit_jump *quit;  struct sljit_jump *quit;
3056  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3057    jump_list *matches = NULL;
3058    pcre_uint8 inverted_start_bits[32];
3059    int i;
3060  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3061  struct sljit_jump *jump;  struct sljit_jump *jump;
3062  #endif  #endif
3063    
3064    for (i = 0; i < 32; ++i)
3065      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3066    
3067  if (firstline)  if (firstline)
3068    {    {
3069    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 3078  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
3078  if (common->utf)  if (common->utf)
3079    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3080  #endif  #endif
3081    
3082    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3083      {
3084  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3085  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3086  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3087  JUMPHERE(jump);    JUMPHERE(jump);
3088  #endif  #endif
3089  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3090  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3091  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3092  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3093  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);
3094  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
3095      }
3096    
3097  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3098  if (common->utf)  if (common->utf)
# Line 2939  if (common->utf) Line 3120  if (common->utf)
3120  #endif /* COMPILE_PCRE[8|16] */  #endif /* COMPILE_PCRE[8|16] */
3121  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
3122  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3123  JUMPHERE(found);  if (found != NULL)
3124      JUMPHERE(found);
3125    if (matches != NULL)
3126      set_jumps(matches, LABEL());
3127  JUMPHERE(quit);  JUMPHERE(quit);
3128    
3129  if (firstline)  if (firstline)
# Line 3022  GET_LOCAL_BASE(TMP3, 0, 0); Line 3206  GET_LOCAL_BASE(TMP3, 0, 0);
3206  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3207  mainloop = LABEL();  mainloop = LABEL();
3208  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3209  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);
3210    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3211    
3212  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3213  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));
3214  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 3216  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_I
3216  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3217    
3218  JUMPHERE(jump);  JUMPHERE(jump);
3219  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3220  /* End of dropping frames. */  /* End of dropping frames. */
3221  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3222    
3223  JUMPHERE(jump);  JUMPHERE(jump);
3224  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3225  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3226  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. */  
3227  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));
3228  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3229  }  }
# Line 3063  static void check_wordboundary(compiler_ Line 3232  static void check_wordboundary(compiler_
3232  {  {
3233  DEFINE_COMPILER;  DEFINE_COMPILER;
3234  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3235    jump_list *skipread_list = NULL;
3236  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3237  struct sljit_jump *jump;  struct sljit_jump *jump;
3238  #endif  #endif
# Line 3120  else Line 3290  else
3290  JUMPHERE(skipread);  JUMPHERE(skipread);
3291    
3292  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3293  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3294  peek_char(common);  peek_char(common);
3295    
3296  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3161  else Line 3331  else
3331      JUMPHERE(jump);      JUMPHERE(jump);
3332  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3333    }    }
3334  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3335    
3336  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);
3337  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 3481  sljit_emit_fast_return(compiler, RETURN_ Line 3651  sljit_emit_fast_return(compiler, RETURN_
3651    
3652  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3653    
3654  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)
3655  {  {
3656  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3657  pcre_uint32 c1, c2;  pcre_uint32 c1, c2;
# Line 3577  do Line 3747  do
3747  #endif  #endif
3748    
3749    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3750  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3751    
3752    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3753    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3594  do Line 3764  do
3764    
3765  #if defined COMPILE_PCRE8  #if defined COMPILE_PCRE8
3766    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))
3767  #elif defined COMPILE_PCRE16  #else
3768    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 */)  
3769  #endif  #endif
3770      {      {
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3771      if (context->length >= 4)      if (context->length >= 4)
3772        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  
3773      else if (context->length >= 2)      else if (context->length >= 2)
3774        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);
3775    #if defined COMPILE_PCRE8
3776      else if (context->length >= 1)      else if (context->length >= 1)
3777        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);
3778  #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] */  
3779      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3780    
3781      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3625  do Line 3786  do
3786        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));
3787        break;        break;
3788    
 #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16  
3789        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3790        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3791          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 3800  do
3800        break;        break;
3801  #endif  #endif
3802    
 #endif /* COMPILE_PCRE[8|16] */  
   
3803        default:        default:
3804        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3805        break;        break;
# Line 3651  do Line 3809  do
3809    
3810  #else  #else
3811    
3812    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3813    if (context->length > 0)    if (context->length >= 1)
3814      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3815    
3816    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
# Line 3813  while (*cc != XCL_END) Line 3971  while (*cc != XCL_END)
3971        break;        break;
3972    
3973        case PT_CLIST:        case PT_CLIST:
3974          case PT_UCNC:
3975        needschar = TRUE;        needschar = TRUE;
3976        break;        break;
3977    
# Line 4014  while (*cc != XCL_END) Line 4173  while (*cc != XCL_END)
4173        case PT_WORD:        case PT_WORD:
4174        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);
4175        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4176        /* ... fall through */        /* Fall through. */
4177    
4178        case PT_ALNUM:        case PT_ALNUM:
4179        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
# Line 4078  while (*cc != XCL_END) Line 4237  while (*cc != XCL_END)
4237          }          }
4238        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4239        break;        break;
4240    
4241          case PT_UCNC:
4242          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
4243          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4244          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
4245          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4246          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
4247          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4248    
4249          SET_CHAR_OFFSET(0xa0);
4250          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4251          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4252          SET_CHAR_OFFSET(0);
4253          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4254          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4255          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4256          break;
4257        }        }
4258      cc += 2;      cc += 2;
4259      }      }
# Line 4103  int length; Line 4279  int length;
4279  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4280  compare_context context;  compare_context context;
4281  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4282    jump_list *end_list;
4283  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4284  struct sljit_label *label;  struct sljit_label *label;
4285  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4171  switch(type) Line 4348  switch(type)
4348    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4349      {      {
4350      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);
4351        end_list = NULL;
4352      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4353        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));
4354      else      else
4355        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4356    
4357      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4358      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));
4359      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4360      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4361      }      }
4362    else    else
# Line 4238  switch(type) Line 4415  switch(type)
4415    read_char(common);    read_char(common);
4416    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);
4417    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4418      end_list = NULL;
4419    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4420      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));
4421    else    else
4422      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4423    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4424    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);
4425    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));
4426    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4427    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4428    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4429      set_jumps(end_list, LABEL());
4430    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4431    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4432    return cc;    return cc;
4433    
4434    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 5001  backtrack_common *backtrack; Line 5179  backtrack_common *backtrack;
5179  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5180  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5181  int start = GET(cc, 1);  int start = GET(cc, 1);
5182    pcre_uchar *start_cc;
5183    
5184  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5185    
5186    /* Inlining simple patterns. */
5187    if (get_framesize(common, common->start + start, TRUE) == no_stack)
5188      {
5189      start_cc = common->start + start;
5190      compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
5191      BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
5192      return cc + 1 + LINK_SIZE;
5193      }
5194    
5195  while (entry != NULL)  while (entry != NULL)
5196    {    {
5197    if (entry->start == start)    if (entry->start == start)
# Line 5051  add_jump(compiler, &backtrack->topbacktr Line 5240  add_jump(compiler, &backtrack->topbacktr
5240  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5241  }  }
5242    
5243    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5244    {
5245    const pcre_uchar *begin = arguments->begin;
5246    int *offset_vector = arguments->offsets;
5247    int offset_count = arguments->offset_count;
5248    int i;
5249    
5250    if (PUBL(callout) == NULL)
5251      return 0;
5252    
5253    callout_block->version = 2;
5254    callout_block->callout_data = arguments->callout_data;
5255    
5256    /* Offsets in subject. */
5257    callout_block->subject_length = arguments->end - arguments->begin;
5258    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5259    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5260    #if defined COMPILE_PCRE8
5261    callout_block->subject = (PCRE_SPTR)begin;
5262    #elif defined COMPILE_PCRE16
5263    callout_block->subject = (PCRE_SPTR16)begin;
5264    #elif defined COMPILE_PCRE32
5265    callout_block->subject = (PCRE_SPTR32)begin;
5266    #endif
5267    
5268    /* Convert and copy the JIT offset vector to the offset_vector array. */
5269    callout_block->capture_top = 0;
5270    callout_block->offset_vector = offset_vector;
5271    for (i = 2; i < offset_count; i += 2)
5272      {
5273      offset_vector[i] = jit_ovector[i] - begin;
5274      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5275      if (jit_ovector[i] >= begin)
5276        callout_block->capture_top = i;
5277      }
5278    
5279    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5280    if (offset_count > 0)
5281      offset_vector[0] = -1;
5282    if (offset_count > 1)
5283      offset_vector[1] = -1;
5284    return (*PUBL(callout))(callout_block);
5285    }
5286    
5287    /* Aligning to 8 byte. */
5288    #define CALLOUT_ARG_SIZE \
5289        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5290    
5291    #define CALLOUT_ARG_OFFSET(arg) \
5292        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5293    
5294    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5295    {
5296    DEFINE_COMPILER;
5297    backtrack_common *backtrack;
5298    
5299    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5300    
5301    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5302    
5303    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5304    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5305    SLJIT_ASSERT(common->capture_last_ptr != 0);
5306    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5307    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5308    
5309    /* These pointer sized fields temporarly stores internal variables. */
5310    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5311    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5312    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5313    
5314    if (common->mark_ptr != 0)
5315      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5316    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5317    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5318    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5319    
5320    /* Needed to save important temporary registers. */
5321    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5322    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5323    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5324    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5325    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5326    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5327    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5328    
5329    /* Check return value. */
5330    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5331    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5332    if (common->forced_quit_label == NULL)
5333      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5334    else
5335      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5336    return cc + 2 + 2 * LINK_SIZE;
5337    }
5338    
5339    #undef CALLOUT_ARG_SIZE
5340    #undef CALLOUT_ARG_OFFSET
5341    
5342  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)
5343  {  {
5344  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 5064  jump_list *tmp = NULL; Line 5352  jump_list *tmp = NULL;
5352  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5353  jump_list **found;  jump_list **found;
5354  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5355  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
5356  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_accept_label = common->accept_label;
5357  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5358  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5359  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 5114  else Line 5402  else
5402    }    }
5403    
5404  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5405  common->quitlabel = NULL;  common->quit_label = NULL;
5406  common->quit = NULL;  common->quit = NULL;
5407  while (1)  while (1)
5408    {    {
5409    common->acceptlabel = NULL;    common->accept_label = NULL;
5410    common->accept = NULL;    common->accept = NULL;
5411    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5412    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5130  while (1) Line 5418  while (1)
5418    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5419    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5420      {      {
5421      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5422      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5423      common->quit = save_quit;      common->quit = save_quit;
5424      common->accept = save_accept;      common->accept = save_accept;
5425      return NULL;      return NULL;
5426      }      }
5427    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5428    if (common->accept != NULL)    if (common->accept != NULL)
5429      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5430    
5431    /* Reset stack. */    /* Reset stack. */
5432    if (framesize < 0)    if (framesize < 0)
# Line 5185  while (1) Line 5473  while (1)
5473    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5474    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5475      {      {
5476      common->quitlabel = save_quitlabel;      common->quit_label = save_quit_label;
5477      common->acceptlabel = save_acceptlabel;      common->accept_label = save_accept_label;
5478      common->quit = save_quit;      common->quit = save_quit;
5479      common->accept = save_accept;      common->accept = save_accept;
5480      return NULL;      return NULL;
# Line 5269  if (opcode == OP_ASSERT || opcode == OP_ Line 5557  if (opcode == OP_ASSERT || opcode == OP_
5557    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5558      {      {
5559      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5560      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5561      }      }
5562    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5563      {      {
# Line 5326  else Line 5614  else
5614      }      }
5615    }    }
5616    
5617  common->quitlabel = save_quitlabel;  common->quit_label = save_quit_label;
5618  common->acceptlabel = save_acceptlabel;  common->accept_label = save_accept_label;
5619  common->quit = save_quit;  common->quit = save_quit;
5620  common->accept = save_accept;  common->accept = save_accept;
5621  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
# Line 5709  if (opcode == OP_ONCE) Line 5997  if (opcode == OP_ONCE)
5997  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5998    {    {
5999    /* Saving the previous values. */    /* Saving the previous values. */
6000    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  
6001      {      {
6002      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));      SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
6003      allocate_stack(common, 2);      allocate_stack(common, 2);
# Line 5730  else if (opcode == OP_CBRA || opcode == Line 6007  else if (opcode == OP_CBRA || opcode ==
6007      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6008      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6009      }      }
6010      else
6011        {
6012        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6013        allocate_stack(common, 1);
6014        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
6015        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
6016        }
6017    }    }
6018  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
6019    {    {
# Line 5871  if (opcode == OP_ONCE) Line 6155  if (opcode == OP_ONCE)
6155  stacksize = 0;  stacksize = 0;
6156  if (ket != OP_KET || bra != OP_BRA)  if (ket != OP_KET || bra != OP_BRA)
6157    stacksize++;    stacksize++;
6158    if (offset != 0)
6159      {
6160      if (common->capture_last_ptr != 0)
6161        stacksize++;
6162      if (common->optimized_cbracket[offset >> 1] == 0)
6163        stacksize += 2;
6164      }
6165  if (has_alternatives && opcode != OP_ONCE)  if (has_alternatives && opcode != OP_ONCE)
6166    stacksize++;    stacksize++;
6167    
# Line 5878  if (stacksize > 0) Line 6169  if (stacksize > 0)
6169    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6170    
6171  stacksize = 0;  stacksize = 0;
6172  if (ket != OP_KET)  if (ket != OP_KET || bra != OP_BRA)
6173    {    {
6174    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);    if (ket != OP_KET)
6175        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), STR_PTR, 0);
6176      else
6177        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
6178    stacksize++;    stacksize++;
6179    }    }
6180  else if (bra != OP_BRA)  
6181    if (offset != 0)
6182    {    {
6183    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);    if (common->capture_last_ptr != 0)
6184    stacksize++;      {
6185        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6186        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6187        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP2, 0);
6188        stacksize++;
6189        }
6190      if (common->optimized_cbracket[offset >> 1] == 0)
6191        {
6192        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6193        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
6194        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
6195        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6196        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
6197        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6198        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6199        stacksize += 2;
6200        }
6201    }    }
6202    
6203  if (has_alternatives)  if (has_alternatives)
# Line 5898  if (has_alternatives) Line 6209  if (has_alternatives)
6209    }    }
6210    
6211  /* Must be after the matchingpath label. */  /* Must be after the matchingpath label. */
6212  if (offset != 0)  if (offset != 0 && common->optimized_cbracket[offset >> 1] != 0)
6213    {    {
6214    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
6215    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);  
6216    }    }
6217    
6218  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
# Line 6016  framesize = get_framesize(common, cc, FA Line 6326  framesize = get_framesize(common, cc, FA
6326  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
6327  if (framesize < 0)  if (framesize < 0)
6328    {    {
6329    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    if (offset != 0)
6330        {
6331        stacksize = 2;
6332        if (common->capture_last_ptr != 0)
6333          stacksize++;
6334        }
6335      else
6336        stacksize = 1;
6337    
6338    if (!zero)    if (!zero)
6339      stacksize++;      stacksize++;
6340    
6341    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
6342    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
6343    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    if (framesize == no_frame)
6344        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
6345    
6346    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (offset != 0)
6347      {      {
6348      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
6349      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));
6350      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
6351        if (common->capture_last_ptr != 0)
6352          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
6353      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
6354        if (common->capture_last_ptr != 0)
6355          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
6356      }      }
6357    else    else
6358      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 6044  else Line 6368  else
6368    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
6369      stacksize++;      stacksize++;
6370    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
   allocate_stack(common, stacksize);  
6371    
6372      allocate_stack(common, stacksize);
6373    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);
6374    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
6375    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);
6376    
6377    stack = 0;    stack = 0;
6378    if (!zero)    if (!zero)
6379      {      {
# Line 6064  else Line 6389  else
6389    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);    init_frame(common, cc, stacksize - 1, stacksize - framesize, FALSE);
6390    }    }
6391    
6392  if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)  if (offset != 0)
6393    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6394    
6395  loop = LABEL();  loop = LABEL();
# Line 6080  while (*cc != OP_KETRPOS) Line 6405  while (*cc != OP_KETRPOS)
6405    
6406    if (framesize < 0)    if (framesize < 0)
6407      {      {
6408      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      if (framesize == no_frame)
6409          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6410    
6411      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6412        {        {
6413        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6414        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);
6415        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6416          if (common->capture_last_ptr != 0)
6417            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6418        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6419        }        }
6420      else      else
# Line 6104  while (*cc != OP_KETRPOS) Line 6432  while (*cc != OP_KETRPOS)
6432      }      }
6433    else    else
6434      {      {
6435      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6436        {        {
6437        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));
6438        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6439        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);
6440        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
6441          if (common->capture_last_ptr != 0)
6442            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
6443        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
6444        }        }
6445      else      else
# Line 6142  while (*cc != OP_KETRPOS) Line 6472  while (*cc != OP_KETRPOS)
6472    
6473    if (framesize < 0)    if (framesize < 0)
6474      {      {
6475      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6476        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6477      else      else
6478        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6479      }      }
6480    else    else
6481      {      {
6482      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (offset != 0)
6483        {        {
6484        /* Last alternative. */        /* Last alternative. */
6485        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
# Line 6296  PUSH_BACKTRACK(sizeof(iterator_backtrack Line 6626  PUSH_BACKTRACK(sizeof(iterator_backtrack
6626    
6627  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6628    
6629  switch (type)  switch(type)
6630    {    {
6631    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
6632    case OP_DIGIT:    case OP_DIGIT:
# Line 6498  static SLJIT_INLINE pcre_uchar *compile_ Line 6828  static SLJIT_INLINE pcre_uchar *compile_
6828  DEFINE_COMPILER;  DEFINE_COMPILER;
6829  backtrack_common *backtrack;  backtrack_common *backtrack;
6830    
6831  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
6832    
6833  if (*cc == OP_FAIL)  if (*cc == OP_FAIL)
6834    {    {
# Line 6509  if (*cc == OP_FAIL) Line 6839  if (*cc == OP_FAIL)
6839  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)  if (*cc == OP_ASSERT_ACCEPT || common->currententry != NULL)
6840    {    {
6841    /* No need to check notempty conditions. */    /* No need to check notempty conditions. */
6842    if (common->acceptlabel == NULL)    if (common->accept_label == NULL)
6843      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
6844    else    else
6845      JUMPTO(SLJIT_JUMP, common->acceptlabel);      JUMPTO(SLJIT_JUMP, common->accept_label);
6846    return cc + 1;    return cc + 1;
6847    }    }
6848    
6849  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6850    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)));
6851  else  else
6852    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);
6853  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6854  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));
6855  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));
6856  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));
6857  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6858    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));
6859  else  else
6860    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->acceptlabel);    CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, common->accept_label);
6861  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));
6862  if (common->acceptlabel == NULL)  if (common->accept_label == NULL)
6863    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));
6864  else  else
6865    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);
6866  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));  add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6867  return cc + 1;  return cc + 1;
6868  }  }
# Line 6712  while (cc < ccend) Line 7042  while (cc < ccend)
7042      cc = compile_recurse_matchingpath(common, cc, parent);      cc = compile_recurse_matchingpath(common, cc, parent);
7043      break;      break;
7044    
7045        case OP_CALLOUT:
7046        cc = compile_callout_matchingpath(common, cc, parent);
7047        break;
7048    
7049      case OP_ASSERT:      case OP_ASSERT:
7050      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
7051      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 6781  while (cc < ccend) Line 7115  while (cc < ccend)
7115      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
7116      break;      break;
7117    
7118        case OP_PRUNE_ARG:
7119        PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7120        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
7121        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)(cc + 2));
7122        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
7123        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
7124        cc += 1 + 2 + cc[1];
7125        break;
7126    
7127        case OP_PRUNE:
7128      case OP_COMMIT:      case OP_COMMIT:
7129      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);      PUSH_BACKTRACK_NOVALUE(sizeof(backtrack_common), cc);
7130      cc += 1;      cc += 1;
# Line 6994  static void compile_recurse_backtracking Line 7338  static void compile_recurse_backtracking
7338  {  {
7339  DEFINE_COMPILER;  DEFINE_COMPILER;
7340    
7341    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7342      compile_backtrackingpath(common, current->top);
7343  set_jumps(current->topbacktracks, LABEL());  set_jumps(current->topbacktracks, LABEL());
7344    if (CURRENT_AS(recurse_backtrack)->inlined_pattern)
7345      return;
7346    
7347  if (common->has_set_som && common->mark_ptr != 0)  if (common->has_set_som && common->mark_ptr != 0)
7348    {    {
# Line 7160  else if (bra == OP_BRAZERO) Line 7508  else if (bra == OP_BRAZERO)
7508    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
7509    }    }
7510    
7511    if (offset != 0)
7512      {
7513      if (common->capture_last_ptr != 0)
7514        {
7515        SLJIT_ASSERT(common->optimized_cbracket[offset >> 1] == 0);
7516        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7517        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7518        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7519        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7520        free_stack(common, 3);
7521        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP2, 0);
7522        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
7523        }
7524      else if (common->optimized_cbracket[offset >> 1] == 0)
7525        {
7526        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7527        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7528        free_stack(common, 2);
7529        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7530        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
7531        }
7532      }
7533    
7534  if (SLJIT_UNLIKELY(opcode == OP_ONCE))  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
7535    {    {
7536    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)    if (CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7299  if (has_alternatives) Line 7670  if (has_alternatives)
7670        }        }
7671    
7672      stacksize = 0;      stacksize = 0;
     if (opcode != OP_ONCE)  
       stacksize++;  
7673      if (ket != OP_KET || bra != OP_BRA)      if (ket != OP_KET || bra != OP_BRA)
7674        stacksize++;        stacksize++;
7675        if (offset != 0)
7676          {
7677          if (common->capture_last_ptr != 0)
7678            stacksize++;
7679          if (common->optimized_cbracket[offset >> 1] == 0)
7680            stacksize += 2;
7681          }
7682        if (opcode != OP_ONCE)
7683          stacksize++;
7684    
7685      if (stacksize > 0) {      if (stacksize > 0) {
7686        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)        if (opcode != OP_ONCE || CURRENT_AS(bracket_backtrack)->u.framesize >= 0)
# Line 7325  if (has_alternatives) Line 7703  if (has_alternatives)
7703        stacksize++;        stacksize++;
7704        }        }
7705    
7706        if (offset != 0)
7707          {
7708          if (common->capture_last_ptr != 0)
7709            {
7710            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
7711            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, offset >> 1);
7712            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7713            stacksize++;
7714            }
7715          if (common->optimized_cbracket[offset >> 1] == 0)
7716            {
7717            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
7718            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
7719            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), TMP1, 0);
7720            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
7721            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize + 1), TMP2, 0);
7722            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
7723            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7724            stacksize += 2;
7725            }
7726          }
7727    
7728      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
7729        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, count++);
7730    
7731      if (offset != 0)      if (offset != 0 && ket == OP_KETRMAX && common->optimized_cbracket[offset >> 1] != 0)
7732        {        {
7733        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. */
7734          SLJIT_ASSERT(private_data_ptr == OVECTOR(offset + 0));
7735        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);  
7736        }        }
7737    
7738      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);      JUMPTO(SLJIT_JUMP, CURRENT_AS(bracket_backtrack)->alternative_matchingpath);
# Line 7374  if (has_alternatives) Line 7774  if (has_alternatives)
7774  if (offset != 0)  if (offset != 0)
7775    {    {
7776    /* Using both tmp register is better for instruction scheduling. */    /* Using both tmp register is better for instruction scheduling. */
7777    if (common->optimized_cbracket[offset >> 1] == 0)    if (common->optimized_cbracket[offset >> 1] != 0)
7778      {      {
7779      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7780      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7781        free_stack(common, 2);
7782      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);  
7783      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);  
7784      }      }
7785    else    else
7786      {      {
7787      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7788      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      free_stack(common, 1);
7789      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);  
7790      }      }
7791    }    }
7792  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
# Line 7477  if (CURRENT_AS(bracketpos_backtrack)->fr Line 7873  if (CURRENT_AS(bracketpos_backtrack)->fr
7873      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
7874      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
7875      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
7876        if (common->capture_last_ptr != 0)
7877          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));
7878      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);
7879        if (common->capture_last_ptr != 0)
7880          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, TMP1, 0);
7881      }      }
7882    set_jumps(current->topbacktracks, LABEL());    set_jumps(current->topbacktracks, LABEL());
7883    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_backtrack)->stacksize);
# Line 7663  while (current) Line 8063  while (current)
8063      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);
8064      break;      break;
8065    
8066        case OP_PRUNE:
8067        case OP_PRUNE_ARG:
8068        if (!common->in_recurse)
8069          add_jump(compiler, &common->reset_match, JUMP(SLJIT_JUMP));
8070        else if (common->quit_label == NULL)
8071          add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8072        else
8073          JUMPTO(SLJIT_JUMP, common->quit_label);
8074        break;
8075    
8076      case OP_COMMIT:      case OP_COMMIT:
8077      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8078      if (common->quitlabel == NULL)      if (common->quit_label == NULL)
8079        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));        add_jump(compiler, &common->quit, JUMP(SLJIT_JUMP));
8080      else      else
8081        JUMPTO(SLJIT_JUMP, common->quitlabel);        JUMPTO(SLJIT_JUMP, common->quit_label);
8082      break;      break;
8083    
8084        case OP_CALLOUT:
8085      case OP_FAIL:      case OP_FAIL:
8086      case OP_ACCEPT:      case OP_ACCEPT:
8087      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 7696  int framesize = get_framesize(common, cc Line 8107  int framesize = get_framesize(common, cc
8107  int alternativesize;  int alternativesize;
8108  BOOL needsframe;  BOOL needsframe;
8109  backtrack_common altbacktrack;  backtrack_common altbacktrack;
 struct sljit_label *save_quitlabel = common->quitlabel;  
 jump_list *save_quit = common->quit;  
8110  struct sljit_jump *jump;  struct sljit_jump *jump;
8111    
8112  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);
# Line 7706  if (!needsframe) Line 8115  if (!needsframe)
8115    framesize = 0;    framesize = 0;
8116  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
8117    
8118  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head_ptr != 0);
8119  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
8120  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
8121    
# Line 7714  sljit_emit_fast_enter(compiler, TMP2, 0) Line 8123  sljit_emit_fast_enter(compiler, TMP2, 0)
8123  allocate_stack(common, private_data_size + framesize + alternativesize);  allocate_stack(common, private_data_size + framesize + alternativesize);
8124  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);
8125  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);
8126  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, STACK_TOP, 0);
8127  if (needsframe)  if (needsframe)
8128    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
8129    
# Line 7722  if (alternativesize > 0) Line 8131  if (alternativesize > 0)
8131    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
8132    
8133  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
8134  common->quitlabel = NULL;  common->quit_label = NULL;
8135  common->acceptlabel = NULL;  common->accept_label = NULL;
8136  common->quit = NULL;  common->quit = NULL;
8137  common->accept = NULL;  common->accept = NULL;
8138  altbacktrack.cc = ccbegin;  altbacktrack.cc = ccbegin;
# Line 7738  while (1) Line 8147  while (1)
8147    
8148    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);    compile_matchingpath(common, altbacktrack.cc, cc, &altbacktrack);
8149    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quitlabel = save_quitlabel;  
     common->quit = save_quit;  
8150      return;      return;
     }  
8151    
8152    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));    add_jump(compiler, &common->accept, JUMP(SLJIT_JUMP));
8153    
8154    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
8155    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
     {  
     common->quitlabel = save_quitlabel;  
     common->quit = save_quit;  
8156      return;      return;
     }  
8157    set_jumps(altbacktrack.topbacktracks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
8158    
8159    if (*cc != OP_ALT)    if (*cc != OP_ALT)
# Line 7769  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 8170  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
8170  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
8171    
8172  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
8173  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);
8174  if (needsframe)  if (needsframe)
8175    {    {
8176    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));
# Line 7783  copy_private_data(common, ccbegin, ccend Line 8184  copy_private_data(common, ccbegin, ccend
8184  free_stack(common, private_data_size + framesize + alternativesize);  free_stack(common, private_data_size + framesize + alternativesize);
8185  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_sw));
8186  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
8187  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head_ptr, TMP2, 0);
8188  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;  
8189  }  }
8190    
8191  #undef COMPILE_BACKTRACKINGPATH  #undef COMPILE_BACKTRACKINGPATH
# Line 7808  executable_functions *functions; Line 8206  executable_functions *functions;
8206  void *executable_func;  void *executable_func;
8207  sljit_uw executable_size;  sljit_uw executable_size;
8208  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
8209  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found_label;
8210  struct sljit_label *empty_match_backtrack;  struct sljit_label *empty_match_backtrack_label;
8211    struct sljit_label *reset_match_label;
8212  struct sljit_jump *jump;  struct sljit_jump *jump;
8213    struct sljit_jump *minlength_check_failed = NULL;
8214  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
8215  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
8216    struct sljit_label *quit_label;
8217    
8218  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != 0);
8219  study = extra->study_data;  study = extra->study_data;
# Line 7881  common->ovector_start = CALL_LIMIT + siz Line 8282  common->ovector_start = CALL_LIMIT + siz
8282  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);  common->optimized_cbracket = (pcre_uint8 *)SLJIT_MALLOC(re->top_bracket + 1);
8283  if (!common->optimized_cbracket)  if (!common->optimized_cbracket)
8284    return;    return;
8285    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 1
8286    memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8287    #else
8288  memset(common->optimized_cbracket, 1, re->top_bracket + 1);  memset(common->optimized_cbracket, 1, re->top_bracket + 1);
8289    #endif
8290    
8291  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootbacktrack.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
8292    #if defined DEBUG_FORCE_UNOPTIMIZED_CBRAS && DEBUG_FORCE_UNOPTIMIZED_CBRAS == 2
8293    common->capture_last_ptr = common->ovector_start;
8294    common->ovector_start += sizeof(sljit_sw);
8295    #endif
8296  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);  private_data_size = get_private_data_length(common, rootbacktrack.cc, ccend);
8297  if (private_data_size < 0)  if (private_data_size < 0)
8298    {    {
# Line 7904  if (mode != JIT_COMPILE) Line 8313  if (mode != JIT_COMPILE)
8313    if (mode == JIT_PARTIAL_SOFT_COMPILE)    if (mode == JIT_PARTIAL_SOFT_COMPILE)
8314      {      {
8315      common->hit_start = common->ovector_start;      common->hit_start = common->ovector_start;
8316      common->ovector_start += sizeof(sljit_sw);      common->ovector_start += 2 * sizeof(sljit_sw);
8317        }
8318      else
8319        {
8320        SLJIT_ASSERT(mode == JIT_PARTIAL_HARD_COMPILE);
8321        common->needs_start_ptr = TRUE;
8322      }      }
8323    }    }
8324  if ((re->options & PCRE_FIRSTLINE) != 0)  if ((re->options & PCRE_FIRSTLINE) != 0)
# Line 7912  if ((re->options & PCRE_FIRSTLINE) != 0) Line 8326  if ((re->options & PCRE_FIRSTLINE) != 0)
8326    common->first_line_end = common->ovector_start;    common->first_line_end = common->ovector_start;
8327    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8328    }    }
8329    if (common->needs_start_ptr && common->has_set_som)
8330      {
8331      /* Saving the real start pointer is necessary. */
8332      common->start_ptr = common->ovector_start;
8333      common->ovector_start += sizeof(sljit_sw);
8334      }
8335    else
8336      common->needs_start_ptr = FALSE;
8337    
8338  /* Aligning ovector to even number of sljit words. */  /* Aligning ovector to even number of sljit words. */
8339  if ((common->ovector_start & sizeof(sljit_sw)) != 0)  if ((common->ovector_start & sizeof(sljit_sw)) != 0)
8340    common->ovector_start += sizeof(sljit_sw);    common->ovector_start += sizeof(sljit_sw);
8341    
8342    if (common->start_ptr == 0)
8343      common->start_ptr = OVECTOR(0);
8344    
8345    /* Capturing brackets cannot be optimized if callouts are allowed. */
8346    if (common->capture_last_ptr != 0)
8347      memset(common->optimized_cbracket, 0, re->top_bracket + 1);
8348    
8349  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));  SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
8350  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);  common->cbra_ptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_sw);
8351  private_data_size += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw);  private_data_size += common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw);
8352  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)  if (private_data_size > SLJIT_MAX_LOCAL_SIZE)
8353    {    {
8354    SLJIT_FREE(common->optimized_cbracket);    SLJIT_FREE(common->optimized_cbracket);
# Line 7932  if (!common->private_data_ptrs) Line 8361  if (!common->private_data_ptrs)
8361    return;    return;
8362    }    }
8363  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));  memset(common->private_data_ptrs, 0, (ccend - rootbacktrack.cc) * sizeof(int));
8364  set_private_data_ptrs(common, common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);  set_private_data_ptrs(common, common->cbra_ptr + (re->top_bracket + 1) * sizeof(sljit_sw), ccend);
8365    
8366  compiler = sljit_create_compiler();  compiler = sljit_create_compiler();
8367  if (!compiler)  if (!compiler)
# Line 7956  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1 Line 8385  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1
8385  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
8386  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
8387  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
8388  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, calllimit));  OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, call_limit));
8389  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, base));
8390  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
8391  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
8392    
8393  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8394    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
8395    
8396  /* Main part of the matching */  /* Main part of the matching */
8397  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
# Line 7981  if ((re->options & PCRE_ANCHORED) == 0) Line 8410  if ((re->options & PCRE_ANCHORED) == 0)
8410        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);        fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
8411      }      }
8412    }    }
8413    if (mode == JIT_COMPILE && study->minlength > 0 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)
8414      {
8415      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8416      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
8417      minlength_check_failed = CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0);
8418      }
8419  if (common->req_char_ptr != 0)  if (common->req_char_ptr != 0)
8420    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
8421    
# Line 7990  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 8425  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
8425  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
8426  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
8427    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
8428    if (common->capture_last_ptr != 0)
8429      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr, SLJIT_IMM, -1);
8430    
8431    if (common->needs_start_ptr)
8432      {
8433      SLJIT_ASSERT(common->start_ptr != OVECTOR(0));
8434      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr, STR_PTR, 0);
8435      }
8436    else
8437      SLJIT_ASSERT(common->start_ptr == OVECTOR(0));
8438    
8439  /* Copy the beginning of the string. */  /* Copy the beginning of the string. */
8440  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8441    {    {
8442    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
8443    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
8444      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start + sizeof(sljit_sw), STR_PTR, 0);
8445    JUMPHERE(jump);    JUMPHERE(jump);
8446    }    }
8447  else if (mode == JIT_PARTIAL_HARD_COMPILE)  else if (mode == JIT_PARTIAL_HARD_COMPILE)
# Line 8010  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 8457  if (SLJIT_UNLIKELY(sljit_get_compiler_er
8457    }    }
8458    
8459  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  empty_match = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
8460  empty_match_found = LABEL();  empty_match_found_label = LABEL();
8461    
8462  common->acceptlabel = LABEL();  common->accept_label = LABEL();
8463  if (common->accept != NULL)  if (common->accept != NULL)
8464    set_jumps(common->accept, common->acceptlabel);    set_jumps(common->accept, common->accept_label);
8465    
8466  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
8467  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
8468  common->quitlabel = LABEL();  common->quit_label = common->forced_quit_label = LABEL();
8469  if (common->quit != NULL)  if (common->quit != NULL)
8470    set_jumps(common->quit, common->quitlabel);    set_jumps(common->quit, common->quit_label);
8471    if (common->forced_quit != NULL)
8472      set_jumps(common->forced_quit, common->forced_quit_label);
8473    if (minlength_check_failed != NULL)
8474      SET_LABEL(minlength_check_failed, common->forced_quit_label);
8475  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
8476    
8477  if (mode != JIT_COMPILE)  if (mode != JIT_COMPILE)
8478    {    {
8479    common->partialmatchlabel = LABEL();    common->partialmatchlabel = LABEL();
8480    set_jumps(common->partialmatch, common->partialmatchlabel);    set_jumps(common->partialmatch, common->partialmatchlabel);
8481    return_with_partial_match(common, common->quitlabel);    return_with_partial_match(common, common->quit_label);
8482    }    }
8483    
8484  empty_match_backtrack = LABEL();  empty_match_backtrack_label = LABEL();
8485  compile_backtrackingpath(common, rootbacktrack.top);  compile_backtrackingpath(common, rootbacktrack.top);
8486  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
8487    {    {
# Line 8041  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 8492  if (SLJIT_UNLIKELY(sljit_get_compiler_er
8492    }    }
8493    
8494  SLJIT_ASSERT(rootbacktrack.prev == NULL);  SLJIT_ASSERT(rootbacktrack.prev == NULL);
8495    reset_match_label = LABEL();
8496    
8497  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8498    {    {
8499    /* Update hit_start only in the first time. */    /* Update hit_start only in the first time. */
8500    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
8501    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
8502    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
8503    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
# Line 8053  if (mode == JIT_PARTIAL_SOFT_COMPILE) Line 8505  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8505    }    }
8506    
8507  /* Check we have remaining characters. */  /* Check we have remaining characters. */
8508  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if ((re->options & PCRE_ANCHORED) == 0 && (re->options & PCRE_FIRSTLINE) != 0)
8509      {
8510      SLJIT_ASSERT(common->first_line_end != 0);
8511      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
8512      }
8513    
8514    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
8515    
8516  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
8517    {    {
8518    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
8519      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);  
     }  
8520    else    else
8521      {      CMPTO(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0, mainloop);
     SLJIT_ASSERT(common->first_line_end != 0);  
     if (mode == JIT_COMPILE && study != NULL && study->minlength > 1 && (re->options & PCRE_NO_START_OPTIMIZE) == 0)  
       {  
       OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength + 1));  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);  
       OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER);  
       OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);  
       OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);  
       JUMPTO(SLJIT_C_ZERO, mainloop);  
       }  
     else  
       CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);  
     }  
8522    }    }
8523    
8524  /* No more remaining characters. */  /* No more remaining characters. */
# Line 8089  if (reqbyte_notfound != NULL) Line 8526  if (reqbyte_notfound != NULL)
8526    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
8527    
8528  if (mode == JIT_PARTIAL_SOFT_COMPILE)  if (mode == JIT_PARTIAL_SOFT_COMPILE)
8529    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);    CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1, common->partialmatchlabel);
8530    
8531  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
8532  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8533    
8534  flush_stubs(common);  flush_stubs(common);
8535    
8536  JUMPHERE(empty_match);  JUMPHERE(empty_match);
8537  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
8538  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));
8539  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_backtrack_label);
8540  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));
8541  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found);  CMPTO(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0, empty_match_found_label);
8542  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));
8543  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, empty_match_found_label);
8544  JUMPTO(SLJIT_JUMP, empty_match_backtrack);  JUMPTO(SLJIT_JUMP, empty_match_backtrack_label);
8545    
8546  common->currententry = common->entries;  common->currententry = common->entries;
8547    common->in_recurse = TRUE;
8548    quit_label = common->quit_label;
8549  while (common->currententry != NULL)  while (common->currententry != NULL)
8550    {    {
8551    /* Might add new entries. */    /* Might add new entries. */
# Line 8121  while (common->currententry != NULL) Line 8560  while (common->currententry != NULL)
8560    flush_stubs(common);    flush_stubs(common);
8561    common->currententry = common->currententry->next;    common->currententry = common->currententry->next;
8562    }    }
8563    common->in_recurse = FALSE;
8564    common->quit_label = quit_label;
8565    
8566  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */  /* Allocating stack, returns with PCRE_ERROR_JIT_STACKLIMIT if fails. */
8567  /* This is a (really) rare case. */  /* This is a (really) rare case. */
# Line 8146  sljit_emit_fast_return(compiler, SLJIT_M Line 8587  sljit_emit_fast_return(compiler, SLJIT_M
8587  JUMPHERE(jump);  JUMPHERE(jump);
8588  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
8589  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
8590  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8591    
8592  /* Call limit reached. */  /* Call limit reached. */
8593  set_jumps(common->calllimit, LABEL());  set_jumps(common->calllimit, LABEL());
8594  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_MATCHLIMIT);
8595  JUMPTO(SLJIT_JUMP, common->quitlabel);  JUMPTO(SLJIT_JUMP, common->quit_label);
8596    
8597  if (common->revertframes != NULL)  if (common->revertframes != NULL)
8598    {    {
# Line 8188  if (common->caselesscmp != NULL) Line 8629  if (common->caselesscmp != NULL)
8629    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
8630    do_caselesscmp(common);    do_caselesscmp(common);
8631    }    }
8632    if (common->reset_match != NULL)
8633      {
8634      set_jumps(common->reset_match, LABEL());
8635      do_reset_match(common, (re->top_bracket + 1) * 2);
8636      JUMPTO(SLJIT_JUMP, reset_match_label);
8637      }
8638  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
8639  #ifndef COMPILE_PCRE32  #ifndef COMPILE_PCRE32
8640  if (common->utfreadchar != NULL)  if (common->utfreadchar != NULL)
# Line 8272  return convert_executable_func.call_exec Line 8719  return convert_executable_func.call_exec
8719    
8720  int  int
8721  PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,  PRIV(jit_exec)(const PUBL(extra) *extra_data, const pcre_uchar *subject,
8722    int length, int start_offset, int options, int *offsets, int offsetcount)    int length, int start_offset, int options, int *offsets, int offset_count)
8723  {  {
8724  executable_functions *functions = (executable_functions *)extra_data->executable_jit;  executable_functions *functions = (executable_functions *)extra_data->executable_jit;
8725  union {  union {
# Line 8280  union { Line 8727  union {
8727     jit_function call_executable_func;     jit_function call_executable_func;
8728  } convert_executable_func;  } convert_executable_func;
8729  jit_arguments arguments;  jit_arguments arguments;
8730  int maxoffsetcount;  int max_offset_count;
8731  int retval;  int retval;
8732  int mode = JIT_COMPILE;  int mode = JIT_COMPILE;
8733    
# Line 8298  arguments.begin = subject; Line 8745  arguments.begin = subject;
8745  arguments.end = subject + length;  arguments.end = subject + length;
8746  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
8747  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
8748  arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
8749  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
8750  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
8751  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
8752  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
8753  arguments.offsets = offsets;  arguments.offsets = offsets;
8754    arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
8755    arguments.real_offset_count = offset_count;
8756    
8757  /* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
8758  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
8759  workspace. We don't need the workspace here. For compatibility, we limit the  workspace. We don't need the workspace here. For compatibility, we limit the
8760  number of captured strings in the same way as pcre_exec(), so that the user  number of captured strings in the same way as pcre_exec(), so that the user
8761  gets the same result with and without JIT. */  gets the same result with and without JIT. */
8762    
8763  if (offsetcount != 2)  if (offset_count != 2)
8764    offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;    offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
8765  maxoffsetcount = functions->top_bracket;  max_offset_count = functions->top_bracket;
8766  if (offsetcount > maxoffsetcount)  if (offset_count > max_offset_count)
8767    offsetcount = maxoffsetcount;    offset_count = max_offset_count;
8768  arguments.offsetcount = offsetcount;  arguments.offset_count = offset_count;
8769    
8770  if (functions->callback)  if (functions->callback)
8771    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
# Line 8331  else Line 8780  else
8780    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
8781    }    }
8782    
8783  if (retval * 2 > offsetcount)  if (retval * 2 > offset_count)
8784    retval = 0;    retval = 0;
8785  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
8786    *(extra_data->mark) = arguments.mark_ptr;    *(extra_data->mark) = arguments.mark_ptr;
# Line 8343  return retval; Line 8792  return retval;
8792  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8793  pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,  pcre_jit_exec(const pcre *argument_re, const pcre_extra *extra_data,
8794    PCRE_SPTR subject, int length, int start_offset, int options,    PCRE_SPTR subject, int length, int start_offset, int options,
8795    int *offsets, int offsetcount, pcre_jit_stack *stack)    int *offsets, int offset_count, pcre_jit_stack *stack)
8796  #elif defined COMPILE_PCRE16  #elif defined COMPILE_PCRE16
8797  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8798  pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,  pcre16_jit_exec(const pcre16 *argument_re, const pcre16_extra *extra_data,
8799    PCRE_SPTR16 subject, int length, int start_offset, int options,    PCRE_SPTR16 subject, int length, int start_offset, int options,
8800    int *offsets, int offsetcount, pcre16_jit_stack *stack)    int *offsets, int offset_count, pcre16_jit_stack *stack)
8801  #elif defined COMPILE_PCRE32  #elif defined COMPILE_PCRE32
8802  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION  PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
8803  pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,  pcre32_jit_exec(const pcre32 *argument_re, const pcre32_extra *extra_data,
8804    PCRE_SPTR32 subject, int length, int start_offset, int options,    PCRE_SPTR32 subject, int length, int start_offset, int options,
8805    int *offsets, int offsetcount, pcre32_jit_stack *stack)    int *offsets, int offset_count, pcre32_jit_stack *stack)
8806  #endif  #endif
8807  {  {
8808  pcre_uchar *subject_ptr = (pcre_uchar *)subject;  pcre_uchar *subject_ptr = (pcre_uchar *)subject;
# Line 8363  union { Line 8812  union {
8812     jit_function call_executable_func;     jit_function call_executable_func;
8813  } convert_executable_func;  } convert_executable_func;
8814  jit_arguments arguments;  jit_arguments arguments;
8815  int maxoffsetcount;  int max_offset_count;
8816  int retval;  int retval;
8817  int mode = JIT_COMPILE;  int mode = JIT_COMPILE;
8818    
# Line 8387  arguments.begin = subject_ptr; Line 8836  arguments.begin = subject_ptr;
8836  arguments.end = subject_ptr + length;  arguments.end = subject_ptr + length;
8837  arguments.mark_ptr = NULL;  arguments.mark_ptr = NULL;
8838  /* JIT decreases this value less frequently than the interpreter. */  /* JIT decreases this value less frequently than the interpreter. */
8839  arguments.calllimit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;  arguments.call_limit = ((extra_data->flags & PCRE_EXTRA_MATCH_LIMIT) == 0) ? MATCH_LIMIT : extra_data->match_limit;
8840  arguments.notbol = (options & PCRE_NOTBOL) != 0;  arguments.notbol = (options & PCRE_NOTBOL) != 0;
8841  arguments.noteol = (options & PCRE_NOTEOL) != 0;  arguments.noteol = (options & PCRE_NOTEOL) != 0;
8842  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;  arguments.notempty = (options & PCRE_NOTEMPTY) != 0;
8843  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;  arguments.notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
8844  arguments.offsets = offsets;  arguments.offsets = offsets;
8845    arguments.callout_data = (extra_data->flags & PCRE_EXTRA_CALLOUT_DATA) != 0 ? extra_data->callout_data : NULL;
8846    arguments.real_offset_count = offset_count;
8847    
8848  /* pcre_exec() rounds offsetcount to a multiple of 3, and then uses only 2/3 of  /* pcre_exec() rounds offset_count to a multiple of 3, and then uses only 2/3 of
8849  the output vector for storing captured strings, with the remainder used as  the output vector for storing captured strings, with the remainder used as
8850  workspace. We don't need the workspace here. For compatibility, we limit the  workspace. We don't need the workspace here. For compatibility, we limit the
8851  number of captured strings in the same way as pcre_exec(), so that the user  number of captured strings in the same way as pcre_exec(), so that the user
8852  gets the same result with and without JIT. */  gets the same result with and without JIT. */
8853    
8854  if (offsetcount != 2)  if (offset_count != 2)
8855    offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;    offset_count = ((offset_count - (offset_count % 3)) * 2) / 3;
8856  maxoffsetcount = functions->top_bracket;  max_offset_count = functions->top_bracket;
8857  if (offsetcount > maxoffsetcount)  if (offset_count > max_offset_count)
8858    offsetcount = maxoffsetcount;    offset_count = max_offset_count;
8859  arguments.offsetcount = offsetcount;  arguments.offset_count = offset_count;
8860    
8861  convert_executable_func.executable_func = functions->executable_funcs[mode];  convert_executable_func.executable_func = functions->executable_funcs[mode];
8862  retval = convert_executable_func.call_executable_func(&arguments);  retval = convert_executable_func.call_executable_func(&arguments);
8863    
8864  if (retval * 2 > offsetcount)  if (retval * 2 > offset_count)
8865    retval = 0;    retval = 0;
8866  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)  if ((extra_data->flags & PCRE_EXTRA_MARK) != 0)
8867    *(extra_data->mark) = arguments.mark_ptr;    *(extra_data->mark) = arguments.mark_ptr;

Legend:
Removed from v.1221  
changed lines
  Added in v.1272

  ViewVC Help
Powered by ViewVC 1.1.5