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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 915 by zherczeg, Tue Feb 14 13:05:39 2012 UTC revision 995 by zherczeg, Wed Jul 11 11:05:30 2012 UTC
# Line 82  The code generator follows the recursive Line 82  The code generator follows the recursive
82  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
83  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
84  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
85  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
86    
87    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
88    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
92  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the try path (expected path), and the other is called as
93  the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94  branches on the hot path.  branches on the try path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Hot path: match happens.     Try path: match happens.
98     Fallback path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Hot path: no need to perform a match.     Try path: no need to perform a match.
101     Fallback path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
104  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# Line 108  we have the following regular expression Line 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A hot path   A try path
112   '(' hot path (pushing arguments to the stack)   '(' try path (pushing arguments to the stack)
113   B hot path   B try path
114   ')' hot path (pushing arguments to the stack)   ')' try path (pushing arguments to the stack)
115   D hot path   D try path
116   return with successful match   return with successful match
117    
118   D fallback path   D backtrack path
119   ')' fallback path (If we arrived from "C" jump to the fallback of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120   B fallback path   B backtrack path
121   C expected path   C expected path
122   jump to D hot path   jump to D try path
123   C fallback path   C backtrack path
124   A fallback path   A backtrack path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of backtrack code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
129   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
130   the hot path eventually. Otherwise it needs to clear out its own stack   the try path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
134  /*  /*
135  Saved stack frames:  Saved stack frames:
136    
137  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of local variables
138  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the locals
139  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
140  mechanism.  mechanism.
141    
# Line 152  typedef struct jit_arguments { Line 152  typedef struct jit_arguments {
152    const pcre_uchar *begin;    const pcre_uchar *begin;
153    const pcre_uchar *end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    pcre_uchar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
# Line 180  typedef struct stub_list { Line 181  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
182    int data;    int data;
183    struct sljit_jump *start;    struct sljit_jump *start;
184    struct sljit_label *leave;    struct sljit_label *quit;
185    struct stub_list *next;    struct stub_list *next;
186  } stub_list;  } stub_list;
187    
188  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189    
190  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
191  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_trypath, and contains
192  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackpath. Must be the first member
193  of its descendants. */  of its descendants. */
194  typedef struct fallback_common {  typedef struct backtrack_common {
195    /* Concatenation stack. */    /* Concatenation stack. */
196    struct fallback_common *prev;    struct backtrack_common *prev;
197    jump_list *nextfallbacks;    jump_list *nextbacktracks;
198    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
199    struct fallback_common *top;    struct backtrack_common *top;
200    jump_list *topfallbacks;    jump_list *topbacktracks;
201    /* Opcode pointer. */    /* Opcode pointer. */
202    pcre_uchar *cc;    pcre_uchar *cc;
203  } fallback_common;  } backtrack_common;
204    
205  typedef struct assert_fallback {  typedef struct assert_backtrack {
206    fallback_common common;    backtrack_common common;
207    jump_list *condfailed;    jump_list *condfailed;
208    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
209    int framesize;    int framesize;
210    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
211    int localptr;    int localptr;
212    /* For iterators. */    /* For iterators. */
213    struct sljit_label *hotpath;    struct sljit_label *trypath;
214  } assert_fallback;  } assert_backtrack;
215    
216  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
217    fallback_common common;    backtrack_common common;
218    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
219    struct sljit_label *althotpath;    struct sljit_label *alttrypath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivehotpath;    struct sljit_label *recursivetrypath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerohotpath;    struct sljit_label *zerotrypath;
224    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
225    union {    union {
226      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
227      jump_list *condfailed;      jump_list *condfailed;
228      assert_fallback *assert;      assert_backtrack *assert;
229      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
230      int framesize;      int framesize;
231    } u;    } u;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int localptr;    int localptr;
234  } bracket_fallback;  } bracket_backtrack;
235    
236  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
237    fallback_common common;    backtrack_common common;
238    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
239    int localptr;    int localptr;
240    /* Reverting stack is needed. */    /* Reverting stack is needed. */
241    int framesize;    int framesize;
242    /* Allocated stack size. */    /* Allocated stack size. */
243    int stacksize;    int stacksize;
244  } bracketpos_fallback;  } bracketpos_backtrack;
245    
246  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
247    fallback_common common;    backtrack_common common;
248    struct sljit_label *hotpath;    struct sljit_label *trypath;
249  } braminzero_fallback;  } braminzero_backtrack;
250    
251  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
252    fallback_common common;    backtrack_common common;
253    /* Next iteration. */    /* Next iteration. */
254    struct sljit_label *hotpath;    struct sljit_label *trypath;
255  } iterator_fallback;  } iterator_backtrack;
256    
257  typedef struct recurse_entry {  typedef struct recurse_entry {
258    struct recurse_entry *next;    struct recurse_entry *next;
# Line 263  typedef struct recurse_entry { Line 264  typedef struct recurse_entry {
264    int start;    int start;
265  } recurse_entry;  } recurse_entry;
266    
267  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
268    fallback_common common;    backtrack_common common;
269  } recurse_fallback;  } recurse_backtrack;
270    
271    #define MAX_RANGE_SIZE 6
272    
273  typedef struct compiler_common {  typedef struct compiler_common {
274    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
275    pcre_uchar *start;    pcre_uchar *start;
276    int localsize;  
277      /* Opcode local area direct map. */
278    int *localptrs;    int *localptrs;
279      int cbraptr;
280      /* OVector starting point. Must be divisible by 2. */
281      int ovector_start;
282      /* Last known position of the requested byte. */
283      int req_char_ptr;
284      /* Head of the last recursion. */
285      int recursive_head;
286      /* First inspected character for partial matching. */
287      int start_used_ptr;
288      /* Starting pointer for partial soft matches. */
289      int hit_start;
290      /* End pointer of the first line. */
291      int first_line_end;
292      /* Points to the marked string. */
293      int mark_ptr;
294    
295      /* Flipped and lower case tables. */
296    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
297    sljit_w lcc;    sljit_w lcc;
298    int cbraptr;    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
299    int mode;    int mode;
300      /* Newline control. */
301    int nltype;    int nltype;
302    int newline;    int newline;
303    int bsr_nltype;    int bsr_nltype;
304      /* Dollar endonly. */
305    int endonly;    int endonly;
306      BOOL has_set_som;
307      /* Tables. */
308    sljit_w ctypes;    sljit_w ctypes;
309      int digits[2 + MAX_RANGE_SIZE];
310      /* Named capturing brackets. */
311    sljit_uw name_table;    sljit_uw name_table;
312    sljit_w name_count;    sljit_w name_count;
313    sljit_w name_entry_size;    sljit_w name_entry_size;
314    
315      /* Labels and jump lists. */
316    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
317      struct sljit_label *quitlabel;
318    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
319    stub_list *stubs;    stub_list *stubs;
320    recurse_entry *entries;    recurse_entry *entries;
321    recurse_entry *currententry;    recurse_entry *currententry;
322    jump_list *partialmatch;    jump_list *partialmatch;
323      jump_list *quit;
324    jump_list *accept;    jump_list *accept;
325    jump_list *calllimit;    jump_list *calllimit;
326    jump_list *stackalloc;    jump_list *stackalloc;
# Line 352  typedef struct compare_context { Line 383  typedef struct compare_context {
383    
384  enum {  enum {
385    frame_end = 0,    frame_end = 0,
386    frame_setstrbegin = -1    frame_setstrbegin = -1,
387      frame_setmark = -2
388  };  };
389    
390  /* Undefine sljit macros. */  /* Undefine sljit macros. */
# Line 379  enum { Line 411  enum {
411  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
412  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
413  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
414  /* Max limit of recursions. */  /* Max limit of recursions. */
415  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte.  
 Same as START_USED_PTR. (Partial matching and req_char are exclusive) */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* First inspected character for partial matching.  
 Same as REQ_CHAR_PTR. (Partial matching and req_char are exclusive) */  
 #define START_USED_PTR   (6 * sizeof(sljit_w))  
 /* Starting pointer for partial soft matches. */  
 #define HIT_START        (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * sizeof(sljit_w))  
416  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
417  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
418  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
419  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. */
420  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
421  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
422  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
423  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
# Line 435  the start pointers when the end of the c Line 455  the start pointers when the end of the c
455    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
456  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
457    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
458    #define GET_LOCAL_BASE(dst, dstw, offset) \
459      sljit_get_local_base(compiler, (dst), (dstw), (offset))
460    
461  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
462  {  {
# Line 453  return cc; Line 475  return cc;
475   init_frame   init_frame
476   get_localsize   get_localsize
477   copy_locals   copy_locals
478   compile_hotpath   compile_trypath
479   compile_fallbackpath   compile_backtrackpath
480  */  */
481    
482  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 506  switch(*cc) Line 528  switch(*cc)
528    case OP_BRAZERO:    case OP_BRAZERO:
529    case OP_BRAMINZERO:    case OP_BRAMINZERO:
530    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
531      case OP_COMMIT:
532    case OP_FAIL:    case OP_FAIL:
533    case OP_ACCEPT:    case OP_ACCEPT:
534    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 644  switch(*cc) Line 667  switch(*cc)
667    case OP_SCBRAPOS:    case OP_SCBRAPOS:
668    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
669    
670      case OP_MARK:
671      return cc + 1 + 2 + cc[1];
672    
673    default:    default:
674    return NULL;    return NULL;
675    }    }
676  }  }
677    
678    #define CASE_ITERATOR_LOCAL1 \
679        case OP_MINSTAR: \
680        case OP_MINPLUS: \
681        case OP_QUERY: \
682        case OP_MINQUERY: \
683        case OP_MINSTARI: \
684        case OP_MINPLUSI: \
685        case OP_QUERYI: \
686        case OP_MINQUERYI: \
687        case OP_NOTMINSTAR: \
688        case OP_NOTMINPLUS: \
689        case OP_NOTQUERY: \
690        case OP_NOTMINQUERY: \
691        case OP_NOTMINSTARI: \
692        case OP_NOTMINPLUSI: \
693        case OP_NOTQUERYI: \
694        case OP_NOTMINQUERYI:
695    
696    #define CASE_ITERATOR_LOCAL2A \
697        case OP_STAR: \
698        case OP_PLUS: \
699        case OP_STARI: \
700        case OP_PLUSI: \
701        case OP_NOTSTAR: \
702        case OP_NOTPLUS: \
703        case OP_NOTSTARI: \
704        case OP_NOTPLUSI:
705    
706    #define CASE_ITERATOR_LOCAL2B \
707        case OP_UPTO: \
708        case OP_MINUPTO: \
709        case OP_UPTOI: \
710        case OP_MINUPTOI: \
711        case OP_NOTUPTO: \
712        case OP_NOTMINUPTO: \
713        case OP_NOTUPTOI: \
714        case OP_NOTMINUPTOI:
715    
716    #define CASE_ITERATOR_TYPE_LOCAL1 \
717        case OP_TYPEMINSTAR: \
718        case OP_TYPEMINPLUS: \
719        case OP_TYPEQUERY: \
720        case OP_TYPEMINQUERY:
721    
722    #define CASE_ITERATOR_TYPE_LOCAL2A \
723        case OP_TYPESTAR: \
724        case OP_TYPEPLUS:
725    
726    #define CASE_ITERATOR_TYPE_LOCAL2B \
727        case OP_TYPEUPTO: \
728        case OP_TYPEMINUPTO:
729    
730    static int get_class_iterator_size(pcre_uchar *cc)
731    {
732    switch(*cc)
733      {
734      case OP_CRSTAR:
735      case OP_CRPLUS:
736      return 2;
737    
738      case OP_CRMINSTAR:
739      case OP_CRMINPLUS:
740      case OP_CRQUERY:
741      case OP_CRMINQUERY:
742      return 1;
743    
744      case OP_CRRANGE:
745      case OP_CRMINRANGE:
746      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
747        return 0;
748      return 2;
749    
750      default:
751      return 0;
752      }
753    }
754    
755  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
756  {  {
757  int localspace = 0;  int localspace = 0;
758  pcre_uchar *alternative;  pcre_uchar *alternative;
759    pcre_uchar *end = NULL;
760    int space, size, bracketlen;
761    
762  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
763  while (cc < ccend)  while (cc < ccend)
764    {    {
765      space = 0;
766      size = 0;
767      bracketlen = 0;
768    switch(*cc)    switch(*cc)
769      {      {
770        case OP_SET_SOM:
771        common->has_set_som = TRUE;
772        cc += 1;
773        break;
774    
775      case OP_ASSERT:      case OP_ASSERT:
776      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
777      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 669  while (cc < ccend) Line 783  while (cc < ccend)
783      case OP_SBRAPOS:      case OP_SBRAPOS:
784      case OP_SCOND:      case OP_SCOND:
785      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
786      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
787      break;      break;
788    
789      case OP_CBRAPOS:      case OP_CBRAPOS:
790      case OP_SCBRAPOS:      case OP_SCBRAPOS:
791      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
792      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
793      break;      break;
794    
795      case OP_COND:      case OP_COND:
# Line 683  while (cc < ccend) Line 797  while (cc < ccend)
797      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
798      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
799        localspace += sizeof(sljit_w);        localspace += sizeof(sljit_w);
800        bracketlen = 1 + LINK_SIZE;
801        break;
802    
803        case OP_BRA:
804        bracketlen = 1 + LINK_SIZE;
805        break;
806    
807        case OP_CBRA:
808        case OP_SCBRA:
809        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
810        break;
811    
812        CASE_ITERATOR_LOCAL1
813        space = 1;
814        size = -2;
815        break;
816    
817        CASE_ITERATOR_LOCAL2A
818        space = 2;
819        size = -2;
820        break;
821    
822        CASE_ITERATOR_LOCAL2B
823        space = 2;
824        size = -(2 + IMM2_SIZE);
825        break;
826    
827        CASE_ITERATOR_TYPE_LOCAL1
828        space = 1;
829        size = 1;
830        break;
831    
832        CASE_ITERATOR_TYPE_LOCAL2A
833        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
834          space = 2;
835        size = 1;
836        break;
837    
838        CASE_ITERATOR_TYPE_LOCAL2B
839        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
840          space = 2;
841        size = 1 + IMM2_SIZE;
842        break;
843    
844        case OP_CLASS:
845        case OP_NCLASS:
846        size += 1 + 32 / sizeof(pcre_uchar);
847        space = get_class_iterator_size(cc + size);
848        break;
849    
850    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
851        case OP_XCLASS:
852        size = GET(cc, 1);
853        space = get_class_iterator_size(cc + size);
854        break;
855    #endif
856    
857        case OP_RECURSE:
858        /* Set its value only once. */
859        if (common->recursive_head == 0)
860          {
861          common->recursive_head = common->ovector_start;
862          common->ovector_start += sizeof(sljit_w);
863          }
864      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
865      break;      break;
866    
867        case OP_MARK:
868        if (common->mark_ptr == 0)
869          {
870          common->mark_ptr = common->ovector_start;
871          common->ovector_start += sizeof(sljit_w);
872          }
873        cc += 1 + 2 + cc[1];
874        break;
875    
876      default:      default:
877      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
878      if (cc == NULL)      if (cc == NULL)
879        return -1;        return -1;
880      break;      break;
881      }      }
882    
883      if (space > 0 && cc >= end)
884        localspace += sizeof(sljit_w) * space;
885    
886      if (size != 0)
887        {
888        if (size < 0)
889          {
890          cc += -size;
891    #ifdef SUPPORT_UTF
892          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
893    #endif
894          }
895        else
896          cc += size;
897        }
898    
899      if (bracketlen > 0)
900        {
901        if (cc >= end)
902          {
903          end = bracketend(cc);
904          if (end[-1 - LINK_SIZE] == OP_KET)
905            end = NULL;
906          }
907        cc += bracketlen;
908        }
909    }    }
910  return localspace;  return localspace;
911  }  }
# Line 700  static void set_localptrs(compiler_commo Line 914  static void set_localptrs(compiler_commo
914  {  {
915  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
916  pcre_uchar *alternative;  pcre_uchar *alternative;
917    pcre_uchar *end = NULL;
918    int space, size, bracketlen;
919    
920  while (cc < ccend)  while (cc < ccend)
921    {    {
922      space = 0;
923      size = 0;
924      bracketlen = 0;
925    switch(*cc)    switch(*cc)
926      {      {
927      case OP_ASSERT:      case OP_ASSERT:
# Line 716  while (cc < ccend) Line 936  while (cc < ccend)
936      case OP_SCOND:      case OP_SCOND:
937      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
938      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
939      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
940      break;      break;
941    
942      case OP_CBRAPOS:      case OP_CBRAPOS:
943      case OP_SCBRAPOS:      case OP_SCBRAPOS:
944      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
945      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
946      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      case OP_COND:      case OP_COND:
# Line 734  while (cc < ccend) Line 954  while (cc < ccend)
954        common->localptrs[cc - common->start] = localptr;        common->localptrs[cc - common->start] = localptr;
955        localptr += sizeof(sljit_w);        localptr += sizeof(sljit_w);
956        }        }
957      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
958      break;      break;
959    
960        case OP_BRA:
961        bracketlen = 1 + LINK_SIZE;
962        break;
963    
964        case OP_CBRA:
965        case OP_SCBRA:
966        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
967        break;
968    
969        CASE_ITERATOR_LOCAL1
970        space = 1;
971        size = -2;
972        break;
973    
974        CASE_ITERATOR_LOCAL2A
975        space = 2;
976        size = -2;
977        break;
978    
979        CASE_ITERATOR_LOCAL2B
980        space = 2;
981        size = -(2 + IMM2_SIZE);
982        break;
983    
984        CASE_ITERATOR_TYPE_LOCAL1
985        space = 1;
986        size = 1;
987        break;
988    
989        CASE_ITERATOR_TYPE_LOCAL2A
990        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
991          space = 2;
992        size = 1;
993        break;
994    
995        CASE_ITERATOR_TYPE_LOCAL2B
996        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
997          space = 2;
998        size = 1 + IMM2_SIZE;
999        break;
1000    
1001        case OP_CLASS:
1002        case OP_NCLASS:
1003        size += 1 + 32 / sizeof(pcre_uchar);
1004        space = get_class_iterator_size(cc + size);
1005        break;
1006    
1007    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1008        case OP_XCLASS:
1009        size = GET(cc, 1);
1010        space = get_class_iterator_size(cc + size);
1011        break;
1012    #endif
1013    
1014      default:      default:
1015      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1016      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1017      break;      break;
1018      }      }
1019    
1020      if (space > 0 && cc >= end)
1021        {
1022        common->localptrs[cc - common->start] = localptr;
1023        localptr += sizeof(sljit_w) * space;
1024        }
1025    
1026      if (size != 0)
1027        {
1028        if (size < 0)
1029          {
1030          cc += -size;
1031    #ifdef SUPPORT_UTF
1032          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1033    #endif
1034          }
1035        else
1036          cc += size;
1037        }
1038    
1039      if (bracketlen > 0)
1040        {
1041        if (cc >= end)
1042          {
1043          end = bracketend(cc);
1044          if (end[-1 - LINK_SIZE] == OP_KET)
1045            end = NULL;
1046          }
1047        cc += bracketlen;
1048        }
1049    }    }
1050  }  }
1051    
# Line 751  static int get_framesize(compiler_common Line 1055  static int get_framesize(compiler_common
1055  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1056  int length = 0;  int length = 0;
1057  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1058  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1059    BOOL setmark_found = recursive;
1060    
1061  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1062    {    {
# Line 765  while (cc < ccend) Line 1070  while (cc < ccend)
1070    switch(*cc)    switch(*cc)
1071      {      {
1072      case OP_SET_SOM:      case OP_SET_SOM:
1073      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1074      if (!setsom_found)      if (!setsom_found)
1075        {        {
1076        length += 2;        length += 2;
1077        setsom_found = TRUE;        setsom_found = TRUE;
1078        }        }
1079      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1080        break;
1081    
1082        case OP_MARK:
1083        SLJIT_ASSERT(common->mark_ptr != 0);
1084        if (!setmark_found)
1085          {
1086          length += 2;
1087          setmark_found = TRUE;
1088          }
1089        cc += 1 + 2 + cc[1];
1090        break;
1091    
1092        case OP_RECURSE:
1093        if (common->has_set_som && !setsom_found)
1094          {
1095          length += 2;
1096          setsom_found = TRUE;
1097          }
1098        if (common->mark_ptr != 0 && !setmark_found)
1099          {
1100          length += 2;
1101          setmark_found = TRUE;
1102          }
1103        cc += 1 + LINK_SIZE;
1104      break;      break;
1105    
1106      case OP_CBRA:      case OP_CBRA:
# Line 801  static void init_frame(compiler_common * Line 1130  static void init_frame(compiler_common *
1130  {  {
1131  DEFINE_COMPILER;  DEFINE_COMPILER;
1132  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1133  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1134    BOOL setmark_found = recursive;
1135  int offset;  int offset;
1136    
1137  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 816  while (cc < ccend) Line 1146  while (cc < ccend)
1146    switch(*cc)    switch(*cc)
1147      {      {
1148      case OP_SET_SOM:      case OP_SET_SOM:
1149      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1150      if (!setsom_found)      if (!setsom_found)
1151        {        {
1152        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 826  while (cc < ccend) Line 1156  while (cc < ccend)
1156        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1157        setsom_found = TRUE;        setsom_found = TRUE;
1158        }        }
1159      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1160        break;
1161    
1162        case OP_MARK:
1163        SLJIT_ASSERT(common->mark_ptr != 0);
1164        if (!setmark_found)
1165          {
1166          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1167          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1168          stackpos += (int)sizeof(sljit_w);
1169          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1170          stackpos += (int)sizeof(sljit_w);
1171          setmark_found = TRUE;
1172          }
1173        cc += 1 + 2 + cc[1];
1174        break;
1175    
1176        case OP_RECURSE:
1177        if (common->has_set_som && !setsom_found)
1178          {
1179          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1180          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1181          stackpos += (int)sizeof(sljit_w);
1182          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1183          stackpos += (int)sizeof(sljit_w);
1184          setsom_found = TRUE;
1185          }
1186        if (common->mark_ptr != 0 && !setmark_found)
1187          {
1188          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1189          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1190          stackpos += (int)sizeof(sljit_w);
1191          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1192          stackpos += (int)sizeof(sljit_w);
1193          setmark_found = TRUE;
1194          }
1195        cc += 1 + LINK_SIZE;
1196      break;      break;
1197    
1198      case OP_CBRA:      case OP_CBRA:
# Line 859  SLJIT_ASSERT(stackpos == STACK(stacktop) Line 1225  SLJIT_ASSERT(stackpos == STACK(stacktop)
1225  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1226  {  {
1227  int localsize = 2;  int localsize = 2;
1228    int size;
1229  pcre_uchar *alternative;  pcre_uchar *alternative;
1230  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
1231  while (cc < ccend)  while (cc < ccend)
1232    {    {
1233      size = 0;
1234    switch(*cc)    switch(*cc)
1235      {      {
1236      case OP_ASSERT:      case OP_ASSERT:
# Line 899  while (cc < ccend) Line 1267  while (cc < ccend)
1267      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1268      break;      break;
1269    
1270        CASE_ITERATOR_LOCAL1
1271        if (PRIV_DATA(cc))
1272          localsize++;
1273        cc += 2;
1274    #ifdef SUPPORT_UTF
1275        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1276    #endif
1277        break;
1278    
1279        CASE_ITERATOR_LOCAL2A
1280        if (PRIV_DATA(cc))
1281          localsize += 2;
1282        cc += 2;
1283    #ifdef SUPPORT_UTF
1284        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1285    #endif
1286        break;
1287    
1288        CASE_ITERATOR_LOCAL2B
1289        if (PRIV_DATA(cc))
1290          localsize += 2;
1291        cc += 2 + IMM2_SIZE;
1292    #ifdef SUPPORT_UTF
1293        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1294    #endif
1295        break;
1296    
1297        CASE_ITERATOR_TYPE_LOCAL1
1298        if (PRIV_DATA(cc))
1299          localsize++;
1300        cc += 1;
1301        break;
1302    
1303        CASE_ITERATOR_TYPE_LOCAL2A
1304        if (PRIV_DATA(cc))
1305          localsize += 2;
1306        cc += 1;
1307        break;
1308    
1309        CASE_ITERATOR_TYPE_LOCAL2B
1310        if (PRIV_DATA(cc))
1311          localsize += 2;
1312        cc += 1 + IMM2_SIZE;
1313        break;
1314    
1315        case OP_CLASS:
1316        case OP_NCLASS:
1317    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1318        case OP_XCLASS:
1319        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1320    #else
1321        size = 1 + 32 / (int)sizeof(pcre_uchar);
1322    #endif
1323        if (PRIV_DATA(cc))
1324          localsize += get_class_iterator_size(cc + size);
1325        cc += size;
1326        break;
1327    
1328      default:      default:
1329      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1330      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 914  static void copy_locals(compiler_common Line 1340  static void copy_locals(compiler_common
1340  {  {
1341  DEFINE_COMPILER;  DEFINE_COMPILER;
1342  int srcw[2];  int srcw[2];
1343  int count;  int count, size;
1344  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1345  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1346  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 953  while (status != end) Line 1379  while (status != end)
1379    switch(status)    switch(status)
1380      {      {
1381      case start:      case start:
1382      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1383      count = 1;      count = 1;
1384      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1385      status = loop;      status = loop;
1386      break;      break;
1387    
# Line 994  while (status != end) Line 1420  while (status != end)
1420        case OP_CBRAPOS:        case OP_CBRAPOS:
1421        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1422        count = 2;        count = 2;
1423        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1424        srcw[0] = PRIV_DATA(cc);        srcw[1] = PRIV_DATA(cc);
1425        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1426        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1427        break;        break;
# Line 1005  while (status != end) Line 1431  while (status != end)
1431        alternative = cc + GET(cc, 1);        alternative = cc + GET(cc, 1);
1432        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1433          {          {
1434          count = 1;          count = 1;
1435            srcw[0] = PRIV_DATA(cc);
1436            SLJIT_ASSERT(srcw[0] != 0);
1437            }
1438          cc += 1 + LINK_SIZE;
1439          break;
1440    
1441          CASE_ITERATOR_LOCAL1
1442          if (PRIV_DATA(cc))
1443            {
1444            count = 1;
1445            srcw[0] = PRIV_DATA(cc);
1446            }
1447          cc += 2;
1448    #ifdef SUPPORT_UTF
1449          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1450    #endif
1451          break;
1452    
1453          CASE_ITERATOR_LOCAL2A
1454          if (PRIV_DATA(cc))
1455            {
1456            count = 2;
1457            srcw[0] = PRIV_DATA(cc);
1458            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1459            }
1460          cc += 2;
1461    #ifdef SUPPORT_UTF
1462          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1463    #endif
1464          break;
1465    
1466          CASE_ITERATOR_LOCAL2B
1467          if (PRIV_DATA(cc))
1468            {
1469            count = 2;
1470            srcw[0] = PRIV_DATA(cc);
1471            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1472            }
1473          cc += 2 + IMM2_SIZE;
1474    #ifdef SUPPORT_UTF
1475          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1476    #endif
1477          break;
1478    
1479          CASE_ITERATOR_TYPE_LOCAL1
1480          if (PRIV_DATA(cc))
1481            {
1482            count = 1;
1483            srcw[0] = PRIV_DATA(cc);
1484            }
1485          cc += 1;
1486          break;
1487    
1488          CASE_ITERATOR_TYPE_LOCAL2A
1489          if (PRIV_DATA(cc))
1490            {
1491            count = 2;
1492            srcw[0] = PRIV_DATA(cc);
1493            srcw[1] = srcw[0] + sizeof(sljit_w);
1494            }
1495          cc += 1;
1496          break;
1497    
1498          CASE_ITERATOR_TYPE_LOCAL2B
1499          if (PRIV_DATA(cc))
1500            {
1501            count = 2;
1502          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIV_DATA(cc);
1503          SLJIT_ASSERT(srcw[0] != 0);          srcw[1] = srcw[0] + sizeof(sljit_w);
1504          }          }
1505        cc += 1 + LINK_SIZE;        cc += 1 + IMM2_SIZE;
1506          break;
1507    
1508          case OP_CLASS:
1509          case OP_NCLASS:
1510    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1511          case OP_XCLASS:
1512          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1513    #else
1514          size = 1 + 32 / (int)sizeof(pcre_uchar);
1515    #endif
1516          if (PRIV_DATA(cc))
1517            switch(get_class_iterator_size(cc + size))
1518              {
1519              case 1:
1520              count = 1;
1521              srcw[0] = PRIV_DATA(cc);
1522              break;
1523    
1524              case 2:
1525              count = 2;
1526              srcw[0] = PRIV_DATA(cc);
1527              srcw[1] = srcw[0] + sizeof(sljit_w);
1528              break;
1529    
1530              default:
1531              SLJIT_ASSERT_STOP();
1532              break;
1533              }
1534          cc += size;
1535        break;        break;
1536    
1537        default:        default:
# Line 1114  if (save) Line 1636  if (save)
1636  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1637  }  }
1638    
1639    #undef CASE_ITERATOR_LOCAL1
1640    #undef CASE_ITERATOR_LOCAL2A
1641    #undef CASE_ITERATOR_LOCAL2B
1642    #undef CASE_ITERATOR_TYPE_LOCAL1
1643    #undef CASE_ITERATOR_TYPE_LOCAL2A
1644    #undef CASE_ITERATOR_TYPE_LOCAL2B
1645    
1646  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1647  {  {
1648  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1151  if (list_item) Line 1680  if (list_item)
1680    list_item->type = type;    list_item->type = type;
1681    list_item->data = data;    list_item->data = data;
1682    list_item->start = start;    list_item->start = start;
1683    list_item->leave = LABEL();    list_item->quit = LABEL();
1684    list_item->next = common->stubs;    list_item->next = common->stubs;
1685    common->stubs = list_item;    common->stubs = list_item;
1686    }    }
# Line 1171  while (list_item) Line 1700  while (list_item)
1700      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1701      break;      break;
1702      }      }
1703    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1704    list_item = list_item->next;    list_item = list_item->next;
1705    }    }
1706  common->stubs = NULL;  common->stubs = NULL;
# Line 1222  if (length < 8) Line 1751  if (length < 8)
1751    }    }
1752  else  else
1753    {    {
1754    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1755    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1756    loop = LABEL();    loop = LABEL();
1757    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1242  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI Line 1771  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJI
1771  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1772    
1773  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1774    if (common->mark_ptr != 0)
1775      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1776  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1777    if (common->mark_ptr != 0)
1778      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1779  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1780  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1781  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1782  /* Unlikely, but possible */  /* Unlikely, but possible */
1783  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1784  loop = LABEL();  loop = LABEL();
# Line 1263  JUMPHERE(earlyexit); Line 1796  JUMPHERE(earlyexit);
1796  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1797  if (topbracket > 1)  if (topbracket > 1)
1798    {    {
1799    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1800    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1801    
1802    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
# Line 1277  else Line 1810  else
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1811  }  }
1812    
1813  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1814  {  {
1815  DEFINE_COMPILER;  DEFINE_COMPILER;
1816    
1817  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);
1818    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1819    
1820  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1821  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1822  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1823  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1824    
1825  /* Store match begin and end. */  /* Store match begin and end. */
1826  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1827  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1828  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? START_USED_PTR : HIT_START);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1829  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);
1830  #ifdef COMPILE_PCRE16  #ifdef COMPILE_PCRE16
1831  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
# Line 1304  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1838  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1838  #endif  #endif
1839  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1840    
1841  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1842  }  }
1843    
1844  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1315  struct sljit_jump *jump; Line 1849  struct sljit_jump *jump;
1849    
1850  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1851    {    {
1852    /* The value of -1 must be kept for START_USED_PTR! */    /* The value of -1 must be kept for start_used_ptr! */
1853    OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1854    /* Jumps if START_USED_PTR < STR_PTR, or START_USED_PTR == -1. Although overwriting    /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1855    is not necessary if START_USED_PTR == STR_PTR, it does not hurt as well. */    is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1856    jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);    jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1857    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1858    JUMPHERE(jump);    JUMPHERE(jump);
1859    }    }
1860  else if (common->mode == JIT_PARTIAL_HARD_COMPILE)  else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1861    {    {
1862    jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1864    JUMPHERE(jump);    JUMPHERE(jump);
1865    }    }
1866  }  }
# Line 1452  return (bit < 256) ? ((0 << 8) | bit) : Line 1986  return (bit < 256) ? ((0 << 8) | bit) :
1986  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
1987  }  }
1988    
1989  static void check_partial(compiler_common *common)  static void check_partial(compiler_common *common, BOOL force)
1990  {  {
1991    /* Checks whether a partial matching is occured. Does not modify registers. */
1992  DEFINE_COMPILER;  DEFINE_COMPILER;
1993  struct sljit_jump *jump;  struct sljit_jump *jump = NULL;
1994    
1995    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1996    
1997  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
1998    return;    return;
1999    
2000  jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);  if (!force)
2001      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2002    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2003      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2004    
2005  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2006    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2007  else  else
2008    {    {
2009    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 1470  else Line 2011  else
2011    else    else
2012      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2013    }    }
2014  JUMPHERE(jump);  
2015    if (jump != NULL)
2016      JUMPHERE(jump);
2017  }  }
2018    
2019  static struct sljit_jump *check_str_end(compiler_common *common)  static struct sljit_jump *check_str_end(compiler_common *common)
# Line 1487  if (common->mode == JIT_COMPILE) Line 2030  if (common->mode == JIT_COMPILE)
2030  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2031  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2032    {    {
2033    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2034    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2035    JUMPHERE(nohit);    JUMPHERE(nohit);
2036    return_value = JUMP(SLJIT_JUMP);    return_value = JUMP(SLJIT_JUMP);
2037    }    }
2038  else  else
2039    {    {
2040    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2041    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2042      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2043    else    else
# Line 1504  JUMPHERE(jump); Line 2047  JUMPHERE(jump);
2047  return return_value;  return return_value;
2048  }  }
2049    
2050  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2051  {  {
2052  DEFINE_COMPILER;  DEFINE_COMPILER;
2053  struct sljit_jump *jump;  struct sljit_jump *jump;
2054    
2055  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2056    {    {
2057    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2058    return;    return;
2059    }    }
2060    
2061  /* Partial matching mode. */  /* Partial matching mode. */
2062  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2063  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), 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));
2064  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2065    {    {
2066    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2067    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2068    }    }
2069  else  else
2070    {    {
# Line 1671  if (common->utf) Line 2214  if (common->utf)
2214  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2215  }  }
2216    
2217  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
2218  {  {
2219  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2220  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1679  DEFINE_COMPILER; Line 2222  DEFINE_COMPILER;
2222  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2223    {    {
2224    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2225    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2226    }    }
2227  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2228    {    {
# Line 1687  else if (nltype == NLTYPE_ANYCRLF) Line 2230  else if (nltype == NLTYPE_ANYCRLF)
2230    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2231    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2232    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2233    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2234    }    }
2235  else  else
2236    {    {
2237    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2238    add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2239    }    }
2240  }  }
2241    
# Line 1706  of the character (>= 0xc0). Return char Line 2249  of the character (>= 0xc0). Return char
2249  DEFINE_COMPILER;  DEFINE_COMPILER;
2250  struct sljit_jump *jump;  struct sljit_jump *jump;
2251    
2252  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2253  /* Searching for the first zero. */  /* Searching for the first zero. */
2254  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2255  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1765  DEFINE_COMPILER; Line 2308  DEFINE_COMPILER;
2308  struct sljit_jump *jump;  struct sljit_jump *jump;
2309  struct sljit_jump *compare;  struct sljit_jump *compare;
2310    
2311  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2312    
2313  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
2314  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1802  of the character (>= 0xd800). Return cha Line 2345  of the character (>= 0xd800). Return cha
2345  DEFINE_COMPILER;  DEFINE_COMPILER;
2346  struct sljit_jump *jump;  struct sljit_jump *jump;
2347    
2348  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2349  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2350  /* Do nothing, only return. */  /* Do nothing, only return. */
2351  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1839  DEFINE_COMPILER; Line 2382  DEFINE_COMPILER;
2382    
2383  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2384    
2385  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2386  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2387  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
2388  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
# Line 1875  if (!(hascrorlf || firstline) && (common Line 2418  if (!(hascrorlf || firstline) && (common
2418  if (firstline)  if (firstline)
2419    {    {
2420    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2421    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2423    
2424    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2425      {      {
# Line 1887  if (firstline) Line 2430  if (firstline)
2430      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2431      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2432      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2433      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      JUMPHERE(end);
2434        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2435      }      }
2436    else    else
2437      {      {
2438      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2439      mainloop = LABEL();      mainloop = LABEL();
2440      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2441      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2442      read_char(common);      read_char(common);
2443      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2444      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2445      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2446        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2447      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2448      }      }
2449    
2450    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2451    }    }
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1970  if (newlinecheck) Line 2514  if (newlinecheck)
2514  return mainloop;  return mainloop;
2515  }  }
2516    
2517    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2518    {
2519    DEFINE_COMPILER;
2520    struct sljit_label *start;
2521    struct sljit_jump *quit;
2522    struct sljit_jump *found;
2523    pcre_int32 chars[4];
2524    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2525    int location = 0;
2526    pcre_int32 len, c, bit, caseless;
2527    BOOL must_end;
2528    
2529    #ifdef COMPILE_PCRE8
2530    union {
2531        sljit_uh ascombined;
2532        sljit_ub asuchars[2];
2533    } pair;
2534    #else
2535    union {
2536        sljit_ui ascombined;
2537        sljit_uh asuchars[2];
2538    } pair;
2539    #endif
2540    
2541    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2542      return FALSE;
2543    
2544    while (TRUE)
2545      {
2546      caseless = 0;
2547      must_end = TRUE;
2548      switch(*cc)
2549        {
2550        case OP_CHAR:
2551        must_end = FALSE;
2552        cc++;
2553        break;
2554    
2555        case OP_CHARI:
2556        caseless = 1;
2557        must_end = FALSE;
2558        cc++;
2559        break;
2560    
2561        case OP_SOD:
2562        case OP_SOM:
2563        case OP_SET_SOM:
2564        case OP_NOT_WORD_BOUNDARY:
2565        case OP_WORD_BOUNDARY:
2566        case OP_EODN:
2567        case OP_EOD:
2568        case OP_CIRC:
2569        case OP_CIRCM:
2570        case OP_DOLL:
2571        case OP_DOLLM:
2572        /* Zero width assertions. */
2573        cc++;
2574        continue;
2575    
2576        case OP_PLUS:
2577        case OP_MINPLUS:
2578        case OP_POSPLUS:
2579        cc++;
2580        break;
2581    
2582        case OP_EXACT:
2583        cc += 1 + IMM2_SIZE;
2584        break;
2585    
2586        case OP_PLUSI:
2587        case OP_MINPLUSI:
2588        case OP_POSPLUSI:
2589        caseless = 1;
2590        cc++;
2591        break;
2592    
2593        case OP_EXACTI:
2594        caseless = 1;
2595        cc += 1 + IMM2_SIZE;
2596        break;
2597    
2598        default:
2599        return FALSE;
2600        }
2601    
2602      len = 1;
2603    #ifdef SUPPORT_UTF
2604      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2605    #endif
2606    
2607      if (caseless && char_has_othercase(common, cc))
2608        {
2609        caseless = char_get_othercase_bit(common, cc);
2610        if (caseless == 0)
2611          return FALSE;
2612    #ifdef COMPILE_PCRE8
2613        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2614    #else
2615        if ((caseless & 0x100) != 0)
2616          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2617        else
2618          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2619    #endif
2620        }
2621      else
2622        caseless = 0;
2623    
2624      while (len > 0 && location < 2 * 2)
2625        {
2626        c = *cc;
2627        bit = 0;
2628        if (len == (caseless & 0xff))
2629          {
2630          bit = caseless >> 8;
2631          c |= bit;
2632          }
2633    
2634        chars[location] = c;
2635        chars[location + 1] = bit;
2636    
2637        len--;
2638        location += 2;
2639        cc++;
2640        }
2641    
2642      if (location == 2 * 2)
2643        break;
2644      else if (must_end)
2645        return FALSE;
2646      }
2647    
2648    if (firstline)
2649      {
2650      SLJIT_ASSERT(common->first_line_end != 0);
2651      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2652      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2653      }
2654    else
2655      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2656    
2657    start = LABEL();
2658    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2659    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2660    #ifdef COMPILE_PCRE8
2661    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2662    #else /* COMPILE_PCRE8 */
2663    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2664    #endif
2665    
2666    #else /* SLJIT_UNALIGNED */
2667    
2668    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2669    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2670    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2671    #else /* SLJIT_BIG_ENDIAN */
2672    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2673    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2674    #endif /* SLJIT_BIG_ENDIAN */
2675    
2676    #ifdef COMPILE_PCRE8
2677    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2678    #else /* COMPILE_PCRE8 */
2679    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2680    #endif
2681    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2682    
2683    #endif
2684    
2685    if (chars[1] != 0 || chars[3] != 0)
2686      {
2687      pair.asuchars[0] = chars[1];
2688      pair.asuchars[1] = chars[3];
2689      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2690      }
2691    
2692    pair.asuchars[0] = chars[0];
2693    pair.asuchars[1] = chars[2];
2694    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2695    
2696    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2697    JUMPTO(SLJIT_JUMP, start);
2698    JUMPHERE(found);
2699    JUMPHERE(quit);
2700    
2701    if (firstline)
2702      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2703    else
2704      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    return TRUE;
2706    }
2707    
2708  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2709  {  {
2710  DEFINE_COMPILER;  DEFINE_COMPILER;
2711  struct sljit_label *start;  struct sljit_label *start;
2712  struct sljit_jump *leave;  struct sljit_jump *quit;
2713  struct sljit_jump *found;  struct sljit_jump *found;
2714  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2715    
2716  if (firstline)  if (firstline)
2717    {    {
2718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2719    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2720      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2721    }    }
2722    
2723  start = LABEL();  start = LABEL();
2724  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2725  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2726    
2727  oc = first_char;  oc = first_char;
# Line 2018  else Line 2754  else
2754    }    }
2755    
2756  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));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2757  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2758  JUMPHERE(found);  JUMPHERE(found);
2759  JUMPHERE(leave);  JUMPHERE(quit);
2760    
2761  if (firstline)  if (firstline)
2762    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2763  }  }
2764    
2765  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2051  DEFINE_COMPILER; Line 2768  DEFINE_COMPILER;
2768  struct sljit_label *loop;  struct sljit_label *loop;
2769  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2770  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2771  struct sljit_jump *leave;  struct sljit_jump *quit;
2772  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2773  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2774  jump_list *newline = NULL;  jump_list *newline = NULL;
2775    
2776  if (firstline)  if (firstline)
2777    {    {
2778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2779    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2780      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2781    }    }
2782    
2783  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 2080  if (common->nltype == NLTYPE_FIXED && co Line 2798  if (common->nltype == NLTYPE_FIXED && co
2798    
2799    loop = LABEL();    loop = LABEL();
2800    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));
2801    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2802    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2803    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2804    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2805    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2806    
2807    JUMPHERE(leave);    JUMPHERE(quit);
2808    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2809    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2810    
# Line 2110  set_jumps(newline, loop); Line 2828  set_jumps(newline, loop);
2828    
2829  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2830    {    {
2831    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2832    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2833    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2834    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2121  if (common->nltype == NLTYPE_ANY || comm Line 2839  if (common->nltype == NLTYPE_ANY || comm
2839  #endif  #endif
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2841    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2842    JUMPHERE(leave);    JUMPHERE(quit);
2843    }    }
2844  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2845  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2846    
2847  if (firstline)  if (firstline)
2848    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2849  }  }
2850    
2851  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)
2852  {  {
2853  DEFINE_COMPILER;  DEFINE_COMPILER;
2854  struct sljit_label *start;  struct sljit_label *start;
2855  struct sljit_jump *leave;  struct sljit_jump *quit;
2856  struct sljit_jump *found;  struct sljit_jump *found;
2857  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2858  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2142  struct sljit_jump *jump; Line 2860  struct sljit_jump *jump;
2860    
2861  if (firstline)  if (firstline)
2862    {    {
2863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2864    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2865      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2866    }    }
2867    
2868  start = LABEL();  start = LABEL();
2869  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2870  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2871  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2872  if (common->utf)  if (common->utf)
# Line 2191  if (common->utf) Line 2910  if (common->utf)
2910  #endif  #endif
2911  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2912  JUMPHERE(found);  JUMPHERE(found);
2913  JUMPHERE(leave);  JUMPHERE(quit);
2914    
2915  if (firstline)  if (firstline)
2916    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2917  }  }
2918    
2919  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2208  struct sljit_jump *foundoc = NULL; Line 2927  struct sljit_jump *foundoc = NULL;
2927  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2928  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2929    
2930  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2931    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2932  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2933  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2934  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2253  JUMPTO(SLJIT_JUMP, loop); Line 2973  JUMPTO(SLJIT_JUMP, loop);
2973  JUMPHERE(found);  JUMPHERE(found);
2974  if (foundoc)  if (foundoc)
2975    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2976  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2977  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2978  JUMPHERE(toolong);  JUMPHERE(toolong);
2979  return notfound;  return notfound;
# Line 2265  DEFINE_COMPILER; Line 2985  DEFINE_COMPILER;
2985  struct sljit_jump *jump;  struct sljit_jump *jump;
2986  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2987    
2988  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2989  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2990    GET_LOCAL_BASE(TMP3, 0, 0);
2991    
2992  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2993  mainloop = LABEL();  mainloop = LABEL();
2994  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2995  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2996  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2997  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2998  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
2999  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
# Line 2292  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 3013  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
3013  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3014    
3015  JUMPHERE(jump);  JUMPHERE(jump);
3016    if (common->mark_ptr != 0)
3017      {
3018      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3019      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3020      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3021      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3022      JUMPTO(SLJIT_JUMP, mainloop);
3023    
3024      JUMPHERE(jump);
3025      }
3026    
3027  /* Unknown command. */  /* Unknown command. */
3028  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3029  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2307  struct sljit_jump *jump; Line 3039  struct sljit_jump *jump;
3039    
3040  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3041    
3042  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3043  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3044  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3045  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 2355  else Line 3087  else
3087      JUMPHERE(jump);      JUMPHERE(jump);
3088  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3089    }    }
3090  JUMPHERE(skipread);  JUMPHERE(skipread);
3091    
3092    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3093    skipread = check_str_end(common);
3094    peek_char(common);
3095    
3096    /* Testing char type. This is a code duplication. */
3097    #ifdef SUPPORT_UCP
3098    if (common->use_ucp)
3099      {
3100      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3101      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3102      add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3103      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3104      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3105      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3106      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3107      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3108      COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
3109      JUMPHERE(jump);
3110      }
3111    else
3112    #endif
3113      {
3114    #ifndef COMPILE_PCRE8
3115      /* TMP2 may be destroyed by peek_char. */
3116      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3117      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3118    #elif defined SUPPORT_UTF
3119      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3120      jump = NULL;
3121      if (common->utf)
3122        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3123    #endif
3124      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3125      OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3126      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3127    #ifndef COMPILE_PCRE8
3128      JUMPHERE(jump);
3129    #elif defined SUPPORT_UTF
3130      if (jump != NULL)
3131        JUMPHERE(jump);
3132    #endif /* COMPILE_PCRE8 */
3133      }
3134    JUMPHERE(skipread);
3135    
3136    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3137    sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3138    }
3139    
3140    /*
3141      range format:
3142    
3143      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3144      ranges[1] = first bit (0 or 1)
3145      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3146    */
3147    
3148    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3149    {
3150    DEFINE_COMPILER;
3151    struct sljit_jump *jump;
3152    
3153    if (ranges[0] < 0)
3154      return FALSE;
3155    
3156    switch(ranges[0])
3157      {
3158      case 1:
3159      if (readch)
3160        read_char(common);
3161      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3162      return TRUE;
3163    
3164      case 2:
3165      if (readch)
3166        read_char(common);
3167      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3168      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3169      return TRUE;
3170    
3171      case 4:
3172      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3173        {
3174        if (readch)
3175          read_char(common);
3176        if (ranges[1] != 0)
3177          {
3178          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          }
3181        else
3182          {
3183          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3184          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3185          JUMPHERE(jump);
3186          }
3187        return TRUE;
3188        }
3189      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3190        {
3191        if (readch)
3192          read_char(common);
3193        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3194        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3195        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3196        return TRUE;
3197        }
3198      return FALSE;
3199    
3200      default:
3201      return FALSE;
3202      }
3203    }
3204    
3205    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3206    {
3207    int i, bit, length;
3208    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3209    
3210    bit = ctypes[0] & flag;
3211    ranges[0] = -1;
3212    ranges[1] = bit != 0 ? 1 : 0;
3213    length = 0;
3214    
3215    for (i = 1; i < 256; i++)
3216      if ((ctypes[i] & flag) != bit)
3217        {
3218        if (length >= MAX_RANGE_SIZE)
3219          return;
3220        ranges[2 + length] = i;
3221        length++;
3222        bit ^= flag;
3223        }
3224    
3225    if (bit != 0)
3226      {
3227      if (length >= MAX_RANGE_SIZE)
3228        return;
3229      ranges[2 + length] = 256;
3230      length++;
3231      }
3232    ranges[0] = length;
3233    }
3234    
3235  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3236  skipread = check_str_end(common);  {
3237  peek_char(common);  int ranges[2 + MAX_RANGE_SIZE];
3238    pcre_uint8 bit, cbit, all;
3239    int i, byte, length = 0;
3240    
3241  /* Testing char type. This is a code duplication. */  bit = bits[0] & 0x1;
3242  #ifdef SUPPORT_UCP  ranges[1] = bit;
3243  if (common->use_ucp)  /* Can be 0 or 255. */
3244    all = -bit;
3245    
3246    for (i = 0; i < 256; )
3247    {    {
3248    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    byte = i >> 3;
3249    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    if ((i & 0x7) == 0 && bits[byte] == all)
3250    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));      i += 8;
3251    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    else
3252    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);      {
3253    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);      cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3254    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);      if (cbit != bit)
3255    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);        {
3256    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        if (length >= MAX_RANGE_SIZE)
3257    JUMPHERE(jump);          return FALSE;
3258          ranges[2 + length] = i;
3259          length++;
3260          bit = cbit;
3261          all = -cbit;
3262          }
3263        i++;
3264        }
3265    }    }
3266  else  
3267  #endif  if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3268    {    {
3269  #ifndef COMPILE_PCRE8    if (length >= MAX_RANGE_SIZE)
3270    /* TMP2 may be destroyed by peek_char. */      return FALSE;
3271    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    ranges[2 + length] = 256;
3272    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    length++;
 #elif defined SUPPORT_UTF  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
   jump = NULL;  
   if (common->utf)  
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #endif  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);  
   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);  
   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (jump != NULL)  
     JUMPHERE(jump);  
 #endif /* COMPILE_PCRE8 */  
3273    }    }
3274  JUMPHERE(skipread);  ranges[0] = length;
3275    
3276  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  return check_ranges(common, ranges, backtracks, FALSE);
 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
3277  }  }
3278    
3279  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 2410  static void check_anynewline(compiler_co Line 3281  static void check_anynewline(compiler_co
3281  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3282  DEFINE_COMPILER;  DEFINE_COMPILER;
3283    
3284  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3285    
3286  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3287  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
# Line 2437  static void check_hspace(compiler_common Line 3308  static void check_hspace(compiler_common
3308  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3309  DEFINE_COMPILER;  DEFINE_COMPILER;
3310    
3311  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3312    
3313  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3314  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
# Line 2476  static void check_vspace(compiler_common Line 3347  static void check_vspace(compiler_common
3347  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3348  DEFINE_COMPILER;  DEFINE_COMPILER;
3349    
3350  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3351    
3352  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3353  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
# Line 2508  DEFINE_COMPILER; Line 3379  DEFINE_COMPILER;
3379  struct sljit_jump *jump;  struct sljit_jump *jump;
3380  struct sljit_label *label;  struct sljit_label *label;
3381    
3382  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3383  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3384  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3385  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2537  DEFINE_COMPILER; Line 3408  DEFINE_COMPILER;
3408  struct sljit_jump *jump;  struct sljit_jump *jump;
3409  struct sljit_label *label;  struct sljit_label *label;
3410    
3411  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3412  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3413    
3414  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2584  static const pcre_uchar *SLJIT_CALL do_u Line 3455  static const pcre_uchar *SLJIT_CALL do_u
3455  {  {
3456  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3457  int c1, c2;  int c1, c2;
3458  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3459  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3460    
3461  while (src1 < end1)  while (src1 < end1)
# Line 2601  return src2; Line 3472  return src2;
3472  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3473    
3474  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
3475      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3476  {  {
3477  DEFINE_COMPILER;  DEFINE_COMPILER;
3478  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2702  do Line 3573  do
3573        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3574        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3575          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
3576        add_jump(compiler, fallbacks, 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));
3577        break;        break;
3578    
3579        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3580        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3581          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);
3582        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
3583        break;        break;
3584    
3585  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3586        case 1:        case 1:
3587        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3588          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
3589        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
3590        break;        break;
3591  #endif  #endif
3592    
# Line 2741  do Line 3612  do
3612    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3613      {      {
3614      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3615      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
3616      }      }
3617    else    else
3618      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc));
3619    
3620  #endif  #endif
3621    
# Line 2780  return cc; Line 3651  return cc;
3651      } \      } \
3652    charoffset = (value);    charoffset = (value);
3653    
3654  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3655  {  {
3656  DEFINE_COMPILER;  DEFINE_COMPILER;
3657  jump_list *found = NULL;  jump_list *found = NULL;
3658  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3659  unsigned int c;  unsigned int c;
3660  int compares;  int compares;
3661  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2798  unsigned int typeoffset; Line 3669  unsigned int typeoffset;
3669  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3670  unsigned int charoffset;  unsigned int charoffset;
3671    
3672  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3673  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3674    detect_partial_match(common, backtracks);
3675  read_char(common);  read_char(common);
3676    
3677  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2812  if ((*cc++ & XCL_MAP) != 0) Line 3684  if ((*cc++ & XCL_MAP) != 0)
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685  #endif  #endif
3686    
3687    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3688    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3690    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3691    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3692    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3693        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3694        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3695        }
3696    
3697  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3698    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2950  typeoffset = 0; Line 3825  typeoffset = 0;
3825  while (*cc != XCL_END)  while (*cc != XCL_END)
3826    {    {
3827    compares--;    compares--;
3828    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3829    jump = NULL;    jump = NULL;
3830    
3831    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3032  while (*cc != XCL_END) Line 3907  while (*cc != XCL_END)
3907      switch(*cc)      switch(*cc)
3908        {        {
3909        case PT_ANY:        case PT_ANY:
3910        if (list != fallbacks)        if (list != backtracks)
3911          {          {
3912          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
3913            continue;            continue;
# Line 3105  while (*cc != XCL_END) Line 3980  while (*cc != XCL_END)
3980  #endif  #endif
3981    
3982    if (jump != NULL)    if (jump != NULL)
3983      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3984    }    }
3985    
3986  if (found != NULL)  if (found != NULL)
# Line 3117  if (found != NULL) Line 3992  if (found != NULL)
3992    
3993  #endif  #endif
3994    
3995  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3996  {  {
3997  DEFINE_COMPILER;  DEFINE_COMPILER;
3998  int length;  int length;
# Line 3136  switch(type) Line 4011  switch(type)
4011    case OP_SOD:    case OP_SOD:
4012    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4013    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4014    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4015    return cc;    return cc;
4016    
4017    case OP_SOM:    case OP_SOM:
4018    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4019    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
4020    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4021    return cc;    return cc;
4022    
4023    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4024    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4025    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4026    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4027    return cc;    return cc;
4028    
4029    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4030    case OP_DIGIT:    case OP_DIGIT:
4031    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4032    read_char8_type(common);    if (common->digits[0] == -2)
4033    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4034    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4035      /* Flip the starting bit in the negative case. */
4036      if (type == OP_NOT_DIGIT)
4037        common->digits[1] ^= 1;
4038      if (!check_ranges(common, common->digits, backtracks, TRUE))
4039        {
4040        read_char8_type(common);
4041        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4042        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4043        }
4044      if (type == OP_NOT_DIGIT)
4045        common->digits[1] ^= 1;
4046    return cc;    return cc;
4047    
4048    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4049    case OP_WHITESPACE:    case OP_WHITESPACE:
4050    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4051    read_char8_type(common);    read_char8_type(common);
4052    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
4053    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4054    return cc;    return cc;
4055    
4056    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4057    case OP_WORDCHAR:    case OP_WORDCHAR:
4058    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4059    read_char8_type(common);    read_char8_type(common);
4060    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
4061    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4062    return cc;    return cc;
4063    
4064    case OP_ANY:    case OP_ANY:
4065    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4066    read_char(common);    read_char(common);
4067    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4068      {      {
4069      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);
4070      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4071          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4072        else
4073          jump[1] = check_str_end(common);
4074    
4075      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4076      add_jump(compiler, fallbacks, 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));
4077      JUMPHERE(jump[1]);      if (jump[1] != NULL)
4078          JUMPHERE(jump[1]);
4079      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4080      }      }
4081    else    else
4082      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4083    return cc;    return cc;
4084    
4085    case OP_ALLANY:    case OP_ALLANY:
4086    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4087  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4088    if (common->utf)    if (common->utf)
4089      {      {
# Line 3220  switch(type) Line 4111  switch(type)
4111    return cc;    return cc;
4112    
4113    case OP_ANYBYTE:    case OP_ANYBYTE:
4114    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4115    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));
4116    return cc;    return cc;
4117    
# Line 3233  switch(type) Line 4124  switch(type)
4124    propdata[2] = cc[0];    propdata[2] = cc[0];
4125    propdata[3] = cc[1];    propdata[3] = cc[1];
4126    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4127    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_trypath(common, propdata, backtracks);
4128    return cc + 2;    return cc + 2;
4129  #endif  #endif
4130  #endif  #endif
4131    
4132    case OP_ANYNL:    case OP_ANYNL:
4133    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4134    read_char(common);    read_char(common);
4135    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);
4136    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
4137      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4138        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4139      else
4140        jump[1] = check_str_end(common);
4141    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4142    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4143    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));
4144    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4145    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4146    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4147    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4148    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4149    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3256  switch(type) Line 4151  switch(type)
4151    
4152    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4153    case OP_HSPACE:    case OP_HSPACE:
4154    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4155    read_char(common);    read_char(common);
4156    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4157    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4158    return cc;    return cc;
4159    
4160    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4161    case OP_VSPACE:    case OP_VSPACE:
4162    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4163    read_char(common);    read_char(common);
4164    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4165    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4166    return cc;    return cc;
4167    
4168  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4169    case OP_EXTUNI:    case OP_EXTUNI:
4170    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4171    read_char(common);    read_char(common);
4172    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4173    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
4174    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
4175    
4176    label = LABEL();    label = LABEL();
4177    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 3291  switch(type) Line 4186  switch(type)
4186    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4187      {      {
4188      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4189      check_partial(common);      /* Since we successfully read a char above, partial matching must occure. */
4190        check_partial(common, TRUE);
4191      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4192      }      }
4193    return cc;    return cc;
4194  #endif  #endif
4195    
4196    case OP_EODN:    case OP_EODN:
4197      /* Requires rather complex checks. */
4198    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4199    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4200      {      {
4201      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4202      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4203      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
4204          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
4205        else
4206          {
4207          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4208          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4209          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4210          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4211          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
4212          add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4213          check_partial(common, TRUE);
4214          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4215          JUMPHERE(jump[1]);
4216          }
4217      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4218      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4219      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4220      }      }
4221    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4222      {      {
4223      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4224      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4225      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
4226      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
4227      }      }
4228    else    else
4229      {      {
# Line 3322  switch(type) Line 4232  switch(type)
4232      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4233      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4234      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4235      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4236      /* Equal. */      /* Equal. */
4237      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4238      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4239      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4240    
4241      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4242      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4243        {        {
4244        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4245        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
4246        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
4247        }        }
4248      else      else
4249        {        {
4250        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4251        read_char(common);        read_char(common);
4252        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
4253        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4254        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4255        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4256        }        }
4257      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
4258      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
4259      }      }
4260    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4261    check_partial(common);    check_partial(common, FALSE);
4262    return cc;    return cc;
4263    
4264    case OP_EOD:    case OP_EOD:
4265    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4266    check_partial(common);    check_partial(common, FALSE);
4267    return cc;    return cc;
4268    
4269    case OP_CIRC:    case OP_CIRC:
4270    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4271    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
4272    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
4273    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
4274    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4275    return cc;    return cc;
4276    
4277    case OP_CIRCM:    case OP_CIRCM:
# Line 3369  switch(type) Line 4279  switch(type)
4279    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
4280    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4281    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
4282    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4283    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4284    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4285    
4286    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4287    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4288      {      {
4289      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4290      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4291      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4292      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4293      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4294      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4295      }      }
4296    else    else
4297      {      {
4298      skip_char_back(common);      skip_char_back(common);
4299      read_char(common);      read_char(common);
4300      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4301      }      }
4302    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4303    return cc;    return cc;
# Line 3395  switch(type) Line 4305  switch(type)
4305    case OP_DOLL:    case OP_DOLL:
4306    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4307    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
4308    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4309    
4310    if (!common->endonly)    if (!common->endonly)
4311      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_trypath(common, OP_EODN, cc, backtracks);
4312    else    else
4313      {      {
4314      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4315      check_partial(common);      check_partial(common, FALSE);
4316      }      }
4317    return cc;    return cc;
4318    
# Line 3410  switch(type) Line 4320  switch(type)
4320    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4321    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4322    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
4323    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4324    check_partial(common);    check_partial(common, FALSE);
4325    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4326    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4327    
4328    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4329      {      {
4330      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));  
4331      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4332        if (common->mode == JIT_COMPILE)
4333          add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
4334        else
4335          {
4336          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4337          /* STR_PTR = STR_END - IN_UCHARS(1) */
4338          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4339          check_partial(common, TRUE);
4340          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4341          JUMPHERE(jump[1]);
4342          }
4343    
4344      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4345      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4346      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4347      }      }
4348    else    else
4349      {      {
4350      peek_char(common);      peek_char(common);
4351      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4352      }      }
4353    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4354    return cc;    return cc;
# Line 3441  switch(type) Line 4362  switch(type)
4362    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
4363      {      {
4364      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
4365      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
4366    
4367      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4368      context.sourcereg = -1;      context.sourcereg = -1;
4369  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4370      context.ucharptr = 0;      context.ucharptr = 0;
4371  #endif  #endif
4372      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4373      }      }
4374    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4375    read_char(common);    read_char(common);
4376  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4377    if (common->utf)    if (common->utf)
# Line 3462  switch(type) Line 4383  switch(type)
4383      c = *cc;      c = *cc;
4384    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4385      {      {
4386      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
4387      return cc + length;      return cc + length;
4388      }      }
4389    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 3470  switch(type) Line 4391  switch(type)
4391    if (ispowerof2(bit))    if (ispowerof2(bit))
4392      {      {
4393      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4394      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4395      return cc + length;      return cc + length;
4396      }      }
4397    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4398    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4399    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
4400    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4401    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4402    return cc + length;    return cc + length;
4403    
4404    case OP_NOT:    case OP_NOT:
4405    case OP_NOTI:    case OP_NOTI:
4406    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4407    length = 1;    length = 1;
4408  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4409    if (common->utf)    if (common->utf)
# Line 3493  switch(type) Line 4414  switch(type)
4414        {        {
4415        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4416        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4417          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4418        else        else
4419          {          {
4420          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
4421          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4422          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
4423          }          }
4424        /* Skip the variable-length character. */        /* Skip the variable-length character. */
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));
# Line 3523  switch(type) Line 4444  switch(type)
4444      }      }
4445    
4446    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4447      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4448    else    else
4449      {      {
4450      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3531  switch(type) Line 4452  switch(type)
4452      if (ispowerof2(bit))      if (ispowerof2(bit))
4453        {        {
4454        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4455        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4456        }        }
4457      else      else
4458        {        {
4459        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
4460        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
4461        }        }
4462      }      }
4463    return cc + 1;    return cc + length;
4464    
4465    case OP_CLASS:    case OP_CLASS:
4466    case OP_NCLASS:    case OP_NCLASS:
4467    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4468    read_char(common);    read_char(common);
4469      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4470        return cc + 32 / sizeof(pcre_uchar);
4471    
4472  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4473    jump[0] = NULL;    jump[0] = NULL;
4474  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3556  switch(type) Line 4480  switch(type)
4480      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4481      if (type == OP_CLASS)      if (type == OP_CLASS)
4482        {        {
4483        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4484        jump[0] = NULL;        jump[0] = NULL;
4485        }        }
4486      }      }
# Line 3566  switch(type) Line 4490  switch(type)
4490    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4491    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4492    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);
4493    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4494  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4495    if (jump[0] != NULL)    if (jump[0] != NULL)
4496      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3575  switch(type) Line 4499  switch(type)
4499    
4500  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4501    case OP_XCLASS:    case OP_XCLASS:
4502    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
4503    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4504  #endif  #endif
4505    
4506    case OP_REVERSE:    case OP_REVERSE:
4507    length = GET(cc, 0);    length = GET(cc, 0);
4508    SLJIT_ASSERT(length > 0);    if (length == 0)
4509        return cc + LINK_SIZE;
4510    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4511  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4512    if (common->utf)    if (common->utf)
# Line 3589  switch(type) Line 4514  switch(type)
4514      OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4515      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4516      label = LABEL();      label = LABEL();
4517      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
4518      skip_char_back(common);      skip_char_back(common);
4519      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
4520      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3599  switch(type) Line 4524  switch(type)
4524      {      {
4525      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
4526      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
4527      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
4528      }      }
4529    check_start_used_ptr(common);    check_start_used_ptr(common);
4530    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3608  SLJIT_ASSERT_STOP(); Line 4533  SLJIT_ASSERT_STOP();
4533  return cc;  return cc;
4534  }  }
4535    
4536  static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4537  {  {
4538  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4539  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3660  if (context.length > 0) Line 4585  if (context.length > 0)
4585    {    {
4586    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4587    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
4588    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
4589    
4590    context.sourcereg = -1;    context.sourcereg = -1;
4591  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4592    context.ucharptr = 0;    context.ucharptr = 0;
4593  #endif  #endif
4594    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
4595    return cc;    return cc;
4596    }    }
4597    
4598  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4599  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_trypath(common, *cc, cc + 1, backtracks);
4600  }  }
4601    
4602  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
4603  {  {
4604  DEFINE_COMPILER;  DEFINE_COMPILER;
4605  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3682  int offset = GET2(cc, 1) << 1; Line 4607  int offset = GET2(cc, 1) << 1;
4607  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4608  if (!common->jscript_compat)  if (!common->jscript_compat)
4609    {    {
4610    if (fallbacks == NULL)    if (backtracks == NULL)
4611      {      {
4612      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4613      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
# Line 3691  if (!common->jscript_compat) Line 4616  if (!common->jscript_compat)
4616      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4617      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4618      }      }
4619    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4620    }    }
4621  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4622  }  }
4623    
4624  /* Forward definitions. */  /* Forward definitions. */
4625  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4626  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
4627    
4628  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4629    do \    do \
4630      { \      { \
4631      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4632      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4633        return error; \        return error; \
4634      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4635      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4636      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4637      parent->top = fallback; \      parent->top = backtrack; \
4638      } \      } \
4639    while (0)    while (0)
4640    
4641  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4642    do \    do \
4643      { \      { \
4644      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4645      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4646        return; \        return; \
4647      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4648      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4649      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4650      parent->top = fallback; \      parent->top = backtrack; \
4651      } \      } \
4652    while (0)    while (0)
4653    
4654  #define FALLBACK_AS(type) ((type *)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4655    
4656  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4657  {  {
4658  DEFINE_COMPILER;  DEFINE_COMPILER;
4659  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3739  struct sljit_jump *nopartial; Line 4664  struct sljit_jump *nopartial;
4664  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4665  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
4666  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4667    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4668    
4669  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4670  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3752  if (common->utf && *cc == OP_REFI) Line 4677  if (common->utf && *cc == OP_REFI)
4677    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
4678    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4679    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
4680    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
4681    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
4682    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4683    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4684      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
4685    else    else
4686      {      {
4687      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
4688      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);      nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
4689      check_partial(common);      check_partial(common, FALSE);
4690      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4691      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4692      }      }
4693    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3777  else Line 4702  else
4702    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4703    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4704    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4705      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
4706    
4707    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
4708    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4709    
4710    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
4711      {      {
# Line 3792  else Line 4717  else
4717      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4718      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4719      add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
4720      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
4721      JUMPHERE(partial);      JUMPHERE(partial);
4722      check_partial(common);      check_partial(common, FALSE);
4723      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4724      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4725      }      }
4726    }    }
# Line 3803  else Line 4728  else
4728  if (jump != NULL)  if (jump != NULL)
4729    {    {
4730    if (emptyfail)    if (emptyfail)
4731      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4732    else    else
4733      JUMPHERE(jump);      JUMPHERE(jump);
4734    }    }
4735  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4736  }  }
4737    
4738  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4739  {  {
4740  DEFINE_COMPILER;  DEFINE_COMPILER;
4741  fallback_common *fallback;  backtrack_common *backtrack;
4742  pcre_uchar type;  pcre_uchar type;
4743  struct sljit_label *label;  struct sljit_label *label;
4744  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3822  pcre_uchar *ccbegin = cc; Line 4747  pcre_uchar *ccbegin = cc;
4747  int min = 0, max = 0;  int min = 0, max = 0;
4748  BOOL minimize;  BOOL minimize;
4749    
4750  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4751    
4752  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4753  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 3874  if (!minimize) Line 4799  if (!minimize)
4799      {      {
4800      allocate_stack(common, 1);      allocate_stack(common, 1);
4801      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4802      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4803      }      }
4804    
4805    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4806      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4807    
4808    label = LABEL();    label = LABEL();
4809    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4810    
4811    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4812      {      {
# Line 3909  if (!minimize) Line 4834  if (!minimize)
4834      }      }
4835    
4836    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4837    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4838    
4839    decrease_call_count(common);    decrease_call_count(common);
4840    return cc;    return cc;
# Line 3927  if (min == 0) Line 4852  if (min == 0)
4852    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4853    }    }
4854  else  else
4855    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4856    
4857  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4858  if (max > 0)  if (max > 0)
4859    add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4860    
4861  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4862  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4863    
4864  if (min > 1)  if (min > 1)
# Line 3941  if (min > 1) Line 4866  if (min > 1)
4866    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4867    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4868    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4869    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);
4870    }    }
4871  else if (max > 0)  else if (max > 0)
4872    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 3954  decrease_call_count(common); Line 4879  decrease_call_count(common);
4879  return cc;  return cc;
4880  }  }
4881    
4882  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4883  {  {
4884  DEFINE_COMPILER;  DEFINE_COMPILER;
4885  fallback_common *fallback;  backtrack_common *backtrack;
4886  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4887  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4888  int start = GET(cc, 1);  int start = GET(cc, 1);
4889    
4890  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4891  while (entry != NULL)  while (entry != NULL)
4892    {    {
4893    if (entry->start == start)    if (entry->start == start)
# Line 3987  if (entry == NULL) Line 4912  if (entry == NULL)
4912      common->entries = entry;      common->entries = entry;
4913    }    }
4914    
4915  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4916  allocate_stack(common, 1);    {
4917  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4918      allocate_stack(common, 2);
4919      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4920      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4921      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4922      }
4923    else if (common->has_set_som || common->mark_ptr != 0)
4924      {
4925      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4926      allocate_stack(common, 1);
4927      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4928      }
4929    
4930  if (entry->entry == NULL)  if (entry->entry == NULL)
4931    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
4932  else  else
4933    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4934  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4935  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
4936  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4937  }  }
4938    
4939  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4940  {  {
4941  DEFINE_COMPILER;  DEFINE_COMPILER;
4942  int framesize;  int framesize;
4943  int localptr;  int localptr;
4944  fallback_common altfallback;  backtrack_common altbacktrack;
4945  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4946  pcre_uchar opcode;  pcre_uchar opcode;
4947  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4948  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4949  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4950  jump_list **found;  jump_list **found;
4951  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4952    struct sljit_label *save_quitlabel = common->quitlabel;
4953  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4954    jump_list *save_quit = common->quit;
4955    jump_list *save_accept = common->accept;
4956  struct sljit_jump *jump;  struct sljit_jump *jump;
4957  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4958    
4959  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4960    {    {
# Line 4027  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4965  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4965  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
4966  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4967  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4968  fallback->framesize = framesize;  backtrack->framesize = framesize;
4969  fallback->localptr = localptr;  backtrack->localptr = localptr;
4970  opcode = *cc;  opcode = *cc;
4971  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4972  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4037  cc += GET(cc, 1); Line 4975  cc += GET(cc, 1);
4975    
4976  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4977    {    {
4978    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
4979    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4980    free_stack(common, 1);    free_stack(common, 1);
4981    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 4060  else Line 4998  else
4998    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
4999    }    }
5000    
5001  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5002    common->quitlabel = NULL;
5003    common->quit = NULL;
5004  while (1)  while (1)
5005    {    {
5006    common->acceptlabel = NULL;    common->acceptlabel = NULL;
5007    common->accept = NULL;    common->accept = NULL;
5008    altfallback.top = NULL;    altbacktrack.top = NULL;
5009    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5010    
5011    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5012      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5013    
5014    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5015    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5016    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5017      {      {
5018        common->quitlabel = save_quitlabel;
5019      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5020        common->quit = save_quit;
5021      common->accept = save_accept;      common->accept = save_accept;
5022      return NULL;      return NULL;
5023      }      }
# Line 4125  while (1) Line 5067  while (1)
5067      }      }
5068    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5069    
5070    compile_fallbackpath(common, altfallback.top);    compile_backtrackpath(common, altbacktrack.top);
5071    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5072      {      {
5073        common->quitlabel = save_quitlabel;
5074      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5075        common->quit = save_quit;
5076      common->accept = save_accept;      common->accept = save_accept;
5077      return NULL;      return NULL;
5078      }      }
5079    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5080    
5081    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5082      break;      break;
# Line 4141  while (1) Line 5085  while (1)
5085    cc += GET(cc, 1);    cc += GET(cc, 1);
5086    }    }
5087  /* None of them matched. */  /* None of them matched. */
5088    if (common->quit != NULL)
5089      set_jumps(common->quit, LABEL());
5090    
5091  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5092    {    {
# Line 4207  if (opcode == OP_ASSERT || opcode == OP_ Line 5153  if (opcode == OP_ASSERT || opcode == OP_
5153    
5154    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5155      {      {
5156      fallback->hotpath = LABEL();      backtrack->trypath = LABEL();
5157      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->trypath);
5158      }      }
5159    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5160      {      {
5161      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->trypath);
5162      JUMPHERE(brajump);      JUMPHERE(brajump);
5163      if (framesize >= 0)      if (framesize >= 0)
5164        {        {
# Line 4220  if (opcode == OP_ASSERT || opcode == OP_ Line 5166  if (opcode == OP_ASSERT || opcode == OP_
5166        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5167        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5168        }        }
5169      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5170      }      }
5171    }    }
5172  else  else
# Line 4250  else Line 5196  else
5196      }      }
5197    
5198    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5199      fallback->hotpath = LABEL();      backtrack->trypath = LABEL();
5200    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5201      {      {
5202      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->trypath);
5203      JUMPHERE(brajump);      JUMPHERE(brajump);
5204      }      }
5205    
5206    if (bra != OP_BRA)    if (bra != OP_BRA)
5207      {      {
5208      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5209      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5210      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5211      }      }
5212    }    }
5213    
5214    common->quitlabel = save_quitlabel;
5215  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5216    common->quit = save_quit;
5217  common->accept = save_accept;  common->accept = save_accept;
5218  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5219  }  }
# Line 4280  sljit_w name_entry_size = locals[LOCALS1 Line 5228  sljit_w name_entry_size = locals[LOCALS1
5228  sljit_w no_capture;  sljit_w no_capture;
5229  int i;  int i;
5230    
5231  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
5232    refno >>= 8;
5233  no_capture = locals[1];  no_capture = locals[1];
5234    
5235  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 4433  return condition; Line 5382  return condition;
5382                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5383  */  */
5384    
5385  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5386  {  {
5387  DEFINE_COMPILER;  DEFINE_COMPILER;
5388  fallback_common *fallback;  backtrack_common *backtrack;
5389  pcre_uchar opcode;  pcre_uchar opcode;
5390  int localptr = 0;  int localptr = 0;
5391  int offset = 0;  int offset = 0;
5392  int stacksize;  int stacksize;
5393  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5394  pcre_uchar *hotpath;  pcre_uchar *trypath;
5395  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5396  pcre_uchar ket;  pcre_uchar ket;
5397  assert_fallback *assert;  assert_backtrack *assert;
5398  BOOL has_alternatives;  BOOL has_alternatives;
5399  struct sljit_jump *jump;  struct sljit_jump *jump;
5400  struct sljit_jump *skip;  struct sljit_jump *skip;
5401  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
5402  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
5403    
5404  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5405    
5406  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5407    {    {
# Line 4463  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5412  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5412    
5413  opcode = *cc;  opcode = *cc;
5414  ccbegin = cc;  ccbegin = cc;
5415  hotpath = ccbegin + 1 + LINK_SIZE;  trypath = ccbegin + 1 + LINK_SIZE;
5416    
5417  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
5418    {    {
5419    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
5420    parent->top = fallback->prev;    parent->top = backtrack->prev;
5421    return bracketend(cc);    return bracketend(cc);
5422    }    }
5423    
# Line 4480  cc += GET(cc, 1); Line 5429  cc += GET(cc, 1);
5429  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5430  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5431    {    {
5432    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*trypath == OP_RREF) ? FALSE : TRUE;
5433    if (*hotpath == OP_NRREF)    if (*trypath == OP_NRREF)
5434      {      {
5435      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
5436      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5437        has_alternatives = FALSE;        has_alternatives = FALSE;
5438      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4504  if (opcode == OP_CBRA || opcode == OP_SC Line 5453  if (opcode == OP_CBRA || opcode == OP_SC
5453    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5454    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
5455    offset <<= 1;    offset <<= 1;
5456    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5457    hotpath += IMM2_SIZE;    trypath += IMM2_SIZE;
5458    }    }
5459  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5460    {    {
5461    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5462    localptr = PRIV_DATA(ccbegin);    localptr = PRIV_DATA(ccbegin);
5463    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
5464    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->localptr = localptr;
5465    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5466      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5467    }    }
5468    
5469  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4539  if (bra == OP_BRAZERO) Line 5488  if (bra == OP_BRAZERO)
5488    
5489  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5490    {    {
5491    /* This is a fallback path! (Since the hot-path of OP_BRAMINZERO matches to the empty string) */    /* This is a backtrack path! (Since the try-path of OP_BRAMINZERO matches to the empty string) */
5492    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5493    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
5494      {      {
# Line 4556  if (bra == OP_BRAMINZERO) Line 5505  if (bra == OP_BRAMINZERO)
5505        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
5506        JUMPHERE(jump);        JUMPHERE(jump);
5507        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5508        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5509          {          {
5510          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, localptr contains the previous STR_PTR. */
5511          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4565  if (bra == OP_BRAMINZERO) Line 5514  if (bra == OP_BRAMINZERO)
5514          {          {
5515          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5516          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5517          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));          braminzerojump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), (BACKTRACK_AS(bracket_backtrack)->u.framesize + 1) * sizeof(sljit_w));
5518          }          }
5519        JUMPHERE(skip);        JUMPHERE(skip);
5520        }        }
# Line 4579  if (bra == OP_BRAMINZERO) Line 5528  if (bra == OP_BRAMINZERO)
5528    }    }
5529    
5530  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5531    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5532    
5533  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5534    {    {
5535    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5536    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5537      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alttrypath = rmaxlabel;
5538    }    }
5539    
5540  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
5541  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5542    {    {
5543    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5544      {      {
5545      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5546      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
# Line 4615  if (opcode == OP_ONCE) Line 5564  if (opcode == OP_ONCE)
5564      {      {
5565      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5566        {        {
5567        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5568        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5569        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize + 1));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize + 1));
5570        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5571        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5572        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5573        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize + 1, 2, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1, 2, FALSE);
5574        }        }
5575      else      else
5576        {        {
5577        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5578        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5579        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(FALLBACK_AS(bracket_fallback)->u.framesize));        OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(BACKTRACK_AS(bracket_backtrack)->u.framesize));
5580        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);
5581        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5582        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5583        }        }
5584      }      }
5585    }    }
# Line 4664  else if (has_alternatives) Line 5613  else if (has_alternatives)
5613  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5614  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5615    {    {
5616    if (*hotpath == OP_CREF)    if (*trypath == OP_CREF)
5617      {      {
5618      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5619      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5620        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(trypath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5621      hotpath += 1 + IMM2_SIZE;      trypath += 1 + IMM2_SIZE;
5622      }      }
5623    else if (*hotpath == OP_NCREF)    else if (*trypath == OP_NCREF)
5624      {      {
5625      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5626      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
5627      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5628    
5629      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5630      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5631      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
5632      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
5633      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5634      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5635      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
5636      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5637      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5638    
5639      JUMPHERE(jump);      JUMPHERE(jump);
5640      hotpath += 1 + IMM2_SIZE;      trypath += 1 + IMM2_SIZE;
5641      }      }
5642    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*trypath == OP_RREF || *trypath == OP_NRREF)
5643      {      {
5644      /* Never has other case. */      /* Never has other case. */
5645      FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5646    
5647      stacksize = GET2(hotpath, 1);      stacksize = GET2(trypath, 1);
5648      if (common->currententry == NULL)      if (common->currententry == NULL)
5649        stacksize = 0;        stacksize = 0;
5650      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4705  if (opcode == OP_COND || opcode == OP_SC Line 5654  if (opcode == OP_COND || opcode == OP_SC
5654      else      else
5655        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5656    
5657      if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)      if (*trypath == OP_RREF || stacksize || common->currententry == NULL)
5658        {        {
5659        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5660        if (stacksize != 0)        if (stacksize != 0)
5661          hotpath += 1 + IMM2_SIZE;          trypath += 1 + IMM2_SIZE;
5662        else        else
5663          {          {
5664          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5665            {            {
5666            hotpath = cc + 1 + LINK_SIZE;            trypath = cc + 1 + LINK_SIZE;
5667            cc += GET(cc, 1);            cc += GET(cc, 1);
5668            }            }
5669          else          else
5670            hotpath = cc;            trypath = cc;
5671          }          }
5672        }        }
5673      else      else
5674        {        {
5675        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5676    
5677        stacksize = GET2(hotpath, 1);        stacksize = GET2(trypath, 1);
5678        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5679        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
5680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
5681        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
5682        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
5683        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);        GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, 0);
5684        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5685        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
5686        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5687        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
5688        hotpath += 1 + IMM2_SIZE;        trypath += 1 + IMM2_SIZE;
5689        }        }
5690      }      }
5691    else    else
5692      {      {
5693      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *trypath >= OP_ASSERT && *trypath <= OP_ASSERTBACK_NOT);
5694      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5695      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5696      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5697        return NULL;        return NULL;
5698      memset(assert, 0, sizeof(assert_fallback));      memset(assert, 0, sizeof(assert_backtrack));
5699      assert->common.cc = hotpath;      assert->common.cc = trypath;
5700      FALLBACK_AS(bracket_fallback)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5701      hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);      trypath = compile_assert_trypath(common, trypath, assert, TRUE);
5702      }      }
5703    }    }
5704    
5705  compile_hotpath(common, hotpath, cc, fallback);  compile_trypath(common, trypath, cc, backtrack);
5706  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5707    return NULL;    return NULL;
5708    
5709  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5710    {    {
5711    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5712      {      {
5713      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5714      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 4774  if (opcode == OP_ONCE) Line 5723  if (opcode == OP_ONCE)
5723    else    else
5724      {      {
5725      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5726      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5727      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5728        {        {
5729        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 4809  if (has_alternatives) Line 5758  if (has_alternatives)
5758    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5759      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5760    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5761      FALLBACK_AS(bracket_fallback)->althotpath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5762    }    }
5763    
5764  /* Must be after the hotpath label. */  /* Must be after the trypath label. */
5765  if (offset != 0)  if (offset != 0)
5766    {    {
5767    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4825  if (ket == OP_KETRMAX) Line 5774  if (ket == OP_KETRMAX)
5774    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5775      {      {
5776      if (has_alternatives)      if (has_alternatives)
5777        FALLBACK_AS(bracket_fallback)->althotpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alttrypath = LABEL();
5778      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5779      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5780          {
5781        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);
5782          /* Drop STR_PTR for greedy plus quantifier. */
5783          if (bra != OP_BRAZERO)
5784            free_stack(common, 1);
5785          }
5786      else      else
5787        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5788        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5789      }      }
5790    else    else
5791      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5792    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursivetrypath = LABEL();
5793    }    }
5794    
5795  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5796    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zerotrypath = LABEL();
5797    
5798  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5799    {    {
5800    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5801    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->trypath);
5802    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5803      {      {
5804      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5805      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5806      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5807      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5808      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5809        {        {
5810        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5811        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 4859  if (bra == OP_BRAMINZERO) Line 5813  if (bra == OP_BRAMINZERO)
5813      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5814        free_stack(common, 1);        free_stack(common, 1);
5815      }      }
5816    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5817    }    }
5818    
5819  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
# Line 4872  cc += 1 + LINK_SIZE; Line 5826  cc += 1 + LINK_SIZE;
5826  return cc;  return cc;
5827  }  }
5828    
5829  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5830  {  {
5831  DEFINE_COMPILER;  DEFINE_COMPILER;
5832  fallback_common *fallback;  backtrack_common *backtrack;
5833  pcre_uchar opcode;  pcre_uchar opcode;
5834  int localptr;  int localptr;
5835  int cbraprivptr = 0;  int cbraprivptr = 0;
# Line 4888  int stack; Line 5842  int stack;
5842  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5843  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5844    
5845  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5846  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5847    {    {
5848    zero = TRUE;    zero = TRUE;
# Line 4898  if (*cc == OP_BRAPOSZERO) Line 5852  if (*cc == OP_BRAPOSZERO)
5852  opcode = *cc;  opcode = *cc;
5853  localptr = PRIV_DATA(cc);  localptr = PRIV_DATA(cc);
5854  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
5855  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->localptr = localptr;
5856  switch(opcode)  switch(opcode)
5857    {    {
5858    case OP_BRAPOS:    case OP_BRAPOS:
# Line 4920  switch(opcode) Line 5874  switch(opcode)
5874    }    }
5875    
5876  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5877  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5878  if (framesize < 0)  if (framesize < 0)
5879    {    {
5880    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5881    if (!zero)    if (!zero)
5882      stacksize++;      stacksize++;
5883    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5884    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5885    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);
5886    
# Line 4950  else Line 5904  else
5904      stacksize++;      stacksize++;
5905    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5906      stacksize++;      stacksize++;
5907    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5908    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5909    
5910    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
# Line 4977  if (opcode == OP_CBRAPOS || opcode == OP Line 5931  if (opcode == OP_CBRAPOS || opcode == OP
5931  loop = LABEL();  loop = LABEL();
5932  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
5933    {    {
5934    fallback->top = NULL;    backtrack->top = NULL;
5935    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
5936    cc += GET(cc, 1);    cc += GET(cc, 1);
5937    
5938    compile_hotpath(common, ccbegin, cc, fallback);    compile_trypath(common, ccbegin, cc, backtrack);
5939    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5940      return NULL;      return NULL;
5941    
# Line 5042  while (*cc != OP_KETRPOS) Line 5996  while (*cc != OP_KETRPOS)
5996    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
5997    flush_stubs(common);    flush_stubs(common);
5998    
5999    compile_fallbackpath(common, fallback->top);    compile_backtrackpath(common, backtrack->top);
6000    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6001      return NULL;      return NULL;
6002    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
6003    
6004    if (framesize < 0)    if (framesize < 0)
6005      {      {
# Line 5075  while (*cc != OP_KETRPOS) Line 6029  while (*cc != OP_KETRPOS)
6029    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6030    }    }
6031    
6032  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
6033  if (!zero)  if (!zero)
6034    {    {
6035    if (framesize < 0)    if (framesize < 0)
6036      add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0));
6037    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [localptr] above. */
6038      add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));      add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0));
6039    }    }
6040    
6041  /* None of them matched. */  /* None of them matched. */
# Line 5182  if (end != NULL) Line 6136  if (end != NULL)
6136  return cc;  return cc;
6137  }  }
6138    
6139  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6140  {  {
6141  DEFINE_COMPILER;  DEFINE_COMPILER;
6142  fallback_common *fallback;  backtrack_common *backtrack;
6143  pcre_uchar opcode;  pcre_uchar opcode;
6144  pcre_uchar type;  pcre_uchar type;
6145  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 5193  pcre_uchar* end; Line 6147  pcre_uchar* end;
6147  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6148  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6149  struct sljit_label *label;  struct sljit_label *label;
6150    int localptr = PRIV_DATA(cc);
6151    int base = (localptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6152    int offset0 = (localptr == 0) ? STACK(0) : localptr;
6153    int offset1 = (localptr == 0) ? STACK(1) : localptr + (int)sizeof(sljit_w);
6154    int tmp_base, tmp_offset;
6155    
6156  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6157