/[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 955 by zherczeg, Tue Apr 3 15:32:36 2012 UTC revision 1015 by ph10, Sun Aug 26 16:07:14 2012 UTC
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 82  The code generator follows the recursive Line 85  The code generator follows the recursive
85  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
86  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
87  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
88  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
89    
90    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
91    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  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.
95  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  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
97  branches on the hot path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Hot path: match happens.     Matching path: match happens.
101     Fallback path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Hot path: no need to perform a match.     Matching path: no need to perform a match.
104     Fallback path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
107  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 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A hot path   A matching path
115   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B hot path   B matching path
117   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D hot path   D matching path
119   return with successful match   return with successful match
120    
121   D fallback path   D backtrack path
122   ')' 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")
123   B fallback path   B backtrack path
124   C expected path   C expected path
125   jump to D hot path   jump to D matching path
126   C fallback path   C backtrack path
127   A fallback path   A backtrack path
128    
129   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
130   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
131   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
132   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
133   the hot path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  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
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 181  typedef struct stub_list { Line 184  typedef struct stub_list {
184    enum stub_types type;    enum stub_types type;
185    int data;    int data;
186    struct sljit_jump *start;    struct sljit_jump *start;
187    struct sljit_label *leave;    struct sljit_label *quit;
188    struct stub_list *next;    struct stub_list *next;
189  } stub_list;  } stub_list;
190    
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct fallback_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
199    struct fallback_common *prev;    struct backtrack_common *prev;
200    jump_list *nextfallbacks;    jump_list *nextbacktracks;
201    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
202    struct fallback_common *top;    struct backtrack_common *top;
203    jump_list *topfallbacks;    jump_list *topbacktracks;
204    /* Opcode pointer. */    /* Opcode pointer. */
205    pcre_uchar *cc;    pcre_uchar *cc;
206  } fallback_common;  } backtrack_common;
207    
208  typedef struct assert_fallback {  typedef struct assert_backtrack {
209    fallback_common common;    backtrack_common common;
210    jump_list *condfailed;    jump_list *condfailed;
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
217  } assert_fallback;  } assert_backtrack;
218    
219  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
220    fallback_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
230      jump_list *condfailed;      jump_list *condfailed;
231      assert_fallback *assert;      assert_backtrack *assert;
232      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_fallback;  } bracket_backtrack;
238    
239  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
240    fallback_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
246    int stacksize;    int stacksize;
247  } bracketpos_fallback;  } bracketpos_backtrack;
248    
249  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
250    fallback_common common;    backtrack_common common;
251    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
252  } braminzero_fallback;  } braminzero_backtrack;
253    
254  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
255    fallback_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
258  } iterator_fallback;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
261    struct recurse_entry *next;    struct recurse_entry *next;
# Line 264  typedef struct recurse_entry { Line 267  typedef struct recurse_entry {
267    int start;    int start;
268  } recurse_entry;  } recurse_entry;
269    
270  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
271    fallback_common common;    backtrack_common common;
272  } recurse_fallback;  } recurse_backtrack;
273    
274    #define MAX_RANGE_SIZE 6
275    
276  typedef struct compiler_common {  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    pcre_uchar *start;    pcre_uchar *start;
279    
280    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
281    int *localptrs;    int *private_data_ptrs;
282      /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
287    int ovector_start;    int ovector_start;
# Line 290  typedef struct compiler_common { Line 298  typedef struct compiler_common {
298    /* Points to the marked string. */    /* Points to the marked string. */
299    int mark_ptr;    int mark_ptr;
300    
301    /* Other  */    /* Flipped and lower case tables. */
302    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
303    sljit_w lcc;    sljit_w lcc;
304      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
305    int mode;    int mode;
306      /* Newline control. */
307    int nltype;    int nltype;
308    int newline;    int newline;
309    int bsr_nltype;    int bsr_nltype;
310      /* Dollar endonly. */
311    int endonly;    int endonly;
312    BOOL has_set_som;    BOOL has_set_som;
313      /* Tables. */
314    sljit_w ctypes;    sljit_w ctypes;
315      int digits[2 + MAX_RANGE_SIZE];
316      /* Named capturing brackets. */
317    sljit_uw name_table;    sljit_uw name_table;
318    sljit_w name_count;    sljit_w name_count;
319    sljit_w name_entry_size;    sljit_w name_entry_size;
320    
321    /* Labels and jump lists. */    /* Labels and jump lists. */
322    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
323    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
324    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
325    stub_list *stubs;    stub_list *stubs;
326    recurse_entry *entries;    recurse_entry *entries;
327    recurse_entry *currententry;    recurse_entry *currententry;
328    jump_list *partialmatch;    jump_list *partialmatch;
329    jump_list *leave;    jump_list *quit;
330    jump_list *accept;    jump_list *accept;
331    jump_list *calllimit;    jump_list *calllimit;
332    jump_list *stackalloc;    jump_list *stackalloc;
# Line 396  enum { Line 410  enum {
410  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
411  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
412    
413  /* Locals layout. */  /* Local space layout. */
414  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
415  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
416  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 412  the start pointers when the end of the c Line 426  the start pointers when the end of the c
426  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
427  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
428  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
429  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
430    
431  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
432  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
# Line 461  return cc; Line 475  return cc;
475    
476  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
477   next_opcode   next_opcode
478   get_localspace   get_private_data_length
479   set_localptrs   set_private_data_ptrs
480   get_framesize   get_framesize
481   init_frame   init_frame
482   get_localsize   get_private_data_length_for_copy
483   copy_locals   copy_private_data
484   compile_hotpath   compile_matchingpath
485   compile_fallbackpath   compile_backtrackingpath
486  */  */
487    
488  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 667  switch(*cc) Line 681  switch(*cc)
681    }    }
682  }  }
683    
684  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
685        case OP_MINSTAR: \
686        case OP_MINPLUS: \
687        case OP_QUERY: \
688        case OP_MINQUERY: \
689        case OP_MINSTARI: \
690        case OP_MINPLUSI: \
691        case OP_QUERYI: \
692        case OP_MINQUERYI: \
693        case OP_NOTMINSTAR: \
694        case OP_NOTMINPLUS: \
695        case OP_NOTQUERY: \
696        case OP_NOTMINQUERY: \
697        case OP_NOTMINSTARI: \
698        case OP_NOTMINPLUSI: \
699        case OP_NOTQUERYI: \
700        case OP_NOTMINQUERYI:
701    
702    #define CASE_ITERATOR_PRIVATE_DATA_2A \
703        case OP_STAR: \
704        case OP_PLUS: \
705        case OP_STARI: \
706        case OP_PLUSI: \
707        case OP_NOTSTAR: \
708        case OP_NOTPLUS: \
709        case OP_NOTSTARI: \
710        case OP_NOTPLUSI:
711    
712    #define CASE_ITERATOR_PRIVATE_DATA_2B \
713        case OP_UPTO: \
714        case OP_MINUPTO: \
715        case OP_UPTOI: \
716        case OP_MINUPTOI: \
717        case OP_NOTUPTO: \
718        case OP_NOTMINUPTO: \
719        case OP_NOTUPTOI: \
720        case OP_NOTMINUPTOI:
721    
722    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
723        case OP_TYPEMINSTAR: \
724        case OP_TYPEMINPLUS: \
725        case OP_TYPEQUERY: \
726        case OP_TYPEMINQUERY:
727    
728    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
729        case OP_TYPESTAR: \
730        case OP_TYPEPLUS:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
733        case OP_TYPEUPTO: \
734        case OP_TYPEMINUPTO:
735    
736    static int get_class_iterator_size(pcre_uchar *cc)
737  {  {
738  int localspace = 0;  switch(*cc)
739      {
740      case OP_CRSTAR:
741      case OP_CRPLUS:
742      return 2;
743    
744      case OP_CRMINSTAR:
745      case OP_CRMINPLUS:
746      case OP_CRQUERY:
747      case OP_CRMINQUERY:
748      return 1;
749    
750      case OP_CRRANGE:
751      case OP_CRMINRANGE:
752      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
753        return 0;
754      return 2;
755    
756      default:
757      return 0;
758      }
759    }
760    
761    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
762    {
763    int private_data_length = 0;
764  pcre_uchar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766    pcre_uchar *end = NULL;
767    int space, size, bracketlen, i;
768    
769  /* 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. */
770  while (cc < ccend)  while (cc < ccend)
771    {    {
772      space = 0;
773      size = 0;
774      bracketlen = 0;
775    switch(*cc)    switch(*cc)
776      {      {
777      case OP_SET_SOM:      case OP_SET_SOM:
# Line 681  while (cc < ccend) Line 779  while (cc < ccend)
779      cc += 1;      cc += 1;
780      break;      break;
781    
782        case OP_REF:
783        case OP_REFI:
784        common->optimized_cbracket[GET2(cc, 1)] = 0;
785        cc += 1 + IMM2_SIZE;
786        break;
787    
788      case OP_ASSERT:      case OP_ASSERT:
789      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
790      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 690  while (cc < ccend) Line 794  while (cc < ccend)
794      case OP_BRAPOS:      case OP_BRAPOS:
795      case OP_SBRA:      case OP_SBRA:
796      case OP_SBRAPOS:      case OP_SBRAPOS:
797      case OP_SCOND:      private_data_length += sizeof(sljit_w);
798      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
799      break;      break;
800    
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
804      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
806      break;      break;
807    
808      case OP_COND:      case OP_COND:
809      /* Might be a hidden SCOND. */      case OP_SCOND:
810      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
811      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
812        localspace += sizeof(sljit_w);        {
813      cc += 1 + LINK_SIZE;        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
814          common->optimized_cbracket[bracketlen] = 0;
815          }
816        else if (bracketlen == OP_NCREF)
817          {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          name = (pcre_uchar *)common->name_table;
820          alternative = name;
821          for (i = 0; i < common->name_count; i++)
822            {
823            if (GET2(name, 0) == bracketlen) break;
824            name += common->name_entry_size;
825            }
826          SLJIT_ASSERT(i != common->name_count);
827    
828          for (i = 0; i < common->name_count; i++)
829            {
830            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
831              common->optimized_cbracket[GET2(alternative, 0)] = 0;
832            alternative += common->name_entry_size;
833            }
834          }
835    
836        if (*cc == OP_COND)
837          {
838          /* Might be a hidden SCOND. */
839          alternative = cc + GET(cc, 1);
840          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
841            private_data_length += sizeof(sljit_w);
842          }
843        else
844          private_data_length += sizeof(sljit_w);
845        bracketlen = 1 + LINK_SIZE;
846        break;
847    
848        case OP_BRA:
849        bracketlen = 1 + LINK_SIZE;
850        break;
851    
852        case OP_CBRA:
853        case OP_SCBRA:
854        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
855        break;
856    
857        CASE_ITERATOR_PRIVATE_DATA_1
858        space = 1;
859        size = -2;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_2A
863        space = 2;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2B
868        space = 2;
869        size = -(2 + IMM2_SIZE);
870        break;
871    
872        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
873        space = 1;
874        size = 1;
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
878        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
879          space = 2;
880        size = 1;
881        break;
882    
883        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
884        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
885          space = 2;
886        size = 1 + IMM2_SIZE;
887      break;      break;
888    
889        case OP_CLASS:
890        case OP_NCLASS:
891        size += 1 + 32 / sizeof(pcre_uchar);
892        space = get_class_iterator_size(cc + size);
893        break;
894    
895    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
896        case OP_XCLASS:
897        size = GET(cc, 1);
898        space = get_class_iterator_size(cc + size);
899        break;
900    #endif
901    
902      case OP_RECURSE:      case OP_RECURSE:
903      /* Set its value only once. */      /* Set its value only once. */
904      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 734  while (cc < ccend) Line 924  while (cc < ccend)
924        return -1;        return -1;
925      break;      break;
926      }      }
927    
928      if (space > 0 && cc >= end)
929        private_data_length += sizeof(sljit_w) * space;
930    
931      if (size != 0)
932        {
933        if (size < 0)
934          {
935          cc += -size;
936    #ifdef SUPPORT_UTF
937          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
938    #endif
939          }
940        else
941          cc += size;
942        }
943    
944      if (bracketlen > 0)
945        {
946        if (cc >= end)
947          {
948          end = bracketend(cc);
949          if (end[-1 - LINK_SIZE] == OP_KET)
950            end = NULL;
951          }
952        cc += bracketlen;
953        }
954    }    }
955  return localspace;  return private_data_length;
956  }  }
957    
958  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
959  {  {
960  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
961  pcre_uchar *alternative;  pcre_uchar *alternative;
962    pcre_uchar *end = NULL;
963    int space, size, bracketlen;
964    
965  while (cc < ccend)  while (cc < ccend)
966    {    {
967      space = 0;
968      size = 0;
969      bracketlen = 0;
970    switch(*cc)    switch(*cc)
971      {      {
972      case OP_ASSERT:      case OP_ASSERT:
# Line 756  while (cc < ccend) Line 979  while (cc < ccend)
979      case OP_SBRA:      case OP_SBRA:
980      case OP_SBRAPOS:      case OP_SBRAPOS:
981      case OP_SCOND:      case OP_SCOND:
982      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
983      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
984      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
985      break;      break;
986    
987      case OP_CBRAPOS:      case OP_CBRAPOS:
988      case OP_SCBRAPOS:      case OP_SCBRAPOS:
989      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
990      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
991      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
994      case OP_COND:      case OP_COND:
# Line 773  while (cc < ccend) Line 996  while (cc < ccend)
996      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
997      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
998        {        {
999        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1000        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1001        }        }
1002      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1003        break;
1004    
1005        case OP_BRA:
1006        bracketlen = 1 + LINK_SIZE;
1007        break;
1008    
1009        case OP_CBRA:
1010        case OP_SCBRA:
1011        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1012        break;
1013    
1014        CASE_ITERATOR_PRIVATE_DATA_1
1015        space = 1;
1016        size = -2;
1017        break;
1018    
1019        CASE_ITERATOR_PRIVATE_DATA_2A
1020        space = 2;
1021        size = -2;
1022        break;
1023    
1024        CASE_ITERATOR_PRIVATE_DATA_2B
1025        space = 2;
1026        size = -(2 + IMM2_SIZE);
1027        break;
1028    
1029        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1030        space = 1;
1031        size = 1;
1032        break;
1033    
1034        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1035        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1036          space = 2;
1037        size = 1;
1038        break;
1039    
1040        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1041        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1042          space = 2;
1043        size = 1 + IMM2_SIZE;
1044        break;
1045    
1046        case OP_CLASS:
1047        case OP_NCLASS:
1048        size += 1 + 32 / sizeof(pcre_uchar);
1049        space = get_class_iterator_size(cc + size);
1050        break;
1051    
1052    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1053        case OP_XCLASS:
1054        size = GET(cc, 1);
1055        space = get_class_iterator_size(cc + size);
1056      break;      break;
1057    #endif
1058    
1059      default:      default:
1060      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1061      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1062      break;      break;
1063      }      }
1064    
1065      if (space > 0 && cc >= end)
1066        {
1067        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1068        private_data_ptr += sizeof(sljit_w) * space;
1069        }
1070    
1071      if (size != 0)
1072        {
1073        if (size < 0)
1074          {
1075          cc += -size;
1076    #ifdef SUPPORT_UTF
1077          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1078    #endif
1079          }
1080        else
1081          cc += size;
1082        }
1083    
1084      if (bracketlen > 0)
1085        {
1086        if (cc >= end)
1087          {
1088          end = bracketend(cc);
1089          if (end[-1 - LINK_SIZE] == OP_KET)
1090            end = NULL;
1091          }
1092        cc += bracketlen;
1093        }
1094    }    }
1095  }  }
1096    
# Line 960  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1267  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1267  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1268  }  }
1269    
1270  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1271  {  {
1272  int localsize = 2;  int private_data_length = 2;
1273    int size;
1274  pcre_uchar *alternative;  pcre_uchar *alternative;
1275  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1276  while (cc < ccend)  while (cc < ccend)
1277    {    {
1278      size = 0;
1279    switch(*cc)    switch(*cc)
1280      {      {
1281      case OP_ASSERT:      case OP_ASSERT:
# Line 979  while (cc < ccend) Line 1288  while (cc < ccend)
1288      case OP_SBRA:      case OP_SBRA:
1289      case OP_SBRAPOS:      case OP_SBRAPOS:
1290      case OP_SCOND:      case OP_SCOND:
1291      localsize++;      private_data_length++;
1292      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1293      break;      break;
1294    
1295      case OP_CBRA:      case OP_CBRA:
1296      case OP_SCBRA:      case OP_SCBRA:
1297      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1298          private_data_length++;
1299      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1300      break;      break;
1301    
1302      case OP_CBRAPOS:      case OP_CBRAPOS:
1303      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1304      localsize += 2;      private_data_length += 2;
1305      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1306      break;      break;
1307    
# Line 999  while (cc < ccend) Line 1309  while (cc < ccend)
1309      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1310      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1311      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1312        localsize++;        private_data_length++;
1313      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1314      break;      break;
1315    
1316        CASE_ITERATOR_PRIVATE_DATA_1
1317        if (PRIVATE_DATA(cc))
1318          private_data_length++;
1319        cc += 2;
1320    #ifdef SUPPORT_UTF
1321        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1322    #endif
1323        break;
1324    
1325        CASE_ITERATOR_PRIVATE_DATA_2A
1326        if (PRIVATE_DATA(cc))
1327          private_data_length += 2;
1328        cc += 2;
1329    #ifdef SUPPORT_UTF
1330        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1331    #endif
1332        break;
1333    
1334        CASE_ITERATOR_PRIVATE_DATA_2B
1335        if (PRIVATE_DATA(cc))
1336          private_data_length += 2;
1337        cc += 2 + IMM2_SIZE;
1338    #ifdef SUPPORT_UTF
1339        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1340    #endif
1341        break;
1342    
1343        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1344        if (PRIVATE_DATA(cc))
1345          private_data_length++;
1346        cc += 1;
1347        break;
1348    
1349        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1350        if (PRIVATE_DATA(cc))
1351          private_data_length += 2;
1352        cc += 1;
1353        break;
1354    
1355        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1356        if (PRIVATE_DATA(cc))
1357          private_data_length += 2;
1358        cc += 1 + IMM2_SIZE;
1359        break;
1360    
1361        case OP_CLASS:
1362        case OP_NCLASS:
1363    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1364        case OP_XCLASS:
1365        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1366    #else
1367        size = 1 + 32 / (int)sizeof(pcre_uchar);
1368    #endif
1369        if (PRIVATE_DATA(cc))
1370          private_data_length += get_class_iterator_size(cc + size);
1371        cc += size;
1372        break;
1373    
1374      default:      default:
1375      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1376      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1010  while (cc < ccend) Line 1378  while (cc < ccend)
1378      }      }
1379    }    }
1380  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1381  return localsize;  return private_data_length;
1382  }  }
1383    
1384  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1385    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1386  {  {
1387  DEFINE_COMPILER;  DEFINE_COMPILER;
1388  int srcw[2];  int srcw[2];
1389  int count;  int count, size;
1390  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1391  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1392  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1083  while (status != end) Line 1451  while (status != end)
1451        case OP_SBRAPOS:        case OP_SBRAPOS:
1452        case OP_SCOND:        case OP_SCOND:
1453        count = 1;        count = 1;
1454        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1455        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1456        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1457        break;        break;
1458    
1459        case OP_CBRA:        case OP_CBRA:
1460        case OP_SCBRA:        case OP_SCBRA:
1461        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1462        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1463            count = 1;
1464            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1465            }
1466        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1467        break;        break;
1468    
1469        case OP_CBRAPOS:        case OP_CBRAPOS:
1470        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1471        count = 2;        count = 2;
1472          srcw[0] = PRIVATE_DATA(cc);
1473        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1474        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1475        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1476        break;        break;
1477    
# Line 1110  while (status != end) Line 1481  while (status != end)
1481        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1482          {          {
1483          count = 1;          count = 1;
1484          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1485          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1486          }          }
1487        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1488        break;        break;
1489    
1490          CASE_ITERATOR_PRIVATE_DATA_1
1491          if (PRIVATE_DATA(cc))
1492            {
1493            count = 1;
1494            srcw[0] = PRIVATE_DATA(cc);
1495            }
1496          cc += 2;
1497    #ifdef SUPPORT_UTF
1498          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1499    #endif
1500          break;
1501    
1502          CASE_ITERATOR_PRIVATE_DATA_2A
1503          if (PRIVATE_DATA(cc))
1504            {
1505            count = 2;
1506            srcw[0] = PRIVATE_DATA(cc);
1507            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1508            }
1509          cc += 2;
1510    #ifdef SUPPORT_UTF
1511          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1512    #endif
1513          break;
1514    
1515          CASE_ITERATOR_PRIVATE_DATA_2B
1516          if (PRIVATE_DATA(cc))
1517            {
1518            count = 2;
1519            srcw[0] = PRIVATE_DATA(cc);
1520            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1521            }
1522          cc += 2 + IMM2_SIZE;
1523    #ifdef SUPPORT_UTF
1524          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1525    #endif
1526          break;
1527    
1528          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1529          if (PRIVATE_DATA(cc))
1530            {
1531            count = 1;
1532            srcw[0] = PRIVATE_DATA(cc);
1533            }
1534          cc += 1;
1535          break;
1536    
1537          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1538          if (PRIVATE_DATA(cc))
1539            {
1540            count = 2;
1541            srcw[0] = PRIVATE_DATA(cc);
1542            srcw[1] = srcw[0] + sizeof(sljit_w);
1543            }
1544          cc += 1;
1545          break;
1546    
1547          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1548          if (PRIVATE_DATA(cc))
1549            {
1550            count = 2;
1551            srcw[0] = PRIVATE_DATA(cc);
1552            srcw[1] = srcw[0] + sizeof(sljit_w);
1553            }
1554          cc += 1 + IMM2_SIZE;
1555          break;
1556    
1557          case OP_CLASS:
1558          case OP_NCLASS:
1559    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1560          case OP_XCLASS:
1561          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1562    #else
1563          size = 1 + 32 / (int)sizeof(pcre_uchar);
1564    #endif
1565          if (PRIVATE_DATA(cc))
1566            switch(get_class_iterator_size(cc + size))
1567              {
1568              case 1:
1569              count = 1;
1570              srcw[0] = PRIVATE_DATA(cc);
1571              break;
1572    
1573              case 2:
1574              count = 2;
1575              srcw[0] = PRIVATE_DATA(cc);
1576              srcw[1] = srcw[0] + sizeof(sljit_w);
1577              break;
1578    
1579              default:
1580              SLJIT_ASSERT_STOP();
1581              break;
1582              }
1583          cc += size;
1584          break;
1585    
1586        default:        default:
1587        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1588        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1218  if (save) Line 1685  if (save)
1685  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1686  }  }
1687    
1688    #undef CASE_ITERATOR_PRIVATE_DATA_1
1689    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1690    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1691    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1692    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1693    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1694    
1695  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1696  {  {
1697  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1228  static SLJIT_INLINE void set_jumps(jump_ Line 1702  static SLJIT_INLINE void set_jumps(jump_
1702  while (list)  while (list)
1703    {    {
1704    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1705    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1706    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1707    list = list->next;    list = list->next;
1708    }    }
# Line 1255  if (list_item) Line 1729  if (list_item)
1729    list_item->type = type;    list_item->type = type;
1730    list_item->data = data;    list_item->data = data;
1731    list_item->start = start;    list_item->start = start;
1732    list_item->leave = LABEL();    list_item->quit = LABEL();
1733    list_item->next = common->stubs;    list_item->next = common->stubs;
1734    common->stubs = list_item;    common->stubs = list_item;
1735    }    }
# Line 1275  while (list_item) Line 1749  while (list_item)
1749      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1750      break;      break;
1751      }      }
1752    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1753    list_item = list_item->next;    list_item = list_item->next;
1754    }    }
1755  common->stubs = NULL;  common->stubs = NULL;
# Line 1385  else Line 1859  else
1859    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1860  }  }
1861    
1862  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)
1863  {  {
1864  DEFINE_COMPILER;  DEFINE_COMPILER;
1865    
# Line 1395  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1869  SLJIT_ASSERT(common->start_used_ptr != 0
1869  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1870  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1871  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));
1872  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1873    
1874  /* Store match begin and end. */  /* Store match begin and end. */
1875  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));
# Line 1413  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, Line 1887  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0,
1887  #endif  #endif
1888  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);
1889    
1890  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1891  }  }
1892    
1893  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1622  JUMPHERE(jump); Line 2096  JUMPHERE(jump);
2096  return return_value;  return return_value;
2097  }  }
2098    
2099  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2100  {  {
2101  DEFINE_COMPILER;  DEFINE_COMPILER;
2102  struct sljit_jump *jump;  struct sljit_jump *jump;
2103    
2104  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2105    {    {
2106    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));
2107    return;    return;
2108    }    }
2109    
2110  /* Partial matching mode. */  /* Partial matching mode. */
2111  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2112  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2113  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2114    {    {
2115    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2116    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2117    }    }
2118  else  else
2119    {    {
# Line 1789  if (common->utf) Line 2263  if (common->utf)
2263  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));
2264  }  }
2265    
2266  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)
2267  {  {
2268  /* 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. */
2269  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1797  DEFINE_COMPILER; Line 2271  DEFINE_COMPILER;
2271  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2272    {    {
2273    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2274    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));
2275    }    }
2276  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2277    {    {
# Line 1805  else if (nltype == NLTYPE_ANYCRLF) Line 2279  else if (nltype == NLTYPE_ANYCRLF)
2279    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2280    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);
2281    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2282    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));
2283    }    }
2284  else  else
2285    {    {
2286    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2287    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));
2288    }    }
2289  }  }
2290    
# Line 1994  if (firstline) Line 2468  if (firstline)
2468    {    {
2469    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2470    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2471    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2472    
2473    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2474      {      {
# Line 2006  if (firstline) Line 2479  if (firstline)
2479      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2480      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);
2481      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);
2482        JUMPHERE(end);
2483      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2484      }      }
2485    else    else
# Line 2017  if (firstline) Line 2491  if (firstline)
2491      read_char(common);      read_char(common);
2492      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2493      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2494        JUMPHERE(end);
2495      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2496      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2497      }      }
2498    
2499    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2500    }    }
2501    
2502  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2082  JUMPHERE(start); Line 2556  JUMPHERE(start);
2556    
2557  if (newlinecheck)  if (newlinecheck)
2558    {    {
2559    JUMPHERE(end);    JUMPHERE(end);
2560    JUMPHERE(nl);    JUMPHERE(nl);
2561      }
2562    
2563    return mainloop;
2564    }
2565    
2566    static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2567    {
2568    DEFINE_COMPILER;
2569    struct sljit_label *start;
2570    struct sljit_jump *quit;
2571    struct sljit_jump *found;
2572    pcre_int32 chars[4];
2573    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2574    int location = 0;
2575    pcre_int32 len, c, bit, caseless;
2576    BOOL must_end;
2577    
2578    #ifdef COMPILE_PCRE8
2579    union {
2580        sljit_uh ascombined;
2581        sljit_ub asuchars[2];
2582    } pair;
2583    #else
2584    union {
2585        sljit_ui ascombined;
2586        sljit_uh asuchars[2];
2587    } pair;
2588    #endif
2589    
2590    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2591      return FALSE;
2592    
2593    while (TRUE)
2594      {
2595      caseless = 0;
2596      must_end = TRUE;
2597      switch(*cc)
2598        {
2599        case OP_CHAR:
2600        must_end = FALSE;
2601        cc++;
2602        break;
2603    
2604        case OP_CHARI:
2605        caseless = 1;
2606        must_end = FALSE;
2607        cc++;
2608        break;
2609    
2610        case OP_SOD:
2611        case OP_SOM:
2612        case OP_SET_SOM:
2613        case OP_NOT_WORD_BOUNDARY:
2614        case OP_WORD_BOUNDARY:
2615        case OP_EODN:
2616        case OP_EOD:
2617        case OP_CIRC:
2618        case OP_CIRCM:
2619        case OP_DOLL:
2620        case OP_DOLLM:
2621        /* Zero width assertions. */
2622        cc++;
2623        continue;
2624    
2625        case OP_PLUS:
2626        case OP_MINPLUS:
2627        case OP_POSPLUS:
2628        cc++;
2629        break;
2630    
2631        case OP_EXACT:
2632        cc += 1 + IMM2_SIZE;
2633        break;
2634    
2635        case OP_PLUSI:
2636        case OP_MINPLUSI:
2637        case OP_POSPLUSI:
2638        caseless = 1;
2639        cc++;
2640        break;
2641    
2642        case OP_EXACTI:
2643        caseless = 1;
2644        cc += 1 + IMM2_SIZE;
2645        break;
2646    
2647        default:
2648        return FALSE;
2649        }
2650    
2651      len = 1;
2652    #ifdef SUPPORT_UTF
2653      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2654    #endif
2655    
2656      if (caseless && char_has_othercase(common, cc))
2657        {
2658        caseless = char_get_othercase_bit(common, cc);
2659        if (caseless == 0)
2660          return FALSE;
2661    #ifdef COMPILE_PCRE8
2662        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2663    #else
2664        if ((caseless & 0x100) != 0)
2665          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2666        else
2667          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2668    #endif
2669        }
2670      else
2671        caseless = 0;
2672    
2673      while (len > 0 && location < 2 * 2)
2674        {
2675        c = *cc;
2676        bit = 0;
2677        if (len == (caseless & 0xff))
2678          {
2679          bit = caseless >> 8;
2680          c |= bit;
2681          }
2682    
2683        chars[location] = c;
2684        chars[location + 1] = bit;
2685    
2686        len--;
2687        location += 2;
2688        cc++;
2689        }
2690    
2691      if (location == 2 * 2)
2692        break;
2693      else if (must_end)
2694        return FALSE;
2695      }
2696    
2697    if (firstline)
2698      {
2699      SLJIT_ASSERT(common->first_line_end != 0);
2700      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2701      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2702      }
2703    else
2704      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    
2706    start = LABEL();
2707    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2708    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2709    #ifdef COMPILE_PCRE8
2710    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2711    #else /* COMPILE_PCRE8 */
2712    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2713    #endif
2714    
2715    #else /* SLJIT_UNALIGNED */
2716    
2717    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2718    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2719    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2720    #else /* SLJIT_BIG_ENDIAN */
2721    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2722    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2723    #endif /* SLJIT_BIG_ENDIAN */
2724    
2725    #ifdef COMPILE_PCRE8
2726    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2727    #else /* COMPILE_PCRE8 */
2728    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2729    #endif
2730    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2731    
2732    #endif
2733    
2734    if (chars[1] != 0 || chars[3] != 0)
2735      {
2736      pair.asuchars[0] = chars[1];
2737      pair.asuchars[1] = chars[3];
2738      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2739    }    }
2740    
2741  return mainloop;  pair.asuchars[0] = chars[0];
2742    pair.asuchars[1] = chars[2];
2743    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2744    
2745    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2746    JUMPTO(SLJIT_JUMP, start);
2747    JUMPHERE(found);
2748    JUMPHERE(quit);
2749    
2750    if (firstline)
2751      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2752    else
2753      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2754    return TRUE;
2755  }  }
2756    
2757  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)
2758  {  {
2759  DEFINE_COMPILER;  DEFINE_COMPILER;
2760  struct sljit_label *start;  struct sljit_label *start;
2761  struct sljit_jump *leave;  struct sljit_jump *quit;
2762  struct sljit_jump *found;  struct sljit_jump *found;
2763  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2764    
2765  if (firstline)  if (firstline)
2766    {    {
2767    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2768      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2769    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2770    }    }
2771    
2772  start = LABEL();  start = LABEL();
2773  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2774  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2775    
2776  oc = first_char;  oc = first_char;
# Line 2137  else Line 2803  else
2803    }    }
2804    
2805  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  
2806  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2807  JUMPHERE(found);  JUMPHERE(found);
2808  JUMPHERE(leave);  JUMPHERE(quit);
2809    
2810  if (firstline)  if (firstline)
2811    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2812  }  }
2813    
2814  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 2170  DEFINE_COMPILER; Line 2817  DEFINE_COMPILER;
2817  struct sljit_label *loop;  struct sljit_label *loop;
2818  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2819  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2820  struct sljit_jump *leave;  struct sljit_jump *quit;
2821  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2822  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2823  jump_list *newline = NULL;  jump_list *newline = NULL;
2824    
2825  if (firstline)  if (firstline)
2826    {    {
2827    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2828      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2829    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2830    }    }
2831    
# Line 2199  if (common->nltype == NLTYPE_FIXED && co Line 2847  if (common->nltype == NLTYPE_FIXED && co
2847    
2848    loop = LABEL();    loop = LABEL();
2849    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));
2850    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2851    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2852    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2853    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);
2854    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);
2855    
2856    JUMPHERE(leave);    JUMPHERE(quit);
2857    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2858    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2859    
# Line 2229  set_jumps(newline, loop); Line 2877  set_jumps(newline, loop);
2877    
2878  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2879    {    {
2880    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2881    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2882    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2883    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
# Line 2240  if (common->nltype == NLTYPE_ANY || comm Line 2888  if (common->nltype == NLTYPE_ANY || comm
2888  #endif  #endif
2889    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2890    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2891    JUMPHERE(leave);    JUMPHERE(quit);
2892    }    }
2893  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2894  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2895    
2896  if (firstline)  if (firstline)
2897    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2898  }  }
2899    
2900  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)
2901  {  {
2902  DEFINE_COMPILER;  DEFINE_COMPILER;
2903  struct sljit_label *start;  struct sljit_label *start;
2904  struct sljit_jump *leave;  struct sljit_jump *quit;
2905  struct sljit_jump *found;  struct sljit_jump *found;
2906  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2907  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2261  struct sljit_jump *jump; Line 2909  struct sljit_jump *jump;
2909    
2910  if (firstline)  if (firstline)
2911    {    {
2912    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2913      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2914    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2915    }    }
2916    
2917  start = LABEL();  start = LABEL();
2918  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2919  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2920  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2921  if (common->utf)  if (common->utf)
# Line 2310  if (common->utf) Line 2959  if (common->utf)
2959  #endif  #endif
2960  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2961  JUMPHERE(found);  JUMPHERE(found);
2962  JUMPHERE(leave);  JUMPHERE(quit);
2963    
2964  if (firstline)  if (firstline)
2965    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2966  }  }
2967    
2968  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 2537  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3186  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3186  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3187  }  }
3188    
3189    /*
3190      range format:
3191    
3192      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3193      ranges[1] = first bit (0 or 1)
3194      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3195    */
3196    
3197    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3198    {
3199    DEFINE_COMPILER;
3200    struct sljit_jump *jump;
3201    
3202    if (ranges[0] < 0)
3203      return FALSE;
3204    
3205    switch(ranges[0])
3206      {
3207      case 1:
3208      if (readch)
3209        read_char(common);
3210      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3211      return TRUE;
3212    
3213      case 2:
3214      if (readch)
3215        read_char(common);
3216      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3217      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3218      return TRUE;
3219    
3220      case 4:
3221      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3222        {
3223        if (readch)
3224          read_char(common);
3225        if (ranges[1] != 0)
3226          {
3227          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3228          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3229          }
3230        else
3231          {
3232          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3233          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3234          JUMPHERE(jump);
3235          }
3236        return TRUE;
3237        }
3238      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3239        {
3240        if (readch)
3241          read_char(common);
3242        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3243        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3244        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3245        return TRUE;
3246        }
3247      return FALSE;
3248    
3249      default:
3250      return FALSE;
3251      }
3252    }
3253    
3254    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3255    {
3256    int i, bit, length;
3257    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3258    
3259    bit = ctypes[0] & flag;
3260    ranges[0] = -1;
3261    ranges[1] = bit != 0 ? 1 : 0;
3262    length = 0;
3263    
3264    for (i = 1; i < 256; i++)
3265      if ((ctypes[i] & flag) != bit)
3266        {
3267        if (length >= MAX_RANGE_SIZE)
3268          return;
3269        ranges[2 + length] = i;
3270        length++;
3271        bit ^= flag;
3272        }
3273    
3274    if (bit != 0)
3275      {
3276      if (length >= MAX_RANGE_SIZE)
3277        return;
3278      ranges[2 + length] = 256;
3279      length++;
3280      }
3281    ranges[0] = length;
3282    }
3283    
3284    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3285    {
3286    int ranges[2 + MAX_RANGE_SIZE];
3287    pcre_uint8 bit, cbit, all;
3288    int i, byte, length = 0;
3289    
3290    bit = bits[0] & 0x1;
3291    ranges[1] = bit;
3292    /* Can be 0 or 255. */
3293    all = -bit;
3294    
3295    for (i = 0; i < 256; )
3296      {
3297      byte = i >> 3;
3298      if ((i & 0x7) == 0 && bits[byte] == all)
3299        i += 8;
3300      else
3301        {
3302        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3303        if (cbit != bit)
3304          {
3305          if (length >= MAX_RANGE_SIZE)
3306            return FALSE;
3307          ranges[2 + length] = i;
3308          length++;
3309          bit = cbit;
3310          all = -cbit;
3311          }
3312        i++;
3313        }
3314      }
3315    
3316    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3317      {
3318      if (length >= MAX_RANGE_SIZE)
3319        return FALSE;
3320      ranges[2 + length] = 256;
3321      length++;
3322      }
3323    ranges[0] = length;
3324    
3325    return check_ranges(common, ranges, backtracks, FALSE);
3326    }
3327    
3328  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3329  {  {
3330  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 2733  return src2; Line 3521  return src2;
3521  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3522    
3523  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,
3524      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3525  {  {
3526  DEFINE_COMPILER;  DEFINE_COMPILER;
3527  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2834  do Line 3622  do
3622        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3623        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3624          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);
3625        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));
3626        break;        break;
3627    
3628        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3629        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3630          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);
3631        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));
3632        break;        break;
3633    
3634  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3635        case 1:        case 1:
3636        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3637          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);
3638        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));
3639        break;        break;
3640  #endif  #endif
3641    
# Line 2873  do Line 3661  do
3661    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3662      {      {
3663      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3664      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));
3665      }      }
3666    else    else
3667      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));
3668    
3669  #endif  #endif
3670    
# Line 2912  return cc; Line 3700  return cc;
3700      } \      } \
3701    charoffset = (value);    charoffset = (value);
3702    
3703  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3704  {  {
3705  DEFINE_COMPILER;  DEFINE_COMPILER;
3706  jump_list *found = NULL;  jump_list *found = NULL;
3707  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3708  unsigned int c;  unsigned int c;
3709  int compares;  int compares;
3710  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 2930  unsigned int typeoffset; Line 3718  unsigned int typeoffset;
3718  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3719  unsigned int charoffset;  unsigned int charoffset;
3720    
3721  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3722  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3723    detect_partial_match(common, backtracks);
3724  read_char(common);  read_char(common);
3725    
3726  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3733  if ((*cc++ & XCL_MAP) != 0)
3733      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3734  #endif  #endif
3735    
3736    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3737    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3738    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3739    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3740    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);
3741    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3742        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3743        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3744        }
3745    
3746  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3747    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3082  typeoffset = 0; Line 3874  typeoffset = 0;
3874  while (*cc != XCL_END)  while (*cc != XCL_END)
3875    {    {
3876    compares--;    compares--;
3877    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3878    jump = NULL;    jump = NULL;
3879    
3880    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3164  while (*cc != XCL_END) Line 3956  while (*cc != XCL_END)
3956      switch(*cc)      switch(*cc)
3957        {        {
3958        case PT_ANY:        case PT_ANY:
3959        if (list != fallbacks)        if (list != backtracks)
3960          {          {
3961          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))
3962            continue;            continue;
# Line 3237  while (*cc != XCL_END) Line 4029  while (*cc != XCL_END)
4029  #endif  #endif
4030    
4031    if (jump != NULL)    if (jump != NULL)
4032      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
4033    }    }
4034    
4035  if (found != NULL)  if (found != NULL)
# Line 3249  if (found != NULL) Line 4041  if (found != NULL)
4041    
4042  #endif  #endif
4043    
4044  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
4045  {  {
4046  DEFINE_COMPILER;  DEFINE_COMPILER;
4047  int length;  int length;
# Line 3268  switch(type) Line 4060  switch(type)
4060    case OP_SOD:    case OP_SOD:
4061    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4062    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));
4063    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));
4064    return cc;    return cc;
4065    
4066    case OP_SOM:    case OP_SOM:
4067    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4068    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));
4069    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));
4070    return cc;    return cc;
4071    
4072    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4073    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4074    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4075    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));
4076    return cc;    return cc;
4077    
4078    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4079    case OP_DIGIT:    case OP_DIGIT:
4080    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4081    read_char8_type(common);    if (common->digits[0] == -2)
4082    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4083    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4084      /* Flip the starting bit in the negative case. */
4085      if (type == OP_NOT_DIGIT)
4086        common->digits[1] ^= 1;
4087      if (!check_ranges(common, common->digits, backtracks, TRUE))
4088        {
4089        read_char8_type(common);
4090        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4091        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4092        }
4093      if (type == OP_NOT_DIGIT)
4094        common->digits[1] ^= 1;
4095    return cc;    return cc;
4096    
4097    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4098    case OP_WHITESPACE:    case OP_WHITESPACE:
4099    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4100    read_char8_type(common);    read_char8_type(common);
4101    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);
4102    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));
4103    return cc;    return cc;
4104    
4105    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4106    case OP_WORDCHAR:    case OP_WORDCHAR:
4107    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4108    read_char8_type(common);    read_char8_type(common);
4109    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);
4110    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));
4111    return cc;    return cc;
4112    
4113    case OP_ANY:    case OP_ANY:
4114    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4115    read_char(common);    read_char(common);
4116    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4117      {      {
# Line 3319  switch(type) Line 4122  switch(type)
4122        jump[1] = check_str_end(common);        jump[1] = check_str_end(common);
4123    
4124      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4125      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));
4126      if (jump[1] != NULL)      if (jump[1] != NULL)
4127        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4128      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4129      }      }
4130    else    else
4131      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4132    return cc;    return cc;
4133    
4134    case OP_ALLANY:    case OP_ALLANY:
4135    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4136  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4137    if (common->utf)    if (common->utf)
4138      {      {
# Line 3357  switch(type) Line 4160  switch(type)
4160    return cc;    return cc;
4161    
4162    case OP_ANYBYTE:    case OP_ANYBYTE:
4163    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4164    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));
4165    return cc;    return cc;
4166    
# Line 3370  switch(type) Line 4173  switch(type)
4173    propdata[2] = cc[0];    propdata[2] = cc[0];
4174    propdata[3] = cc[1];    propdata[3] = cc[1];
4175    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4176    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4177    return cc + 2;    return cc + 2;
4178  #endif  #endif
4179  #endif  #endif
4180    
4181    case OP_ANYNL:    case OP_ANYNL:
4182    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4183    read_char(common);    read_char(common);
4184    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);
4185    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
# Line 3389  switch(type) Line 4192  switch(type)
4192    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));
4193    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4194    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4195    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4196    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4197    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4198    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3397  switch(type) Line 4200  switch(type)
4200    
4201    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4202    case OP_HSPACE:    case OP_HSPACE:
4203    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4204    read_char(common);    read_char(common);
4205    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4206    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));
4207    return cc;    return cc;
4208    
4209    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4210    case OP_VSPACE:    case OP_VSPACE:
4211    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4212    read_char(common);    read_char(common);
4213    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4214    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));
4215    return cc;    return cc;
4216    
4217  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4218    case OP_EXTUNI:    case OP_EXTUNI:
4219    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4220    read_char(common);    read_char(common);
4221    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4222    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4223    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4224      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4225      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4226    
4227    label = LABEL();    label = LABEL();
4228    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);
4229    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4230    read_char(common);    read_char(common);
4231    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4232    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4233    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4234    
4235      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4236      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4237      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4238      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4239      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4240      JUMPTO(SLJIT_C_NOT_ZERO, label);
4241    
4242    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4243    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4244      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4245    
4246    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4247      {      {
4248      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 3447  switch(type) Line 4261  switch(type)
4261      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));
4262      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4263      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4264        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));
4265      else      else
4266        {        {
4267        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
# Line 3455  switch(type) Line 4269  switch(type)
4269        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4270        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4271        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
4272        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4273        check_partial(common, TRUE);        check_partial(common, TRUE);
4274        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4275        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4276        }        }
4277      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4278      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));
4279      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));
4280      }      }
4281    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4282      {      {
4283      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));
4284      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4285      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));
4286      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));
4287      }      }
4288    else    else
4289      {      {
# Line 3478  switch(type) Line 4292  switch(type)
4292      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));
4293      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);
4294      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4295      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4296      /* Equal. */      /* Equal. */
4297      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4298      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4299      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4300    
4301      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4302      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4303        {        {
4304        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));
4305        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));
4306        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));
4307        }        }
4308      else      else
4309        {        {
4310        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4311        read_char(common);        read_char(common);
4312        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));
4313        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4314        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4315        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4316        }        }
4317      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
# Line 3508  switch(type) Line 4322  switch(type)
4322    return cc;    return cc;
4323    
4324    case OP_EOD:    case OP_EOD:
4325    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));
4326    check_partial(common, FALSE);    check_partial(common, FALSE);
4327    return cc;    return cc;
4328    
4329    case OP_CIRC:    case OP_CIRC:
4330    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4331    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));
4332    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));
4333    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));
4334    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));
4335    return cc;    return cc;
4336    
4337    case OP_CIRCM:    case OP_CIRCM:
# Line 3525  switch(type) Line 4339  switch(type)
4339    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));
4340    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4341    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));
4342    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));
4343    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4344    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4345    
4346    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));
4347    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4348      {      {
4349      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));
4350      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4351      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4352      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4353      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));
4354      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));
4355      }      }
4356    else    else
4357      {      {
4358      skip_char_back(common);      skip_char_back(common);
4359      read_char(common);      read_char(common);
4360      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4361      }      }
4362    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4363    return cc;    return cc;
# Line 3551  switch(type) Line 4365  switch(type)
4365    case OP_DOLL:    case OP_DOLL:
4366    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4367    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));
4368    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));
4369    
4370    if (!common->endonly)    if (!common->endonly)
4371      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4372    else    else
4373      {      {
4374      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));
4375      check_partial(common, FALSE);      check_partial(common, FALSE);
4376      }      }
4377    return cc;    return cc;
# Line 3566  switch(type) Line 4380  switch(type)
4380    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4381    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4382    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));
4383    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));
4384    check_partial(common, FALSE);    check_partial(common, FALSE);
4385    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4386    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3576  switch(type) Line 4390  switch(type)
4390      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));
4391      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4392      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4393        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
4394      else      else
4395        {        {
4396        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4397        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
4398        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));
4399        check_partial(common, TRUE);        check_partial(common, TRUE);
4400        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4401        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4402        }        }
4403    
4404      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4405      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));
4406      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));
4407      }      }
4408    else    else
4409      {      {
4410      peek_char(common);      peek_char(common);
4411      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4412      }      }
4413    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4414    return cc;    return cc;
# Line 3608  switch(type) Line 4422  switch(type)
4422    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))
4423      {      {
4424      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));
4425      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));
4426    
4427      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4428      context.sourcereg = -1;      context.sourcereg = -1;
4429  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4430      context.ucharptr = 0;      context.ucharptr = 0;
4431  #endif  #endif
4432      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4433      }      }
4434    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4435    read_char(common);    read_char(common);
4436  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4437    if (common->utf)    if (common->utf)
# Line 3629  switch(type) Line 4443  switch(type)
4443      c = *cc;      c = *cc;
4444    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4445      {      {
4446      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));
4447      return cc + length;      return cc + length;
4448      }      }
4449    oc = char_othercase(common, c);    oc = char_othercase(common, c);
# Line 3637  switch(type) Line 4451  switch(type)
4451    if (ispowerof2(bit))    if (ispowerof2(bit))
4452      {      {
4453      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4454      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));
4455      return cc + length;      return cc + length;
4456      }      }
4457    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);
4458    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4459    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);
4460    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4461    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4462    return cc + length;    return cc + length;
4463    
4464    case OP_NOT:    case OP_NOT:
4465    case OP_NOTI:    case OP_NOTI:
4466    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4467    length = 1;    length = 1;
4468  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4469    if (common->utf)    if (common->utf)
# Line 3660  switch(type) Line 4474  switch(type)
4474        {        {
4475        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4476        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4477          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));
4478        else        else
4479          {          {
4480          /* 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. */
4481          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4482          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));
4483          }          }
4484        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4485        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 3690  switch(type) Line 4504  switch(type)
4504      }      }
4505    
4506    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4507      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));
4508    else    else
4509      {      {
4510      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3698  switch(type) Line 4512  switch(type)
4512      if (ispowerof2(bit))      if (ispowerof2(bit))
4513        {        {
4514        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4515        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));
4516        }        }
4517      else      else
4518        {        {
4519        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));
4520        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));
4521        }        }
4522      }      }
4523    return cc + length;    return cc + length;
4524    
4525    case OP_CLASS:    case OP_CLASS:
4526    case OP_NCLASS:    case OP_NCLASS:
4527    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4528    read_char(common);    read_char(common);
4529      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4530        return cc + 32 / sizeof(pcre_uchar);
4531    
4532  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4533    jump[0] = NULL;    jump[0] = NULL;
4534  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3723  switch(type) Line 4540  switch(type)
4540      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4541      if (type == OP_CLASS)      if (type == OP_CLASS)
4542        {        {
4543        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4544        jump[0] = NULL;        jump[0] = NULL;
4545        }        }
4546      }      }
# Line 3733  switch(type) Line 4550  switch(type)
4550    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4551    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4552    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);
4553    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4554  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4555    if (jump[0] != NULL)    if (jump[0] != NULL)
4556      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 3742  switch(type) Line 4559  switch(type)
4559    
4560  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
4561    case OP_XCLASS:    case OP_XCLASS:
4562    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4563    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4564  #endif  #endif
4565    
# Line 3757  switch(type) Line 4574  switch(type)
4574      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));
4575      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4576      label = LABEL();      label = LABEL();
4577      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));
4578      skip_char_back(common);      skip_char_back(common);
4579      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);
4580      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3767  switch(type) Line 4584  switch(type)
4584      {      {
4585      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));
4586      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));
4587      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));
4588      }      }
4589    check_start_used_ptr(common);    check_start_used_ptr(common);
4590    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3776  SLJIT_ASSERT_STOP(); Line 4593  SLJIT_ASSERT_STOP();
4593  return cc;  return cc;
4594  }  }
4595    
4596  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_matchingpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
4597  {  {
4598  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4599  /* 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 3828  if (context.length > 0) Line 4645  if (context.length > 0)
4645    {    {
4646    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4647    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);
4648    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));
4649    
4650    context.sourcereg = -1;    context.sourcereg = -1;
4651  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4652    context.ucharptr = 0;    context.ucharptr = 0;
4653  #endif  #endif
4654    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);
4655    return cc;    return cc;
4656    }    }
4657    
4658  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4659  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4660  }  }
4661    
4662  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)
4663  {  {
4664  DEFINE_COMPILER;  DEFINE_COMPILER;
4665  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3850  int offset = GET2(cc, 1) << 1; Line 4667  int offset = GET2(cc, 1) << 1;
4667  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4668  if (!common->jscript_compat)  if (!common->jscript_compat)
4669    {    {
4670    if (fallbacks == NULL)    if (backtracks == NULL)
4671      {      {
4672      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4673      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 3859  if (!common->jscript_compat) Line 4676  if (!common->jscript_compat)
4676      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4677      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4678      }      }
4679    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)));
4680    }    }
4681  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));
4682  }  }
4683    
4684  /* Forward definitions. */  /* Forward definitions. */
4685  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4686  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4687    
4688  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4689    do \    do \
4690      { \      { \
4691      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4692      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4693        return error; \        return error; \
4694      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4695      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4696      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4697      parent->top = fallback; \      parent->top = backtrack; \
4698      } \      } \
4699    while (0)    while (0)
4700    
4701  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4702    do \    do \
4703      { \      { \
4704      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4705      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4706        return; \        return; \
4707      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4708      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4709      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4710      parent->top = fallback; \      parent->top = backtrack; \
4711      } \      } \
4712    while (0)    while (0)
4713    
4714  #define FALLBACK_AS(type) ((type *)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4715    
4716  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
4717  {  {
4718  DEFINE_COMPILER;  DEFINE_COMPILER;
4719  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3907  struct sljit_jump *nopartial; Line 4724  struct sljit_jump *nopartial;
4724  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4725  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
4726  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4727    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)));
4728    
4729  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4730  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3924  if (common->utf && *cc == OP_REFI) Line 4741  if (common->utf && *cc == OP_REFI)
4741    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));
4742    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4743    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4744      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));
4745    else    else
4746      {      {
4747      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));
4748      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);
4749      check_partial(common, FALSE);      check_partial(common, FALSE);
4750      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4751      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4752      }      }
4753    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3945  else Line 4762  else
4762    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4763    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4764    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4765      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
4766    
4767    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));
4768    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));
4769    
4770    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
4771      {      {
# Line 3960  else Line 4777  else
4777      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4778      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4779      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));
4780      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));
4781      JUMPHERE(partial);      JUMPHERE(partial);
4782      check_partial(common, FALSE);      check_partial(common, FALSE);
4783      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4784      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4785      }      }
4786    }    }
# Line 3971  else Line 4788  else
4788  if (jump != NULL)  if (jump != NULL)
4789    {    {
4790    if (emptyfail)    if (emptyfail)
4791      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4792    else    else
4793      JUMPHERE(jump);      JUMPHERE(jump);
4794    }    }
4795  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4796  }  }
4797    
4798  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_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4799  {  {
4800  DEFINE_COMPILER;  DEFINE_COMPILER;
4801  fallback_common *fallback;  backtrack_common *backtrack;
4802  pcre_uchar type;  pcre_uchar type;
4803  struct sljit_label *label;  struct sljit_label *label;
4804  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3990  pcre_uchar *ccbegin = cc; Line 4807  pcre_uchar *ccbegin = cc;
4807  int min = 0, max = 0;  int min = 0, max = 0;
4808  BOOL minimize;  BOOL minimize;
4809    
4810  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4811    
4812  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4813  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 4042  if (!minimize) Line 4859  if (!minimize)
4859      {      {
4860      allocate_stack(common, 1);      allocate_stack(common, 1);
4861      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4862      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4863      }      }
4864    
4865    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4866      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4867    
4868    label = LABEL();    label = LABEL();
4869    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4870    
4871    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4872      {      {
# Line 4077  if (!minimize) Line 4894  if (!minimize)
4894      }      }
4895    
4896    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4897    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4898    
4899    decrease_call_count(common);    decrease_call_count(common);
4900    return cc;    return cc;
# Line 4095  if (min == 0) Line 4912  if (min == 0)
4912    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4913    }    }
4914  else  else
4915    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4916    
4917  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4918  if (max > 0)  if (max > 0)
4919    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));
4920    
4921  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4922  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4923    
4924  if (min > 1)  if (min > 1)
# Line 4109  if (min > 1) Line 4926  if (min > 1)
4926    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4927    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4928    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4929    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)->matchingpath);
4930    }    }
4931  else if (max > 0)  else if (max > 0)
4932    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 4122  decrease_call_count(common); Line 4939  decrease_call_count(common);
4939  return cc;  return cc;
4940  }  }
4941    
4942  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4943  {  {
4944  DEFINE_COMPILER;  DEFINE_COMPILER;
4945  fallback_common *fallback;  backtrack_common *backtrack;
4946  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4947  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4948  int start = GET(cc, 1);  int start = GET(cc, 1);
4949    
4950  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4951  while (entry != NULL)  while (entry != NULL)
4952    {    {
4953    if (entry->start == start)    if (entry->start == start)
# Line 4175  if (entry->entry == NULL) Line 4992  if (entry->entry == NULL)
4992  else  else
4993    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4994  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4995  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));
4996  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4997  }  }
4998    
4999  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5000  {  {
5001  DEFINE_COMPILER;  DEFINE_COMPILER;
5002  int framesize;  int framesize;
5003  int localptr;  int private_data_ptr;
5004  fallback_common altfallback;  backtrack_common altbacktrack;
5005  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5006  pcre_uchar opcode;  pcre_uchar opcode;
5007  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5008  jump_list *tmp = NULL;  jump_list *tmp = NULL;
5009  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5010  jump_list **found;  jump_list **found;
5011  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5012  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5013  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5014  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5015  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5016  struct sljit_jump *jump;  struct sljit_jump *jump;
5017  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5022  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5022    bra = *cc;    bra = *cc;
5023    cc++;    cc++;
5024    }    }
5025  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5026  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5027  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5028  fallback->framesize = framesize;  backtrack->framesize = framesize;
5029  fallback->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5030  opcode = *cc;  opcode = *cc;
5031  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5032  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4218  cc += GET(cc, 1); Line 5035  cc += GET(cc, 1);
5035    
5036  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5037    {    {
5038    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
5039    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5040    free_stack(common, 1);    free_stack(common, 1);
5041    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 4226  if (bra == OP_BRAMINZERO) Line 5043  if (bra == OP_BRAMINZERO)
5043    
5044  if (framesize < 0)  if (framesize < 0)
5045    {    {
5046    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5047    allocate_stack(common, 1);    allocate_stack(common, 1);
5048    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5049    }    }
5050  else  else
5051    {    {
5052    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5053    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5054    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));
5055    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5056    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5057    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5058    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5059    }    }
5060    
5061  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5062  common->leavelabel = NULL;  common->quitlabel = NULL;
5063  common->leave = NULL;  common->quit = NULL;
5064  while (1)  while (1)
5065    {    {
5066    common->acceptlabel = NULL;    common->acceptlabel = NULL;
5067    common->accept = NULL;    common->accept = NULL;
5068    altfallback.top = NULL;    altbacktrack.top = NULL;
5069    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5070    
5071    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5072      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5073    
5074    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5075    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5076    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5077      {      {
5078      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5079      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5080      common->leave = save_leave;      common->quit = save_quit;
5081      common->accept = save_accept;      common->accept = save_accept;
5082      return NULL;      return NULL;
5083      }      }
# Line 4270  while (1) Line 5087  while (1)
5087    
5088    /* Reset stack. */    /* Reset stack. */
5089    if (framesize < 0)    if (framesize < 0)
5090      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5091    else {    else {
5092      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5093        {        {
5094        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5095        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5096        }        }
5097      else      else
5098        {        {
5099        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5100        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5101        }        }
5102    }    }
# Line 4297  while (1) Line 5114  while (1)
5114          {          {
5115          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5116          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
5117          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5118          }          }
5119        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5120        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
# Line 4305  while (1) Line 5122  while (1)
5122      else if (framesize >= 0)      else if (framesize >= 0)
5123        {        {
5124        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5125        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), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5126        }        }
5127      }      }
5128    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5129    
5130    compile_fallbackpath(common, altfallback.top);    compile_backtrackingpath(common, altbacktrack.top);
5131    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5132      {      {
5133      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5134      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5135      common->leave = save_leave;      common->quit = save_quit;
5136      common->accept = save_accept;      common->accept = save_accept;
5137      return NULL;      return NULL;
5138      }      }
5139    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5140    
5141    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5142      break;      break;
# Line 4328  while (1) Line 5145  while (1)
5145    cc += GET(cc, 1);    cc += GET(cc, 1);
5146    }    }
5147  /* None of them matched. */  /* None of them matched. */
5148  if (common->leave != NULL)  if (common->quit != NULL)
5149    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5150    
5151  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5152    {    {
# Line 4356  if (opcode == OP_ASSERT || opcode == OP_ Line 5173  if (opcode == OP_ASSERT || opcode == OP_
5173        }        }
5174      else      else
5175        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5176      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5177      }      }
5178    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5179    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4381  if (opcode == OP_ASSERT || opcode == OP_ Line 5198  if (opcode == OP_ASSERT || opcode == OP_
5198      {      {
5199      if (bra == OP_BRA)      if (bra == OP_BRA)
5200        {        {
5201        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5202        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
5203        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5204        }        }
5205      else      else
5206        {        {
5207        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5208        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
5209        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5210        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5211        }        }
# Line 4396  if (opcode == OP_ASSERT || opcode == OP_ Line 5213  if (opcode == OP_ASSERT || opcode == OP_
5213    
5214    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5215      {      {
5216      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5217      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->matchingpath);
5218      }      }
5219    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5220      {      {
5221      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5222      JUMPHERE(brajump);      JUMPHERE(brajump);
5223      if (framesize >= 0)      if (framesize >= 0)
5224        {        {
5225        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5226        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5227        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), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
5228        }        }
5229      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5230      }      }
5231    }    }
5232  else  else
# Line 4435  else Line 5252  else
5252        }        }
5253      else      else
5254        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5255      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5256      }      }
5257    
5258    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5259      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5260    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5261      {      {
5262      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5263      JUMPHERE(brajump);      JUMPHERE(brajump);
5264      }      }
5265    
5266    if (bra != OP_BRA)    if (bra != OP_BRA)
5267      {      {
5268      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5269      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5270      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5271      }      }
5272    }    }
5273    
5274  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5275  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5276  common->leave = save_leave;  common->quit = save_quit;
5277  common->accept = save_accept;  common->accept = save_accept;
5278  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5279  }  }
# Line 4625  return condition; Line 5442  return condition;
5442                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
5443  */  */
5444    
5445  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5446  {  {
5447  DEFINE_COMPILER;  DEFINE_COMPILER;
5448  fallback_common *fallback;  backtrack_common *backtrack;
5449  pcre_uchar opcode;  pcre_uchar opcode;
5450  int localptr = 0;  int private_data_ptr = 0;
5451  int offset = 0;  int offset = 0;
5452  int stacksize;  int stacksize;
5453  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5454  pcre_uchar *hotpath;  pcre_uchar *matchingpath;
5455  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5456  pcre_uchar ket;  pcre_uchar ket;
5457  assert_fallback *assert;  assert_backtrack *assert;
5458  BOOL has_alternatives;  BOOL has_alternatives;
5459  struct sljit_jump *jump;  struct sljit_jump *jump;
5460  struct sljit_jump *skip;  struct sljit_jump *skip;
5461  struct sljit_label *rmaxlabel = NULL;  struct sljit_label *rmaxlabel = NULL;
5462  struct sljit_jump *braminzerojump = NULL;  struct sljit_jump *braminzerojump = NULL;
5463    
5464  PUSH_FALLBACK(sizeof(bracket_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracket_backtrack), cc, NULL);
5465    
5466  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5467    {    {
# Line 4655  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5472  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5472    
5473  opcode = *cc;  opcode = *cc;
5474  ccbegin = cc;  ccbegin = cc;
5475  hotpath = ccbegin + 1 + LINK_SIZE;  matchingpath = ccbegin + 1 + LINK_SIZE;
5476    
5477  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)
5478    {    {
5479    /* Drop this bracket_fallback. */    /* Drop this bracket_backtrack. */
5480    parent->top = fallback->prev;    parent->top = backtrack->prev;
5481    return bracketend(cc);    return bracketend(cc);
5482    }    }
5483    
# Line 4672  cc += GET(cc, 1); Line 5489  cc += GET(cc, 1);
5489  has_alternatives = *cc == OP_ALT;  has_alternatives = *cc == OP_ALT;
5490  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5491    {    {
5492    has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;    has_alternatives = (*matchingpath == OP_RREF) ? FALSE : TRUE;
5493    if (*hotpath == OP_NRREF)    if (*matchingpath == OP_NRREF)
5494      {      {
5495      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5496      if (common->currententry == NULL || stacksize == RREF_ANY)      if (common->currententry == NULL || stacksize == RREF_ANY)
5497        has_alternatives = FALSE;        has_alternatives = FALSE;
5498      else if (common->currententry->start == 0)      else if (common->currententry->start == 0)
# Line 4694  if (opcode == OP_CBRA || opcode == OP_SC Line 5511  if (opcode == OP_CBRA || opcode == OP_SC
5511    {    {
5512    /* Capturing brackets has a pre-allocated space. */    /* Capturing brackets has a pre-allocated space. */
5513    offset = GET2(ccbegin, 1 + LINK_SIZE);    offset = GET2(ccbegin, 1 + LINK_SIZE);
5514    localptr = OVECTOR_PRIV(offset);    if (common->optimized_cbracket[offset] == 0)
5515    offset <<= 1;      {
5516    FALLBACK_AS(bracket_fallback)->localptr = localptr;      private_data_ptr = OVECTOR_PRIV(offset);
5517    hotpath += IMM2_SIZE;      offset <<= 1;
5518        }
5519      else
5520        {
5521        offset <<= 1;
5522        private_data_ptr = OVECTOR(offset);
5523        }
5524      BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5525      matchingpath += IMM2_SIZE;
5526    }    }
5527  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
5528    {    {
5529    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
5530    localptr = PRIV_DATA(ccbegin);    private_data_ptr = PRIVATE_DATA(ccbegin);
5531    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(private_data_ptr != 0);
5532    FALLBACK_AS(bracket_fallback)->localptr = localptr;    BACKTRACK_AS(bracket_backtrack)->private_data_ptr = private_data_ptr;
5533    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
5534      FALLBACK_AS(bracket_fallback)->u.framesize = get_framesize(common, ccbegin, FALSE);      BACKTRACK_AS(bracket_backtrack)->u.framesize = get_framesize(common, ccbegin, FALSE);
5535    }    }
5536    
5537  /* Instructions before the first alternative. */  /* Instructions before the first alternative. */
# Line 4731  if (bra == OP_BRAZERO) Line 5556  if (bra == OP_BRAZERO)
5556    
5557  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5558    {    {
5559    /* 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) */
5560    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5561    if (ket != OP_KETRMIN)    if (ket != OP_KETRMIN)
5562      {      {
# Line 4748  if (bra == OP_BRAMINZERO) Line 5573  if (bra == OP_BRAMINZERO)
5573        skip = JUMP(SLJIT_JUMP);        skip = JUMP(SLJIT_JUMP);
5574        JUMPHERE(jump);        JUMPHERE(jump);
5575        /* Checking zero-length iteration. */        /* Checking zero-length iteration. */
5576        if (opcode != OP_ONCE || FALLBACK_AS(bracket_fallback)->u.framesize < 0)        if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5577          {          {
5578          /* When we come from outside, localptr contains the previous STR_PTR. */          /* When we come from outside, private_data_ptr contains the previous STR_PTR. */
5579          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), private_data_ptr);
5580          }          }
5581        else        else
5582          {          {
5583          /* Except when the whole stack frame must be saved. */          /* Except when the whole stack frame must be saved. */
5584          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5585          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));
5586          }          }
5587        JUMPHERE(skip);        JUMPHERE(skip);
5588        }        }
# Line 4771  if (bra == OP_BRAMINZERO) Line 5596  if (bra == OP_BRAMINZERO)
5596    }    }
5597    
5598  if (ket == OP_KETRMIN)  if (ket == OP_KETRMIN)
5599    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5600    
5601  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5602    {    {
5603    rmaxlabel = LABEL();    rmaxlabel = LABEL();
5604    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)    if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA)
5605      FALLBACK_AS(bracket_fallback)->althotpath = rmaxlabel;      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmaxlabel;
5606    }    }
5607    
5608  /* Handling capturing brackets and alternatives. */  /* Handling capturing brackets and alternatives. */
5609  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5610    {    {
5611    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5612      {      {
5613      /* Neither capturing brackets nor recursions are not found in the block. */      /* Neither capturing brackets nor recursions are not found in the block. */
5614      if (ket == OP_KETRMIN)      if (ket == OP_KETRMIN)
5615        {        {
5616        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5617        allocate_stack(common, 2);        allocate_stack(common, 2);
5618        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5619        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5620        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
5621        }        }
5622      else if (ket == OP_KETRMAX || has_alternatives)      else if (ket == OP_KETRMAX || has_alternatives)
5623        {        {
5624        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5625        allocate_stack(common, 1);        allocate_stack(common, 1);
5626        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5627        }        }
5628      else      else
5629        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5630      }      }
5631    else    else
5632      {      {
5633      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)      if (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives)
5634        {        {
5635        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 2);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 2);
5636        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5637        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));
5638        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5640        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5641        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);
5642        }        }
5643      else      else
5644        {        {
5645        allocate_stack(common, FALLBACK_AS(bracket_fallback)->u.framesize + 1);        allocate_stack(common, BACKTRACK_AS(bracket_backtrack)->u.framesize + 1);
5646        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5647        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));
5648        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5649        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5650        init_frame(common, ccbegin, FALLBACK_AS(bracket_fallback)->u.framesize, 1, FALSE);        init_frame(common, ccbegin, BACKTRACK_AS(bracket_backtrack)->u.framesize, 1, FALSE);
5651        }        }
5652      }      }
5653    }    }
5654  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
5655    {    {
5656    /* Saving the previous values. */    /* Saving the previous values. */
5657    allocate_stack(common, 3);    if (common->optimized_cbracket[offset >> 1] == 0)
5658    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      {
5659    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      allocate_stack(common, 3);
5660    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
5661    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5662    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5663    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5664    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5665        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5666        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5667        }
5668      else
5669        {
5670        SLJIT_ASSERT(private_data_ptr == OVECTOR(offset));
5671        allocate_stack(common, 2);
5672        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5673        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr + sizeof(sljit_w));
5674        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5675        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
5676        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5677        }
5678    }    }
5679  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5680    {    {
5681    /* Saving the previous value. */    /* Saving the previous value. */
5682    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5683    allocate_stack(common, 1);    allocate_stack(common, 1);
5684    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0);
5685    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5686    }    }
5687  else if (has_alternatives)  else if (has_alternatives)
# Line 4856  else if (has_alternatives) Line 5694  else if (has_alternatives)
5694  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
5695  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
5696    {    {
5697    if (*hotpath == OP_CREF)    if (*matchingpath == OP_CREF)
5698      {      {
5699      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5700      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(BACKTRACK_AS(bracket_backtrack)->u.condfailed),
5701        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(matchingpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
5702      hotpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5703      }      }
5704    else if (*hotpath == OP_NCREF)    else if (*matchingpath == OP_NCREF)
5705      {      {
5706      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
5707      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5708      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));
5709    
5710      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
# Line 4877  if (opcode == OP_COND || opcode == OP_SC Line 5715  if (opcode == OP_COND || opcode == OP_SC
5715      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5716      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));
5717      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5718      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));
5719    
5720      JUMPHERE(jump);      JUMPHERE(jump);
5721      hotpath += 1 + IMM2_SIZE;      matchingpath += 1 + IMM2_SIZE;
5722      }      }
5723    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*matchingpath == OP_RREF || *matchingpath == OP_NRREF)
5724      {      {
5725      /* Never has other case. */      /* Never has other case. */
5726      FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;      BACKTRACK_AS(bracket_backtrack)->u.condfailed = NULL;
5727    
5728      stacksize = GET2(hotpath, 1);      stacksize = GET2(matchingpath, 1);
5729      if (common->currententry == NULL)      if (common->currententry == NULL)
5730        stacksize = 0;        stacksize = 0;
5731      else if (stacksize == RREF_ANY)      else if (stacksize == RREF_ANY)
# Line 4897  if (opcode == OP_COND || opcode == OP_SC Line 5735  if (opcode == OP_COND || opcode == OP_SC
5735      else      else
5736        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);        stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
5737    
5738      if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)      if (*matchingpath == OP_RREF || stacksize || common->currententry == NULL)
5739        {        {
5740        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
5741        if (stacksize != 0)        if (stacksize != 0)
5742          hotpath += 1 + IMM2_SIZE;          matchingpath += 1 + IMM2_SIZE;
5743        else        else
5744          {          {
5745          if (*cc == OP_ALT)          if (*cc == OP_ALT)
5746            {            {
5747            hotpath = cc + 1 + LINK_SIZE;            matchingpath = cc + 1 + LINK_SIZE;
5748            cc += GET(cc, 1);            cc += GET(cc, 1);
5749            }            }
5750          else          else
5751            hotpath = cc;            matchingpath = cc;
5752          }          }
5753        }        }
5754      else      else
5755        {        {
5756        SLJIT_ASSERT(has_alternatives);        SLJIT_ASSERT(has_alternatives);
5757    
5758        stacksize = GET2(hotpath, 1);        stacksize = GET2(matchingpath, 1);
5759        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
5760        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);
5761        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);
# Line 4927  if (opcode == OP_COND || opcode == OP_SC Line 5765  if (opcode == OP_COND || opcode == OP_SC
5765        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
5766        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));
5767        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
5768        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));
5769        hotpath += 1 + IMM2_SIZE;        matchingpath += 1 + IMM2_SIZE;
5770        }        }
5771      }      }
5772    else    else
5773      {      {
5774      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *matchingpath >= OP_ASSERT && *matchingpath <= OP_ASSERTBACK_NOT);
5775      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_BACKTRACK macro. */
5776      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_backtrack));
5777      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5778        return NULL;        return NULL;
5779      memset(assert, 0, sizeof(assert_fallback));      memset(assert, 0, sizeof(assert_backtrack));
5780      assert->common.cc = hotpath;      assert->common.cc = matchingpath;
5781      FALLBACK_AS(bracket_fallback)->u.assert = assert;      BACKTRACK_AS(bracket_backtrack)->u.assert = assert;
5782      hotpath = compile_assert_hotpath(common, hotpath, assert, TRUE);      matchingpath = compile_assert_matchingpath(common, matchingpath, assert, TRUE);
5783      }      }
5784    }    }
5785    
5786  compile_hotpath(common, hotpath, cc, fallback);  compile_matchingpath(common, matchingpath, cc, backtrack);
5787  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5788    return NULL;    return NULL;
5789    
5790  if (opcode == OP_ONCE)  if (opcode == OP_ONCE)
5791    {    {
5792    if (FALLBACK_AS(bracket_fallback)->u.framesize < 0)    if (BACKTRACK_AS(bracket_backtrack)->u.framesize < 0)
5793      {      {
5794      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5795      /* TMP2 which is set here used by OP_KETRMAX below. */      /* TMP2 which is set here used by OP_KETRMAX below. */
5796      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5797        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5798      else if (ket == OP_KETRMIN)      else if (ket == OP_KETRMIN)
5799        {        {
5800        /* Move the STR_PTR to the localptr. */        /* Move the STR_PTR to the private_data_ptr. */
5801        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), 0);
5802        }        }
5803      }      }
5804    else    else
5805      {      {
5806      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
5807      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), private_data_ptr, SLJIT_IMM, (BACKTRACK_AS(bracket_backtrack)->u.framesize + stacksize) * sizeof(sljit_w));
5808      if (ket == OP_KETRMAX)      if (ket == OP_KETRMAX)
5809        {        {
5810        /* TMP2 which is set here used by OP_KETRMAX below. */        /* TMP2 which is set here used by OP_KETRMAX below. */
# Line 5001  if (has_alternatives) Line 5839  if (has_alternatives)
5839    if (opcode != OP_ONCE)    if (opcode != OP_ONCE)
5840      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize), SLJIT_IMM, 0);
5841    if (ket != OP_KETRMAX)    if (ket != OP_KETRMAX)
5842      FALLBACK_AS(bracket_fallback)->althotpath = LABEL();      BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5843    }    }
5844    
5845  /* Must be after the hotpath label. */  /* Must be after the matchingpath label. */
5846  if (offset != 0)  if (offset != 0)
5847    {    {
5848    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5849    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5850    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 0), TMP1, 0);
5851    }    }
# Line 5017  if (ket == OP_KETRMAX) Line 5855  if (ket == OP_KETRMAX)
5855    if (opcode == OP_ONCE || opcode >= OP_SBRA)    if (opcode == OP_ONCE || opcode >= OP_SBRA)
5856      {      {
5857      if (has_alternatives)      if (has_alternatives)
5858        FALLBACK_AS(bracket_fallback)->althotpath = LABEL();        BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL();
5859      /* Checking zero-length iteration. */      /* Checking zero-length iteration. */
5860      if (opcode != OP_ONCE)      if (opcode != OP_ONCE)
5861        CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0, rmaxlabel);        {
5862          CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STR_PTR, 0, rmaxlabel);
5863          /* Drop STR_PTR for greedy plus quantifier. */
5864          if (bra != OP_BRAZERO)
5865            free_stack(common, 1);
5866          }
5867      else      else
5868        /* TMP2 must contain the starting STR_PTR. */        /* TMP2 must contain the starting STR_PTR. */
5869        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_PTR, 0, rmaxlabel);
5870      }      }
5871    else    else
5872      JUMPTO(SLJIT_JUMP, rmaxlabel);      JUMPTO(SLJIT_JUMP, rmaxlabel);
5873    FALLBACK_AS(bracket_fallback)->recursivehotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->recursive_matchingpath = LABEL();
5874    }    }
5875    
5876  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5877    FALLBACK_AS(bracket_fallback)->zerohotpath = LABEL();    BACKTRACK_AS(bracket_backtrack)->zero_matchingpath = LABEL();
5878    
5879  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5880    {    {
5881    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a backtrack path! (From the viewpoint of OP_BRAMINZERO) */
5882    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_backtrack *)parent)->matchingpath);
5883    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5884      {      {
5885      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
5886      /* We need to release the end pointer to perform the      /* We need to release the end pointer to perform the
5887      fallback for the zero-length iteration. When      backtrack for the zero-length iteration. When
5888      framesize is < 0, OP_ONCE will do the release itself. */      framesize is < 0, OP_ONCE will do the release itself. */
5889      if (opcode == OP_ONCE && FALLBACK_AS(bracket_fallback)->u.framesize >= 0)      if (opcode == OP_ONCE && BACKTRACK_AS(bracket_backtrack)->u.framesize >= 0)
5890        {        {
5891        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5892        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5893        }        }
5894      else if (ket == OP_KETRMIN && opcode != OP_ONCE)      else if (ket == OP_KETRMIN && opcode != OP_ONCE)
5895        free_stack(common, 1);        free_stack(common, 1);
5896      }      }
5897    /* Continue to the normal fallback. */    /* Continue to the normal backtrack. */
5898    }    }
5899    
5900  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)  if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
# Line 5064  cc += 1 + LINK_SIZE; Line 5907  cc += 1 + LINK_SIZE;
5907  return cc;  return cc;
5908  }  }
5909    
5910  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5911  {  {
5912  DEFINE_COMPILER;  DEFINE_COMPILER;
5913  fallback_common *fallback;  backtrack_common *backtrack;
5914  pcre_uchar opcode;  pcre_uchar opcode;
5915  int localptr;  int private_data_ptr;
5916  int cbraprivptr = 0;  int cbraprivptr = 0;
5917  int framesize;  int framesize;
5918  int stacksize;  int stacksize;
# Line 5080  int stack; Line 5923  int stack;
5923  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5924  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
5925    
5926  PUSH_FALLBACK(sizeof(bracketpos_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(bracketpos_backtrack), cc, NULL);
5927  if (*cc == OP_BRAPOSZERO)  if (*cc == OP_BRAPOSZERO)
5928    {    {
5929    zero = TRUE;    zero = TRUE;
# Line 5088  if (*cc == OP_BRAPOSZERO) Line 5931  if (*cc == OP_BRAPOSZERO)
5931    }    }
5932    
5933  opcode = *cc;  opcode = *cc;
5934  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5935  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5936  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  BACKTRACK_AS(bracketpos_backtrack)->private_data_ptr = private_data_ptr;
5937  switch(opcode)  switch(opcode)
5938    {    {
5939    case OP_BRAPOS:    case OP_BRAPOS:
# Line 5101  switch(opcode) Line 5944  switch(opcode)
5944    case OP_CBRAPOS:    case OP_CBRAPOS:
5945    case OP_SCBRAPOS:    case OP_SCBRAPOS:
5946    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5947      /* This case cannot be optimized in the same was as
5948      normal capturing brackets. */
5949      SLJIT_ASSERT(common->optimized_cbracket[offset] == 0);
5950    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5951    offset <<= 1;    offset <<= 1;
5952    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
# Line 5112  switch(opcode) Line 5958  switch(opcode)
5958    }    }
5959    
5960  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5961  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  BACKTRACK_AS(bracketpos_backtrack)->framesize = framesize;
5962  if (framesize < 0)  if (framesize < 0)
5963    {    {
5964    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
5965    if (!zero)    if (!zero)
5966      stacksize++;      stacksize++;
5967    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5968    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5969    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5970    
5971    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)    if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5972      {      {
# Line 5142  else Line 5988  else
5988      stacksize++;      stacksize++;
5989    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)    if (opcode == OP_BRAPOS || opcode == OP_SBRAPOS)
5990      stacksize++;      stacksize++;
5991    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    BACKTRACK_AS(bracketpos_backtrack)->stacksize = stacksize;
5992    allocate_stack(common, stacksize);    allocate_stack(common, stacksize);
5993    
5994    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5995    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(stacksize - 1));
5996    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5997    stack = 0;    stack = 0;
5998    if (!zero)    if (!zero)
5999      {      {
# Line 5169  if (opcode == OP_CBRAPOS || opcode == OP Line 6015  if (opcode == OP_CBRAPOS || opcode == OP
6015  loop = LABEL();  loop = LABEL();
6016  while (*cc != OP_KETRPOS)  while (*cc != OP_KETRPOS)
6017    {    {
6018    fallback->top = NULL;    backtrack->top = NULL;
6019    fallback->topfallbacks = NULL;    backtrack->topbacktracks = NULL;
6020    cc += GET(cc, 1);    cc += GET(cc, 1);
6021    
6022    compile_hotpath(common, ccbegin, cc, fallback);    compile_matchingpath(common, ccbegin, cc, backtrack);
6023    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6024      return NULL;      return NULL;
6025    
6026    if (framesize < 0)    if (framesize < 0)
6027      {      {
6028      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6029    
6030      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6031        {        {
# Line 5205  while (*cc != OP_KETRPOS) Line 6051  while (*cc != OP_KETRPOS)
6051      {      {
6052      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
6053        {        {
6054        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
6055        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6056        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
6057        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
# Line 5213  while (*cc != OP_KETRPOS) Line 6059  while (*cc != OP_KETRPOS)
6059        }        }
6060      else      else
6061        {        {
6062        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6063        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
6064        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
6065          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
# Line 5234  while (*cc != OP_KETRPOS) Line 6080  while (*cc != OP_KETRPOS)
6080    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
6081    flush_stubs(common);    flush_stubs(common);
6082    
6083    compile_fallbackpath(common, fallback->top);    compile_backtrackingpath(common, backtrack->top);
6084    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
6085      return NULL;      return NULL;
6086    set_jumps(fallback->topfallbacks, LABEL());    set_jumps(backtrack->topbacktracks, LABEL());
6087    
6088    if (framesize < 0)    if (framesize < 0)
6089      {      {
# Line 5252  while (*cc != OP_KETRPOS) Line 6098  while (*cc != OP_KETRPOS)
6098        {        {
6099        /* Last alternative. */        /* Last alternative. */
6100        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
6101          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6102        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
6103        }        }
6104      else      else
6105        {        {
6106        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
6107        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
6108        }        }
6109      }      }
# Line 5267  while (*cc != OP_KETRPOS) Line 6113  while (*cc != OP_KETRPOS)
6113    ccbegin = cc + 1 + LINK_SIZE;    ccbegin = cc + 1 + LINK_SIZE;
6114    }    }
6115    
6116  fallback->topfallbacks = NULL;  backtrack->topbacktracks = NULL;
6117  if (!zero)  if (!zero)
6118    {    {
6119    if (framesize < 0)    if (framesize < 0)
6120      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));
6121    else /* TMP2 is set to [localptr] above. */    else /* TMP2 is set to [private_data_ptr] above. */
6122      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));
6123    }    }
6124    
6125  /* None of them matched. */  /* None of them matched. */
# Line 5374  if (end != NULL) Line 6220  if (end != NULL)
6220  return cc;  return cc;
6221  }  }
6222    
6223  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
6224  {  {
6225  DEFINE_COMPILER;  DEFINE_COMPILER;
6226  fallback_common *fallback;  backtrack_common *backtrack;
6227  pcre_uchar opcode;  pcre_uchar opcode;
6228  pcre_uchar type;  pcre_uchar type;
6229  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
# Line 5385  pcre_uchar* end; Line 6231  pcre_uchar* end;
6231  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
6232  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
6233  struct sljit_label *label;  struct sljit_label *label;
6234    int private_data_ptr = PRIVATE_DATA(cc);
6235    int base = (private_data_ptr == 0) ? SLJIT_MEM1(STACK_TOP) : SLJIT_MEM1(SLJIT_LOCALS_REG);
6236    int offset0 = (private_data_ptr == 0) ? STACK(0) : private_data_ptr;
6237    int offset1 = (private_data_ptr == 0) ? STACK(1) : private_data_ptr + (int)sizeof(sljit_w);
6238    int tmp_base, tmp_offset;
6239    
6240  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
6241    
6242  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);  cc = get_iterator_parameters(common, cc, &opcode, &type, &arg1, &arg2, &end);
6243    
6244    switch (type)
6245      {
6246      case OP_NOT_DIGIT:
6247      case OP_DIGIT:
6248      case OP_NOT_WHITESPACE:
6249      case OP_WHITESPACE:
6250      case OP_NOT_WORDCHAR:
6251      case OP_WORDCHAR:
6252      case OP_ANY:
6253      case OP_ALLANY:
6254      case OP_ANYBYTE:
6255      case OP_ANYNL:
6256      case OP_NOT_HSPACE:
6257      case OP_HSPACE:
6258      case OP_NOT_VSPACE:
6259      case OP_VSPACE:
6260      case OP_CHAR:
6261      case OP_CHARI:
6262      case OP_NOT:
6263      case OP_NOTI:
6264      case OP_CLASS:
6265      case OP_NCLASS:
6266      tmp_base = TMP3;
6267      tmp_offset = 0;
6268      break;
6269    
6270      default:
6271      SLJIT_ASSERT_STOP();
6272      /* Fall through. */
6273    
6274      case OP_EXTUNI:
6275      case OP_XCLASS:
6276      case OP_NOTPROP:
6277      case OP_PROP:
6278      tmp_base = SLJIT_MEM1(SLJIT_LOCALS_REG);
6279      tmp_offset = POSSESSIVE0;
6280      break;
6281      }
6282    
6283  switch(opcode)  switch(opcode)
6284    {    {
6285    case OP_STAR:    case OP_STAR:
# Line 5398  switch(opcode) Line 6288  switch(opcode)
6288    case OP_CRRANGE:    case OP_CRRANGE:
6289    if (type == OP_ANYNL || type == OP_EXTUNI)    if (type == OP_ANYNL || type == OP_EXTUNI)
6290      {      {
6291        SLJIT_ASSERT(private_data_ptr == 0);
6292      if (opcode == OP_STAR || opcode == OP_UPTO)      if (opcode == OP_STAR || opcode == OP_UPTO)
6293        {        {
6294        allocate_stack(common, 2);        allocate_stack(common, 2);
# Line 5409  switch(opcode) Line 6300  switch(opcode)
6300        allocate_stack(common, 1);        allocate_stack(common, 1);
6301        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
6302        }        }
6303    
6304      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6305        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
6306    
6307      label = LABEL();      label = LABEL();
6308      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6309      if (opcode == OP_UPTO || opcode == OP_CRRANGE)      if (opcode == OP_UPTO || opcode == OP_CRRANGE)
6310        {        {
6311        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
# Line 5425  switch(opcode) Line 6317  switch(opcode)
6317        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);
6318        }        }
6319    
6320        /* We cannot use TMP3 because of this allocate_stack. */
6321      allocate_stack(common, 1);      allocate_stack(common, 1);
6322      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
6323      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
# Line 5433  switch(opcode) Line 6326  switch(opcode)
6326      }      }
6327    else    else
6328      {      {
6329      allocate_stack(common, 2);      if (opcode == OP_PLUS)
6330      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6331      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);      if (private_data_ptr == 0)
6332          allocate_stack(common, 2);
6333        OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6334        if (opcode <= OP_PLUS)
6335          OP1(SLJIT_MOV, base, offset1, STR_PTR, 0);
6336        else
6337          OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6338      label = LABEL();      label = LABEL();
6339      compile_char1_hotpath(common, type, cc, &nomatch);      compile_char1_matchingpath(common, type, cc, &nomatch);
6340      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6341      if (opcode <= OP_PLUS || (opcode == OP_CRRANGE && arg1 == 0))      if (opcode <= OP_PLUS)
6342          JUMPTO(SLJIT_JUMP, label);
6343        else if (opcode == OP_CRRANGE && arg1 == 0)
6344        {        {
6345        OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);        OP2(SLJIT_ADD, base, offset1, base, offset1, SLJIT_IMM, 1);
6346        JUMPTO(SLJIT_JUMP, label);        JUMPTO(SLJIT_JUMP, label);
6347        }        }
6348      else      else
6349        {        {
6350        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));        OP1(SLJIT_MOV, TMP1, 0, base, offset1);
6351        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
6352        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);        OP1(SLJIT_MOV, base, offset1, TMP1, 0);
6353        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);        CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);
6354        }        }
6355      set_jumps(nomatch, LABEL());      set_jumps(nomatch, LABEL());
6356      if (opcode == OP_PLUS || opcode == OP_CRRANGE)      if (opcode == OP_CRRANGE)
6357        add_jump(compiler, &fallback->topfallbacks,        add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_LESS, base, offset1, SLJIT_IMM, arg2 + 1));
6358          CMP(SLJIT_C_LESS, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, opcode == OP_PLUS ? 2 : arg2 + 1));      OP1(SLJIT_MOV, STR_PTR, 0, base, offset0);
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6359      }      }
6360    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6361    break;    break;
6362    
6363    case OP_MINSTAR:    case OP_MINSTAR:
6364    case OP_MINPLUS:    case OP_MINPLUS:
   allocate_stack(common, 1);  
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  
6365    if (opcode == OP_MINPLUS)    if (opcode == OP_MINPLUS)
6366      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6367    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    if (private_data_ptr == 0)
6368        allocate_stack(common, 1);
6369      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6370      BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6371    break;    break;
6372    
6373    case OP_MINUPTO:    case OP_MINUPTO:
6374    case OP_CRMINRANGE:    case OP_CRMINRANGE:
6375    allocate_stack(common, 2);    if (private_data_ptr == 0)
6376    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 2);
6377    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6378      OP1(SLJIT_MOV, base, offset1, SLJIT_IMM, 1);
6379    if (opcode == OP_CRMINRANGE)    if (opcode == OP_CRMINRANGE)
6380      add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_JUMP));
6381    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6382    break;    break;
6383    
6384    case OP_QUERY:    case OP_QUERY:
6385    case OP_MINQUERY:    case OP_MINQUERY:
6386    allocate_stack(common, 1);    if (private_data_ptr == 0)
6387    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      allocate_stack(common, 1);
6388      OP1(SLJIT_MOV, base, offset0, STR_PTR, 0);
6389    if (opcode == OP_QUERY)    if (opcode == OP_QUERY)
6390      compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6391    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
6392    break;    break;
6393    
6394    case OP_EXACT:    case OP_EXACT:
6395    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, tmp_base, tmp_offset, SLJIT_IMM, arg1);
6396    label = LABEL();    label = LABEL();
6397    compile_char1_hotpath(common, type, cc, &fallback->topfallbacks);    compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6398    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP2(SLJIT_SUB | SLJIT_SET_E, tmp_base, tmp_offset, tmp_base, tmp_offset, SLJIT_IMM, 1);
6399    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    JUMPTO(SLJIT_C_NOT_ZERO, label);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6400    break;    break;
6401    
6402    case OP_POSSTAR:    case OP_POSSTAR:
6403    case OP_POSPLUS:    case OP_POSPLUS:
6404    case OP_POSUPTO:    case OP_POSUPTO:
6405    if (opcode != OP_POSSTAR)    if (opcode == OP_POSPLUS)
6406      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 1);      compile_char1_matchingpath(common, type, cc, &backtrack->topbacktracks);
6407    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    if (opcode == OP_POSUPTO)
6408        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, arg1);
6409      OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6410    label = LABEL();    label = LABEL();
6411    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6412    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6413    if (opcode != OP_POSUPTO)    if (opcode != OP_POSUPTO)
     {  
     if (opcode == OP_POSPLUS)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2);  
6414      JUMPTO(SLJIT_JUMP, label);      JUMPTO(SLJIT_JUMP, label);
     }  
6415    else    else
6416      {      {
6417      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, SLJIT_IMM, 1);
6418      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, TMP1, 0);  
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, arg1 + 1, label);  
6419      }      }
6420    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());
6421    if (opcode == OP_POSPLUS)    OP1(SLJIT_MOV, STR_PTR, 0, tmp_base, tmp_offset);
     add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_LESS, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 2));  
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);  
6422    break;    break;
6423    
6424    case OP_POSQUERY:    case OP_POSQUERY:
6425    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6426    compile_char1_hotpath(common, type, cc, &nomatch);    compile_char1_matchingpath(common, type, cc, &nomatch);
6427    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STR_PTR, 0);    OP1(SLJIT_MOV, tmp_base, tmp_offset, STR_PTR, 0);
6428    set_jumps(nomatch, LABEL());    set_jumps(nomatch, LABEL());