/[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 941 by zherczeg, Tue Feb 28 11:33:34 2012 UTC revision 1176 by ph10, Sat Oct 27 15:46:35 2012 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
# 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    /* Local stack area size and variable pointers. */    /* Maps private data offset to each opcode. */
281    int localsize;    int *private_data_ptrs;
282    int *localptrs;    /* 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 291  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 330  typedef struct compiler_common { Line 343  typedef struct compiler_common {
343  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
344    BOOL use_ucp;    BOOL use_ucp;
345  #endif  #endif
346    #ifndef COMPILE_PCRE32
347    jump_list *utfreadchar;    jump_list *utfreadchar;
348    #endif
349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
350    jump_list *utfreadtype8;    jump_list *utfreadtype8;
351  #endif  #endif
# Line 350  typedef struct compare_context { Line 365  typedef struct compare_context {
365    union {    union {
366      sljit_i asint;      sljit_i asint;
367      sljit_uh asushort;      sljit_uh asushort;
368  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
369      sljit_ub asbyte;      sljit_ub asbyte;
370      sljit_ub asuchars[4];      sljit_ub asuchars[4];
371  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
372      sljit_uh asuchars[2];      sljit_uh asuchars[2];
373  #endif  #elif defined COMPILE_PCRE32
374        sljit_ui asuchars[1];
375  #endif  #endif
376    } c;    } c;
377    union {    union {
378      sljit_i asint;      sljit_i asint;
379      sljit_uh asushort;      sljit_uh asushort;
380  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
381      sljit_ub asbyte;      sljit_ub asbyte;
382      sljit_ub asuchars[4];      sljit_ub asuchars[4];
383  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
384      sljit_uh asuchars[2];      sljit_uh asuchars[2];
385  #endif  #elif defined COMPILE_PCRE32
386        sljit_ui asuchars[1];
387  #endif  #endif
388    } oc;    } oc;
389  #endif  #endif
# Line 397  enum { Line 412  enum {
412  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
413  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
414    
415  /* Locals layout. */  /* Local space layout. */
416  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
417  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
418  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
# Line 413  the start pointers when the end of the c Line 428  the start pointers when the end of the c
428  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
429  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
430  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
431  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
432    
433  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
434  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
435  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
436  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
437  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
438  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
439    #elif defined COMPILE_PCRE32
440    #define MOV_UCHAR  SLJIT_MOV_UI
441    #define MOVU_UCHAR SLJIT_MOVU_UI
442  #else  #else
443  #error Unsupported compiling mode  #error Unsupported compiling mode
444  #endif  #endif
 #endif  
445    
446  /* Shortcuts. */  /* Shortcuts. */
447  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 448  the start pointers when the end of the c Line 464  the start pointers when the end of the c
464    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
465  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
466    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
467    #define GET_LOCAL_BASE(dst, dstw, offset) \
468      sljit_get_local_base(compiler, (dst), (dstw), (offset))
469    
470  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
471  {  {
# Line 460  return cc; Line 478  return cc;
478    
479  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
480   next_opcode   next_opcode
481   get_localspace   get_private_data_length
482   set_localptrs   set_private_data_ptrs
483   get_framesize   get_framesize
484   init_frame   init_frame
485   get_localsize   get_private_data_length_for_copy
486   copy_locals   copy_private_data
487   compile_hotpath   compile_matchingpath
488   compile_fallbackpath   compile_backtrackingpath
489  */  */
490    
491  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 666  switch(*cc) Line 684  switch(*cc)
684    }    }
685  }  }
686    
687  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
688        case OP_MINSTAR: \
689        case OP_MINPLUS: \
690        case OP_QUERY: \
691        case OP_MINQUERY: \
692        case OP_MINSTARI: \
693        case OP_MINPLUSI: \
694        case OP_QUERYI: \
695        case OP_MINQUERYI: \
696        case OP_NOTMINSTAR: \
697        case OP_NOTMINPLUS: \
698        case OP_NOTQUERY: \
699        case OP_NOTMINQUERY: \
700        case OP_NOTMINSTARI: \
701        case OP_NOTMINPLUSI: \
702        case OP_NOTQUERYI: \
703        case OP_NOTMINQUERYI:
704    
705    #define CASE_ITERATOR_PRIVATE_DATA_2A \
706        case OP_STAR: \
707        case OP_PLUS: \
708        case OP_STARI: \
709        case OP_PLUSI: \
710        case OP_NOTSTAR: \
711        case OP_NOTPLUS: \
712        case OP_NOTSTARI: \
713        case OP_NOTPLUSI:
714    
715    #define CASE_ITERATOR_PRIVATE_DATA_2B \
716        case OP_UPTO: \
717        case OP_MINUPTO: \
718        case OP_UPTOI: \
719        case OP_MINUPTOI: \
720        case OP_NOTUPTO: \
721        case OP_NOTMINUPTO: \
722        case OP_NOTUPTOI: \
723        case OP_NOTMINUPTOI:
724    
725    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
726        case OP_TYPEMINSTAR: \
727        case OP_TYPEMINPLUS: \
728        case OP_TYPEQUERY: \
729        case OP_TYPEMINQUERY:
730    
731    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
732        case OP_TYPESTAR: \
733        case OP_TYPEPLUS:
734    
735    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
736        case OP_TYPEUPTO: \
737        case OP_TYPEMINUPTO:
738    
739    static int get_class_iterator_size(pcre_uchar *cc)
740    {
741    switch(*cc)
742      {
743      case OP_CRSTAR:
744      case OP_CRPLUS:
745      return 2;
746    
747      case OP_CRMINSTAR:
748      case OP_CRMINPLUS:
749      case OP_CRQUERY:
750      case OP_CRMINQUERY:
751      return 1;
752    
753      case OP_CRRANGE:
754      case OP_CRMINRANGE:
755      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
756        return 0;
757      return 2;
758    
759      default:
760      return 0;
761      }
762    }
763    
764    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
765  {  {
766  int localspace = 0;  int private_data_length = 0;
767  pcre_uchar *alternative;  pcre_uchar *alternative;
768    pcre_uchar *name;
769    pcre_uchar *end = NULL;
770    int space, size, i;
771    pcre_uint32 bracketlen;
772    
773  /* 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. */
774  while (cc < ccend)  while (cc < ccend)
775    {    {
776      space = 0;
777      size = 0;
778      bracketlen = 0;
779    switch(*cc)    switch(*cc)
780      {      {
781      case OP_SET_SOM:      case OP_SET_SOM:
# Line 680  while (cc < ccend) Line 783  while (cc < ccend)
783      cc += 1;      cc += 1;
784      break;      break;
785    
786        case OP_REF:
787        case OP_REFI:
788        common->optimized_cbracket[GET2(cc, 1)] = 0;
789        cc += 1 + IMM2_SIZE;
790        break;
791    
792      case OP_ASSERT:      case OP_ASSERT:
793      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
794      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 689  while (cc < ccend) Line 798  while (cc < ccend)
798      case OP_BRAPOS:      case OP_BRAPOS:
799      case OP_SBRA:      case OP_SBRA:
800      case OP_SBRAPOS:      case OP_SBRAPOS:
801      case OP_SCOND:      private_data_length += sizeof(sljit_w);
802      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
803      break;      break;
804    
805      case OP_CBRAPOS:      case OP_CBRAPOS:
806      case OP_SCBRAPOS:      case OP_SCBRAPOS:
807      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
808      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
809        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
810      break;      break;
811    
812      case OP_COND:      case OP_COND:
813      /* Might be a hidden SCOND. */      case OP_SCOND:
814      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
815      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
816        localspace += sizeof(sljit_w);        {
817      cc += 1 + LINK_SIZE;        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
818          common->optimized_cbracket[bracketlen] = 0;
819          }
820        else if (bracketlen == OP_NCREF)
821          {
822          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
823          name = (pcre_uchar *)common->name_table;
824          alternative = name;
825          for (i = 0; i < common->name_count; i++)
826            {
827            if (GET2(name, 0) == bracketlen) break;
828            name += common->name_entry_size;
829            }
830          SLJIT_ASSERT(i != common->name_count);
831    
832          for (i = 0; i < common->name_count; i++)
833            {
834            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
835              common->optimized_cbracket[GET2(alternative, 0)] = 0;
836            alternative += common->name_entry_size;
837            }
838          }
839    
840        if (*cc == OP_COND)
841          {
842          /* Might be a hidden SCOND. */
843          alternative = cc + GET(cc, 1);
844          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
845            private_data_length += sizeof(sljit_w);
846          }
847        else
848          private_data_length += sizeof(sljit_w);
849        bracketlen = 1 + LINK_SIZE;
850        break;
851    
852        case OP_BRA:
853        bracketlen = 1 + LINK_SIZE;
854        break;
855    
856        case OP_CBRA:
857        case OP_SCBRA:
858        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
859        break;
860    
861        CASE_ITERATOR_PRIVATE_DATA_1
862        space = 1;
863        size = -2;
864        break;
865    
866        CASE_ITERATOR_PRIVATE_DATA_2A
867        space = 2;
868        size = -2;
869        break;
870    
871        CASE_ITERATOR_PRIVATE_DATA_2B
872        space = 2;
873        size = -(2 + IMM2_SIZE);
874        break;
875    
876        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
877        space = 1;
878        size = 1;
879      break;      break;
880    
881        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
882        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
883          space = 2;
884        size = 1;
885        break;
886    
887        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
888        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
889          space = 2;
890        size = 1 + IMM2_SIZE;
891        break;
892    
893        case OP_CLASS:
894        case OP_NCLASS:
895        size += 1 + 32 / sizeof(pcre_uchar);
896        space = get_class_iterator_size(cc + size);
897        break;
898    
899    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
900        case OP_XCLASS:
901        size = GET(cc, 1);
902        space = get_class_iterator_size(cc + size);
903        break;
904    #endif
905    
906      case OP_RECURSE:      case OP_RECURSE:
907      /* Set its value only once. */      /* Set its value only once. */
908      if (common->recursive_head == 0)      if (common->recursive_head == 0)
# Line 733  while (cc < ccend) Line 928  while (cc < ccend)
928        return -1;        return -1;
929      break;      break;
930      }      }
931    
932      if (space > 0 && cc >= end)
933        private_data_length += sizeof(sljit_w) * space;
934    
935      if (size != 0)
936        {
937        if (size < 0)
938          {
939          cc += -size;
940    #ifdef SUPPORT_UTF
941          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
942    #endif
943          }
944        else
945          cc += size;
946        }
947    
948      if (bracketlen != 0)
949        {
950        if (cc >= end)
951          {
952          end = bracketend(cc);
953          if (end[-1 - LINK_SIZE] == OP_KET)
954            end = NULL;
955          }
956        cc += bracketlen;
957        }
958    }    }
959  return localspace;  return private_data_length;
960  }  }
961    
962  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)
963  {  {
964  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
965  pcre_uchar *alternative;  pcre_uchar *alternative;
966    pcre_uchar *end = NULL;
967    int space, size, bracketlen;
968    
969  while (cc < ccend)  while (cc < ccend)
970    {    {
971      space = 0;
972      size = 0;
973      bracketlen = 0;
974    switch(*cc)    switch(*cc)
975      {      {
976      case OP_ASSERT:      case OP_ASSERT:
# Line 755  while (cc < ccend) Line 983  while (cc < ccend)
983      case OP_SBRA:      case OP_SBRA:
984      case OP_SBRAPOS:      case OP_SBRAPOS:
985      case OP_SCOND:      case OP_SCOND:
986      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
987      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
988      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
989      break;      break;
990    
991      case OP_CBRAPOS:      case OP_CBRAPOS:
992      case OP_SCBRAPOS:      case OP_SCBRAPOS:
993      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
994      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
995      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
996      break;      break;
997    
998      case OP_COND:      case OP_COND:
# Line 772  while (cc < ccend) Line 1000  while (cc < ccend)
1000      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1001      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1002        {        {
1003        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1004        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1005        }        }
1006      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1007        break;
1008    
1009        case OP_BRA:
1010        bracketlen = 1 + LINK_SIZE;
1011        break;
1012    
1013        case OP_CBRA:
1014        case OP_SCBRA:
1015        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1016        break;
1017    
1018        CASE_ITERATOR_PRIVATE_DATA_1
1019        space = 1;
1020        size = -2;
1021        break;
1022    
1023        CASE_ITERATOR_PRIVATE_DATA_2A
1024        space = 2;
1025        size = -2;
1026        break;
1027    
1028        CASE_ITERATOR_PRIVATE_DATA_2B
1029        space = 2;
1030        size = -(2 + IMM2_SIZE);
1031        break;
1032    
1033        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1034        space = 1;
1035        size = 1;
1036        break;
1037    
1038        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1039        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1040          space = 2;
1041        size = 1;
1042        break;
1043    
1044        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1045        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1046          space = 2;
1047        size = 1 + IMM2_SIZE;
1048        break;
1049    
1050        case OP_CLASS:
1051        case OP_NCLASS:
1052        size += 1 + 32 / sizeof(pcre_uchar);
1053        space = get_class_iterator_size(cc + size);
1054      break;      break;
1055    
1056    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1057        case OP_XCLASS:
1058        size = GET(cc, 1);
1059        space = get_class_iterator_size(cc + size);
1060        break;
1061    #endif
1062    
1063      default:      default:
1064      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1065      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1066      break;      break;
1067      }      }
1068    
1069      if (space > 0 && cc >= end)
1070        {
1071        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1072        private_data_ptr += sizeof(sljit_w) * space;
1073        }
1074    
1075      if (size != 0)
1076        {
1077        if (size < 0)
1078          {
1079          cc += -size;
1080    #ifdef SUPPORT_UTF
1081          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1082    #endif
1083          }
1084        else
1085          cc += size;
1086        }
1087    
1088      if (bracketlen > 0)
1089        {
1090        if (cc >= end)
1091          {
1092          end = bracketend(cc);
1093          if (end[-1 - LINK_SIZE] == OP_KET)
1094            end = NULL;
1095          }
1096        cc += bracketlen;
1097        }
1098    }    }
1099  }  }
1100    
# Line 959  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1271  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1271  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1272  }  }
1273    
1274  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)
1275  {  {
1276  int localsize = 2;  int private_data_length = 2;
1277    int size;
1278  pcre_uchar *alternative;  pcre_uchar *alternative;
1279  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1280  while (cc < ccend)  while (cc < ccend)
1281    {    {
1282      size = 0;
1283    switch(*cc)    switch(*cc)
1284      {      {
1285      case OP_ASSERT:      case OP_ASSERT:
# Line 978  while (cc < ccend) Line 1292  while (cc < ccend)
1292      case OP_SBRA:      case OP_SBRA:
1293      case OP_SBRAPOS:      case OP_SBRAPOS:
1294      case OP_SCOND:      case OP_SCOND:
1295      localsize++;      private_data_length++;
1296      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1297      break;      break;
1298    
1299      case OP_CBRA:      case OP_CBRA:
1300      case OP_SCBRA:      case OP_SCBRA:
1301      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1302          private_data_length++;
1303      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1304      break;      break;
1305    
1306      case OP_CBRAPOS:      case OP_CBRAPOS:
1307      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1308      localsize += 2;      private_data_length += 2;
1309      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1310      break;      break;
1311    
# Line 998  while (cc < ccend) Line 1313  while (cc < ccend)
1313      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1314      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1315      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1316        localsize++;        private_data_length++;
1317      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1318      break;      break;
1319    
1320        CASE_ITERATOR_PRIVATE_DATA_1
1321        if (PRIVATE_DATA(cc))
1322          private_data_length++;
1323        cc += 2;
1324    #ifdef SUPPORT_UTF
1325        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1326    #endif
1327        break;
1328    
1329        CASE_ITERATOR_PRIVATE_DATA_2A
1330        if (PRIVATE_DATA(cc))
1331          private_data_length += 2;
1332        cc += 2;
1333    #ifdef SUPPORT_UTF
1334        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1335    #endif
1336        break;
1337    
1338        CASE_ITERATOR_PRIVATE_DATA_2B
1339        if (PRIVATE_DATA(cc))
1340          private_data_length += 2;
1341        cc += 2 + IMM2_SIZE;
1342    #ifdef SUPPORT_UTF
1343        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1344    #endif
1345        break;
1346    
1347        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1348        if (PRIVATE_DATA(cc))
1349          private_data_length++;
1350        cc += 1;
1351        break;
1352    
1353        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1354        if (PRIVATE_DATA(cc))
1355          private_data_length += 2;
1356        cc += 1;
1357        break;
1358    
1359        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1360        if (PRIVATE_DATA(cc))
1361          private_data_length += 2;
1362        cc += 1 + IMM2_SIZE;
1363        break;
1364    
1365        case OP_CLASS:
1366        case OP_NCLASS:
1367    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1368        case OP_XCLASS:
1369        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1370    #else
1371        size = 1 + 32 / (int)sizeof(pcre_uchar);
1372    #endif
1373        if (PRIVATE_DATA(cc))
1374          private_data_length += get_class_iterator_size(cc + size);
1375        cc += size;
1376        break;
1377    
1378      default:      default:
1379      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1380      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1009  while (cc < ccend) Line 1382  while (cc < ccend)
1382      }      }
1383    }    }
1384  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1385  return localsize;  return private_data_length;
1386  }  }
1387    
1388  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,
1389    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1390  {  {
1391  DEFINE_COMPILER;  DEFINE_COMPILER;
1392  int srcw[2];  int srcw[2];
1393  int count;  int count, size;
1394  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1395  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1396  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1082  while (status != end) Line 1455  while (status != end)
1455        case OP_SBRAPOS:        case OP_SBRAPOS:
1456        case OP_SCOND:        case OP_SCOND:
1457        count = 1;        count = 1;
1458        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1459        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1460        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1461        break;        break;
1462    
1463        case OP_CBRA:        case OP_CBRA:
1464        case OP_SCBRA:        case OP_SCBRA:
1465        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1466        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1467            count = 1;
1468            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1469            }
1470        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1471        break;        break;
1472    
1473        case OP_CBRAPOS:        case OP_CBRAPOS:
1474        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1475        count = 2;        count = 2;
1476          srcw[0] = PRIVATE_DATA(cc);
1477        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1478        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1479        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1480        break;        break;
1481    
# Line 1109  while (status != end) Line 1485  while (status != end)
1485        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1486          {          {
1487          count = 1;          count = 1;
1488          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1489          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1490          }          }
1491        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1492        break;        break;
1493    
1494          CASE_ITERATOR_PRIVATE_DATA_1
1495          if (PRIVATE_DATA(cc))
1496            {
1497            count = 1;
1498            srcw[0] = PRIVATE_DATA(cc);
1499            }
1500          cc += 2;
1501    #ifdef SUPPORT_UTF
1502          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1503    #endif
1504          break;
1505    
1506          CASE_ITERATOR_PRIVATE_DATA_2A
1507          if (PRIVATE_DATA(cc))
1508            {
1509            count = 2;
1510            srcw[0] = PRIVATE_DATA(cc);
1511            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1512            }
1513          cc += 2;
1514    #ifdef SUPPORT_UTF
1515          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1516    #endif
1517          break;
1518    
1519          CASE_ITERATOR_PRIVATE_DATA_2B
1520          if (PRIVATE_DATA(cc))
1521            {
1522            count = 2;
1523            srcw[0] = PRIVATE_DATA(cc);
1524            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1525            }
1526          cc += 2 + IMM2_SIZE;
1527    #ifdef SUPPORT_UTF
1528          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1529    #endif
1530          break;
1531    
1532          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1533          if (PRIVATE_DATA(cc))
1534            {
1535            count = 1;
1536            srcw[0] = PRIVATE_DATA(cc);
1537            }
1538          cc += 1;
1539          break;
1540    
1541          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1542          if (PRIVATE_DATA(cc))
1543            {
1544            count = 2;
1545            srcw[0] = PRIVATE_DATA(cc);
1546            srcw[1] = srcw[0] + sizeof(sljit_w);
1547            }
1548          cc += 1;
1549          break;
1550    
1551          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1552          if (PRIVATE_DATA(cc))
1553            {
1554            count = 2;
1555            srcw[0] = PRIVATE_DATA(cc);
1556            srcw[1] = srcw[0] + sizeof(sljit_w);
1557            }
1558          cc += 1 + IMM2_SIZE;
1559          break;
1560    
1561          case OP_CLASS:
1562          case OP_NCLASS:
1563    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1564          case OP_XCLASS:
1565          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1566    #else
1567          size = 1 + 32 / (int)sizeof(pcre_uchar);
1568    #endif
1569          if (PRIVATE_DATA(cc))
1570            switch(get_class_iterator_size(cc + size))
1571              {
1572              case 1:
1573              count = 1;
1574              srcw[0] = PRIVATE_DATA(cc);
1575              break;
1576    
1577              case 2:
1578              count = 2;
1579              srcw[0] = PRIVATE_DATA(cc);
1580              srcw[1] = srcw[0] + sizeof(sljit_w);
1581              break;
1582    
1583              default:
1584              SLJIT_ASSERT_STOP();
1585              break;
1586              }
1587          cc += size;
1588          break;
1589    
1590        default:        default:
1591        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1592        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1217  if (save) Line 1689  if (save)
1689  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1690  }  }
1691    
1692  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1693    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1694    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1695    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1696    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1697    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1698    
1699    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1700  {  {
1701  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1702  }  }
# Line 1227  static SLJIT_INLINE void set_jumps(jump_ Line 1706  static SLJIT_INLINE void set_jumps(jump_
1706  while (list)  while (list)
1707    {    {
1708    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1709    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1710    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1711    list = list->next;    list = list->next;
1712    }    }
# Line 1254  if (list_item) Line 1733  if (list_item)
1733    list_item->type = type;    list_item->type = type;
1734    list_item->data = data;    list_item->data = data;
1735    list_item->start = start;    list_item->start = start;
1736    list_item->leave = LABEL();    list_item->quit = LABEL();
1737    list_item->next = common->stubs;    list_item->next = common->stubs;
1738    common->stubs = list_item;    common->stubs = list_item;
1739    }    }
# Line 1274  while (list_item) Line 1753  while (list_item)
1753      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1754      break;      break;
1755      }      }
1756    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1757    list_item = list_item->next;    list_item = list_item->next;
1758    }    }
1759  common->stubs = NULL;  common->stubs = NULL;
# Line 1325  if (length < 8) Line 1804  if (length < 8)
1804    }    }
1805  else  else
1806    {    {
1807    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1808    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1809    loop = LABEL();    loop = LABEL();
1810    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1352  if (common->mark_ptr != 0) Line 1831  if (common->mark_ptr != 0)
1831    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1832  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1833  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1834  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1835  /* Unlikely, but possible */  /* Unlikely, but possible */
1836  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1837  loop = LABEL();  loop = LABEL();
1838  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1839  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1840  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1841  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1842  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1843  #endif  #endif
1844  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1845  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
# Line 1370  JUMPHERE(earlyexit); Line 1849  JUMPHERE(earlyexit);
1849  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1850  if (topbracket > 1)  if (topbracket > 1)
1851    {    {
1852    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1853    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1854    
1855    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
# Line 1384  else Line 1863  else
1863    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1864  }  }
1865    
1866  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)
1867  {  {
1868  DEFINE_COMPILER;  DEFINE_COMPILER;
1869    
# Line 1394  SLJIT_ASSERT(common->start_used_ptr != 0 Line 1873  SLJIT_ASSERT(common->start_used_ptr != 0
1873  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1874  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1875  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));
1876  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1877    
1878  /* Store match begin and end. */  /* Store match begin and end. */
1879  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));
1880  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1881  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1882  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1883  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1884  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1885  #endif  #endif
1886  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1887    
1888  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1889  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1890  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1891  #endif  #endif
1892  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);
1893    
1894  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1895  }  }
1896    
1897  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1523  if (c <= 127 && bit == 0x20) Line 2002  if (c <= 127 && bit == 0x20)
2002    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2003    
2004  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2005  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2006    return 0;    return 0;
2007    
2008  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2009    
2010  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2011  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1542  if (common->utf && c > 127) Line 2021  if (common->utf && c > 127)
2021  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2022  return (0 << 8) | bit;  return (0 << 8) | bit;
2023    
2024  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2025    
 #ifdef COMPILE_PCRE16  
2026  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2027  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2028    {    {
# Line 1555  if (common->utf && c > 65535) Line 2033  if (common->utf && c > 65535)
2033    }    }
2034  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2035  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2036    
2037  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2038  }  }
2039    
2040  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 1621  JUMPHERE(jump); Line 2098  JUMPHERE(jump);
2098  return return_value;  return return_value;
2099  }  }
2100    
2101  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2102  {  {
2103  DEFINE_COMPILER;  DEFINE_COMPILER;
2104  struct sljit_jump *jump;  struct sljit_jump *jump;
2105    
2106  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2107    {    {
2108    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));
2109    return;    return;
2110    }    }
2111    
2112  /* Partial matching mode. */  /* Partial matching mode. */
2113  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2114  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));
2115  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2116    {    {
2117    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);
2118    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2119    }    }
2120  else  else
2121    {    {
# Line 1655  static void read_char(compiler_common *c Line 2132  static void read_char(compiler_common *c
2132  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2133  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2134  DEFINE_COMPILER;  DEFINE_COMPILER;
2135  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2136  struct sljit_jump *jump;  struct sljit_jump *jump;
2137  #endif  #endif
2138    
2139  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2140  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2141  if (common->utf)  if (common->utf)
2142    {    {
2143  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2144    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2145  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2146    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2147  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2148    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2149    JUMPHERE(jump);    JUMPHERE(jump);
2150    }    }
2151  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2152  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));
2153  }  }
2154    
# Line 1682  static void peek_char(compiler_common *c Line 2157  static void peek_char(compiler_common *c
2157  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2158  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2159  DEFINE_COMPILER;  DEFINE_COMPILER;
2160  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2161  struct sljit_jump *jump;  struct sljit_jump *jump;
2162  #endif  #endif
2163    
2164  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2165  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2166  if (common->utf)  if (common->utf)
2167    {    {
2168  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2169    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2170  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2171    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2172  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2173    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2174    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2175    JUMPHERE(jump);    JUMPHERE(jump);
2176    }    }
2177  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2178  }  }
2179    
2180  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2181  {  {
2182  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2183  DEFINE_COMPILER;  DEFINE_COMPILER;
2184  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2185  struct sljit_jump *jump;  struct sljit_jump *jump;
2186  #endif  #endif
2187    
# Line 1717  if (common->utf) Line 2190  if (common->utf)
2190    {    {
2191    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2192    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));
2193  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2194    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2195    it is needed in most cases. */    it is needed in most cases. */
2196    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2197    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2198    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2199    JUMPHERE(jump);    JUMPHERE(jump);
2200  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2201    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2202    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2203    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 1736  if (common->utf) Line 2208  if (common->utf)
2208    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2209    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2210    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2211  #endif  #elif defined COMPILE_PCRE32
2212  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2213      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2214      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2215      JUMPHERE(jump);
2216    #endif /* COMPILE_PCRE[8|16|32] */
2217    return;    return;
2218    }    }
2219  #endif  #endif /* SUPPORT_UTF */
2220  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2221  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));
2222  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2223  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2224  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2225  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2226  #endif  #endif
2227  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2228  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2229  JUMPHERE(jump);  JUMPHERE(jump);
2230  #endif  #endif
2231  }  }
# Line 1758  static void skip_char_back(compiler_comm Line 2234  static void skip_char_back(compiler_comm
2234  {  {
2235  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2236  DEFINE_COMPILER;  DEFINE_COMPILER;
2237  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2238    #if defined COMPILE_PCRE8
2239  struct sljit_label *label;  struct sljit_label *label;
2240    
2241  if (common->utf)  if (common->utf)
# Line 1770  if (common->utf) Line 2247  if (common->utf)
2247    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2248    return;    return;
2249    }    }
2250  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2251  if (common->utf)  if (common->utf)
2252    {    {
2253    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 1784  if (common->utf) Line 2260  if (common->utf)
2260    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2261    return;    return;
2262    }    }
2263  #endif  #endif /* COMPILE_PCRE[8|16] */
2264    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2265  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));
2266  }  }
2267    
2268  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)
2269  {  {
2270  /* 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. */
2271  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1796  DEFINE_COMPILER; Line 2273  DEFINE_COMPILER;
2273  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2274    {    {
2275    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2276    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));
2277    }    }
2278  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2279    {    {
# Line 1804  else if (nltype == NLTYPE_ANYCRLF) Line 2281  else if (nltype == NLTYPE_ANYCRLF)
2281    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2282    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);
2283    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2284    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));
2285    }    }
2286  else  else
2287    {    {
2288    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2289    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));
2290    }    }
2291  }  }
2292    
2293  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2294    
2295  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2296  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2297  {  {
2298  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 1823  of the character (>= 0xc0). Return char Line 2300  of the character (>= 0xc0). Return char
2300  DEFINE_COMPILER;  DEFINE_COMPILER;
2301  struct sljit_jump *jump;  struct sljit_jump *jump;
2302    
2303  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2304  /* Searching for the first zero. */  /* Searching for the first zero. */
2305  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2306  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1882  DEFINE_COMPILER; Line 2359  DEFINE_COMPILER;
2359  struct sljit_jump *jump;  struct sljit_jump *jump;
2360  struct sljit_jump *compare;  struct sljit_jump *compare;
2361    
2362  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2363    
2364  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
2365  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1909  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); Line 2386  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2386  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2387  }  }
2388    
2389  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2390    
 #ifdef COMPILE_PCRE16  
2391  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2392  {  {
2393  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 1919  of the character (>= 0xd800). Return cha Line 2395  of the character (>= 0xd800). Return cha
2395  DEFINE_COMPILER;  DEFINE_COMPILER;
2396  struct sljit_jump *jump;  struct sljit_jump *jump;
2397    
2398  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2399  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2400  /* Do nothing, only return. */  /* Do nothing, only return. */
2401  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1936  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2412  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2412  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2413  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2414  }  }
 #endif /* COMPILE_PCRE16 */  
2415    
2416  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2417    
2418  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2419    
# Line 1956  DEFINE_COMPILER; Line 2431  DEFINE_COMPILER;
2431    
2432  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2433    
2434  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2435  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2436  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
2437  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
# Line 1978  struct sljit_label *newlinelabel = NULL; Line 2453  struct sljit_label *newlinelabel = NULL;
2453  struct sljit_jump *start;  struct sljit_jump *start;
2454  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2455  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2456  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2457  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2458  #endif  #endif
2459  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 1993  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 2005  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 2016  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 2034  if (newlinecheck) Line 2509  if (newlinecheck)
2509    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2510    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2511    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2512  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2513    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2514  #endif  #endif
2515    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2516    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2056  if (newlinecheck) Line 2531  if (newlinecheck)
2531    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2532    
2533  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));
2534  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2535    #if defined COMPILE_PCRE8
2536  if (common->utf)  if (common->utf)
2537    {    {
2538    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
# Line 2064  if (common->utf) Line 2540  if (common->utf)
2540    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2541    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2542    }    }
2543  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2544  if (common->utf)  if (common->utf)
2545    {    {
2546    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
# Line 2076  if (common->utf) Line 2551  if (common->utf)
2551    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2552    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2553    }    }
2554  #endif  #endif /* COMPILE_PCRE[8|16] */
2555    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2556  JUMPHERE(start);  JUMPHERE(start);
2557    
2558  if (newlinecheck)  if (newlinecheck)
# Line 2088  if (newlinecheck) Line 2564  if (newlinecheck)
2564  return mainloop;  return mainloop;
2565  }  }
2566    
2567    #define MAX_N_CHARS 3
2568    
2569    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2570    {
2571    DEFINE_COMPILER;
2572    struct sljit_label *start;
2573    struct sljit_jump *quit;
2574    pcre_uint32 chars[MAX_N_CHARS * 2];
2575    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2576    int location = 0;
2577    pcre_int32 len, c, bit, caseless;
2578    int must_stop;
2579    
2580    /* We do not support alternatives now. */
2581    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2582      return FALSE;
2583    
2584    while (TRUE)
2585      {
2586      caseless = 0;
2587      must_stop = 1;
2588      switch(*cc)
2589        {
2590        case OP_CHAR:
2591        must_stop = 0;
2592        cc++;
2593        break;
2594    
2595        case OP_CHARI:
2596        caseless = 1;
2597        must_stop = 0;
2598        cc++;
2599        break;
2600    
2601        case OP_SOD:
2602        case OP_SOM:
2603        case OP_SET_SOM:
2604        case OP_NOT_WORD_BOUNDARY:
2605        case OP_WORD_BOUNDARY:
2606        case OP_EODN:
2607        case OP_EOD:
2608        case OP_CIRC:
2609        case OP_CIRCM:
2610        case OP_DOLL:
2611        case OP_DOLLM:
2612        /* Zero width assertions. */
2613        cc++;
2614        continue;
2615    
2616        case OP_PLUS:
2617        case OP_MINPLUS:
2618        case OP_POSPLUS:
2619        cc++;
2620        break;
2621    
2622        case OP_EXACT:
2623        cc += 1 + IMM2_SIZE;
2624        break;
2625    
2626        case OP_PLUSI:
2627        case OP_MINPLUSI:
2628        case OP_POSPLUSI:
2629        caseless = 1;
2630        cc++;
2631        break;
2632    
2633        case OP_EXACTI:
2634        caseless = 1;
2635        cc += 1 + IMM2_SIZE;
2636        break;
2637    
2638        default:
2639        must_stop = 2;
2640        break;
2641        }
2642    
2643      if (must_stop == 2)
2644          break;
2645    
2646      len = 1;
2647    #ifdef SUPPORT_UTF
2648      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2649    #endif
2650    
2651      if (caseless && char_has_othercase(common, cc))
2652        {
2653        caseless = char_get_othercase_bit(common, cc);
2654        if (caseless == 0)
2655          return FALSE;
2656    #ifdef COMPILE_PCRE8
2657        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2658    #else
2659        if ((caseless & 0x100) != 0)
2660          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2661        else
2662          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2663    #endif
2664        }
2665      else
2666        caseless = 0;
2667    
2668      while (len > 0 && location < MAX_N_CHARS * 2)
2669        {
2670        c = *cc;
2671        bit = 0;
2672        if (len == (caseless & 0xff))
2673          {
2674          bit = caseless >> 8;
2675          c |= bit;
2676          }
2677    
2678        chars[location] = c;
2679        chars[location + 1] = bit;
2680    
2681        len--;
2682        location += 2;
2683        cc++;
2684        }
2685    
2686      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2687        break;
2688      }
2689    
2690    /* At least two characters are required. */
2691    if (location < 2 * 2)
2692        return FALSE;
2693    
2694    if (firstline)
2695      {
2696      SLJIT_ASSERT(common->first_line_end != 0);
2697      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2698      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2699      }
2700    else
2701      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2702    
2703    start = LABEL();
2704    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2705    
2706    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2707    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2708    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2709    if (chars[1] != 0)
2710      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2711    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2712    if (location > 2 * 2)
2713      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2714    if (chars[3] != 0)
2715      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2716    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2717    if (location > 2 * 2)
2718      {
2719      if (chars[5] != 0)
2720        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2721      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2722      }
2723    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2724    
2725    JUMPHERE(quit);
2726    
2727    if (firstline)
2728      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2729    else
2730      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2731    return TRUE;
2732    }
2733    
2734    #undef MAX_N_CHARS
2735    
2736  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)
2737  {  {
2738  DEFINE_COMPILER;  DEFINE_COMPILER;
2739  struct sljit_label *start;  struct sljit_label *start;
2740  struct sljit_jump *leave;  struct sljit_jump *quit;
2741  struct sljit_jump *found;  struct sljit_jump *found;
2742  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2743    
2744  if (firstline)  if (firstline)
2745    {    {
2746    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2747      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2748    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);
2749    }    }
2750    
2751  start = LABEL();  start = LABEL();
2752  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2753  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2754    
2755  oc = first_char;  oc = first_char;
# Line 2120  if (first_char == oc) Line 2766  if (first_char == oc)
2766  else  else
2767    {    {
2768    bit = first_char ^ oc;    bit = first_char ^ oc;
2769    if (ispowerof2(bit))    if (is_powerof2(bit))
2770      {      {
2771      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2772      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2136  else Line 2782  else
2782    }    }
2783    
2784  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  
2785  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2786  JUMPHERE(found);  JUMPHERE(found);
2787  JUMPHERE(leave);  JUMPHERE(quit);
2788    
2789  if (firstline)  if (firstline)
2790    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2791  }  }
2792    
2793  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 2169  DEFINE_COMPILER; Line 2796  DEFINE_COMPILER;
2796  struct sljit_label *loop;  struct sljit_label *loop;
2797  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2798  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2799  struct sljit_jump *leave;  struct sljit_jump *quit;
2800  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2801  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2802  jump_list *newline = NULL;  jump_list *newline = NULL;
2803    
2804  if (firstline)  if (firstline)
2805    {    {
2806    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2807      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2808    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);
2809    }    }
2810    
# Line 2191  if (common->nltype == NLTYPE_FIXED && co Line 2819  if (common->nltype == NLTYPE_FIXED && co
2819    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2820    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2821    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2822  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2823    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2824  #endif  #endif
2825    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2826    
2827    loop = LABEL();    loop = LABEL();
2828    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));
2829    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2830    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2831    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2832    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);
2833    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);
2834    
2835    JUMPHERE(leave);    JUMPHERE(quit);
2836    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2837    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2838    
# Line 2228  set_jumps(newline, loop); Line 2856  set_jumps(newline, loop);
2856    
2857  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2858    {    {
2859    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2860    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2861    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2862    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2863    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);
2864    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2865  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2866    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2867  #endif  #endif
2868    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2869    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2870    JUMPHERE(leave);    JUMPHERE(quit);
2871    }    }
2872  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2873  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2874    
2875  if (firstline)  if (firstline)
2876    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2877  }  }
2878    
2879  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)
2880  {  {
2881  DEFINE_COMPILER;  DEFINE_COMPILER;
2882  struct sljit_label *start;  struct sljit_label *start;
2883  struct sljit_jump *leave;  struct sljit_jump *quit;
2884  struct sljit_jump *found;  struct sljit_jump *found;
2885  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2886  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2260  struct sljit_jump *jump; Line 2888  struct sljit_jump *jump;
2888    
2889  if (firstline)  if (firstline)
2890    {    {
2891    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2892      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2893    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);
2894    }    }
2895    
2896  start = LABEL();  start = LABEL();
2897  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2898  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2899  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2900  if (common->utf)  if (common->utf)
# Line 2288  if (common->utf) Line 2917  if (common->utf)
2917    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2918  #endif  #endif
2919  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));
2920  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2921    #if defined COMPILE_PCRE8
2922  if (common->utf)  if (common->utf)
2923    {    {
2924    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2925    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2926    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2927    }    }
2928  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2929  if (common->utf)  if (common->utf)
2930    {    {
2931    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
# Line 2306  if (common->utf) Line 2935  if (common->utf)
2935    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2936    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2937    }    }
2938  #endif  #endif /* COMPILE_PCRE[8|16] */
2939    #endif /* SUPPORT_UTF */
2940  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2941  JUMPHERE(found);  JUMPHERE(found);
2942  JUMPHERE(leave);  JUMPHERE(quit);
2943    
2944  if (firstline)  if (firstline)
2945    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2946  }  }
2947    
2948  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 2324  struct sljit_jump *alreadyfound; Line 2954  struct sljit_jump *alreadyfound;
2954  struct sljit_jump *found;  struct sljit_jump *found;
2955  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2956  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2957  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2958    
2959  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2960  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2355  if (req_char == oc) Line 2985  if (req_char == oc)
2985  else  else
2986    {    {
2987    bit = req_char ^ oc;    bit = req_char ^ oc;
2988    if (ispowerof2(bit))    if (is_powerof2(bit))
2989      {      {
2990      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2991      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 2384  DEFINE_COMPILER; Line 3014  DEFINE_COMPILER;
3014  struct sljit_jump *jump;  struct sljit_jump *jump;
3015  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3016    
3017  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3018  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3019    GET_LOCAL_BASE(TMP3, 0, 0);
3020    
3021  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3022  mainloop = LABEL();  mainloop = LABEL();
3023  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3024  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
3025  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3026  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3027  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
3028  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
# Line 2437  struct sljit_jump *jump; Line 3068  struct sljit_jump *jump;
3068    
3069  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3070    
3071  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3072  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3073  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3074  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
# Line 2529  else Line 3160  else
3160      JUMPHERE(jump);      JUMPHERE(jump);
3161  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3162    }    }
3163  JUMPHERE(skipread);  JUMPHERE(skipread);
3164    
3165    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3166    sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3167    }
3168    
3169    /*
3170      range format:
3171    
3172      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3173      ranges[1] = first bit (0 or 1)
3174      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3175    */
3176    
3177    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3178    {
3179    DEFINE_COMPILER;
3180    struct sljit_jump *jump;
3181    
3182    if (ranges[0] < 0)
3183      return FALSE;
3184    
3185    switch(ranges[0])
3186      {
3187      case 1:
3188      if (readch)
3189        read_char(common);
3190      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3191      return TRUE;
3192    
3193      case 2:
3194      if (readch)
3195        read_char(common);
3196      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3197      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3198      return TRUE;
3199    
3200      case 4:
3201      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3202        {
3203        if (readch)
3204          read_char(common);
3205        if (ranges[1] != 0)
3206          {
3207          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3208          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3209          }
3210        else
3211          {
3212          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3213          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3214          JUMPHERE(jump);
3215          }
3216        return TRUE;
3217        }
3218      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3219        {
3220        if (readch)
3221          read_char(common);
3222        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3223        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3224        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3225        return TRUE;
3226        }
3227      return FALSE;
3228    
3229      default:
3230      return FALSE;
3231      }
3232    }
3233    
3234    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3235    {
3236    int i, bit, length;
3237    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3238    
3239    bit = ctypes[0] & flag;
3240    ranges[0] = -1;
3241    ranges[1] = bit != 0 ? 1 : 0;
3242    length = 0;
3243    
3244    for (i = 1; i < 256; i++)
3245      if ((ctypes[i] & flag) != bit)
3246        {
3247        if (length >= MAX_RANGE_SIZE)
3248          return;
3249        ranges[2 + length] = i;
3250        length++;
3251        bit ^= flag;
3252        }
3253    
3254    if (bit != 0)
3255      {
3256      if (length >= MAX_RANGE_SIZE)
3257        return;
3258      ranges[2 + length] = 256;
3259      length++;
3260      }
3261    ranges[0] = length;
3262    }
3263    
3264    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3265    {
3266    int ranges[2 + MAX_RANGE_SIZE];
3267    pcre_uint8 bit, cbit, all;
3268    int i, byte, length = 0;
3269    
3270    bit = bits[0] & 0x1;
3271    ranges[1] = bit;
3272    /* Can be 0 or 255. */
3273    all = -bit;
3274    
3275    for (i = 0; i < 256; )
3276      {
3277      byte = i >> 3;
3278      if ((i & 0x7) == 0 && bits[byte] == all)
3279        i += 8;
3280      else
3281        {
3282        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3283        if (cbit != bit)
3284          {
3285          if (length >= MAX_RANGE_SIZE)
3286            return FALSE;
3287          ranges[2 + length] = i;
3288          length++;
3289          bit = cbit;
3290          all = -cbit;
3291          }
3292        i++;
3293        }
3294      }
3295    
3296  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3297  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    {
3298      if (length >= MAX_RANGE_SIZE)
3299        return FALSE;
3300      ranges[2 + length] = 256;
3301      length++;
3302      }
3303    ranges[0] = length;
3304    
3305    return check_ranges(common, ranges, backtracks, FALSE);
3306  }  }
3307    
3308  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 2540  static void check_anynewline(compiler_co Line 3310  static void check_anynewline(compiler_co
3310  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3311  DEFINE_COMPILER;  DEFINE_COMPILER;
3312    
3313  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3314    
3315  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3316  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3317  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3318  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3319  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3320  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3321  if (common->utf)  if (common->utf)
3322    {    {
# Line 2557  if (common->utf) Line 3327  if (common->utf)
3327  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3328    }    }
3329  #endif  #endif
3330  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3331  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3332  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3333  }  }
# Line 2567  static void check_hspace(compiler_common Line 3337  static void check_hspace(compiler_common
3337  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3338  DEFINE_COMPILER;  DEFINE_COMPILER;
3339    
3340  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3341    
3342  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3343  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3344  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3345  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3346  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3347  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3348  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3349  if (common->utf)  if (common->utf)
3350    {    {
# Line 2595  if (common->utf) Line 3365  if (common->utf)
3365  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3366    }    }
3367  #endif  #endif
3368  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3369  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3370    
3371  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2606  static void check_vspace(compiler_common Line 3376  static void check_vspace(compiler_common
3376  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3377  DEFINE_COMPILER;  DEFINE_COMPILER;
3378    
3379  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3380    
3381  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3382  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3383  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3384  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3385  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3386  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3387  if (common->utf)  if (common->utf)
3388    {    {
# Line 2623  if (common->utf) Line 3393  if (common->utf)
3393  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3394    }    }
3395  #endif  #endif
3396  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3397  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3398    
3399  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2638  DEFINE_COMPILER; Line 3408  DEFINE_COMPILER;
3408  struct sljit_jump *jump;  struct sljit_jump *jump;
3409  struct sljit_label *label;  struct sljit_label *label;
3410    
3411  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3412  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3413  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3414  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2667  DEFINE_COMPILER; Line 3437  DEFINE_COMPILER;
3437  struct sljit_jump *jump;  struct sljit_jump *jump;
3438  struct sljit_label *label;  struct sljit_label *label;
3439    
3440  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3441  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3442    
3443  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2713  sljit_emit_fast_return(compiler, RETURN_ Line 3483  sljit_emit_fast_return(compiler, RETURN_
3483  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3484  {  {
3485  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3486  int c1, c2;  pcre_uint32 c1, c2;
3487  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3488  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3489    const ucd_record *ur;
3490    const pcre_uint32 *pp;
3491    
3492  while (src1 < end1)  while (src1 < end1)
3493    {    {
# Line 2723  while (src1 < end1) Line 3495  while (src1 < end1)
3495      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3496    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3497    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3498    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3499      if (c1 != c2 && c1 != c2 + ur->other_case)
3500        {
3501        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3502        for (;;)
3503          {
3504          if (c1 < *pp) return NULL;
3505          if (c1 == *pp++) break;
3506          }
3507        }
3508    }    }
3509  return src2;  return src2;
3510  }  }
# Line 2731  return src2; Line 3512  return src2;
3512  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3513    
3514  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,
3515      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3516  {  {
3517  DEFINE_COMPILER;  DEFINE_COMPILER;
3518  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2745  if (caseless && char_has_othercase(commo Line 3526  if (caseless && char_has_othercase(commo
3526    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3527    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3528    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3529  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3530    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3531    othercasebit &= 0xff;    othercasebit &= 0xff;
3532  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3533  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3534      ever are characters outside the BMP whose othercase differs in only one
3535      bit from itself (there currently are none), this code will need to be
3536      revised for COMPILE_PCRE32. */
3537    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3538    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3539      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3540    else    else
3541      othercasebit &= 0xff;      othercasebit &= 0xff;
3542  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3543    }    }
3544    
3545  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3546    {    {
3547  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3548  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3549    if (context->length >= 4)    if (context->length >= 4)
3550      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 2770  if (context->sourcereg == -1) Line 3553  if (context->sourcereg == -1)
3553    else    else
3554  #endif  #endif
3555      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3556  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3557  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3558    if (context->length >= 4)    if (context->length >= 4)
3559      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3560    else    else
3561  #endif  #endif
3562      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3563  #endif  #elif defined COMPILE_PCRE32
3564  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3565    #endif /* COMPILE_PCRE[8|16|32] */
3566    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3567    }    }
3568    
# Line 2808  do Line 3591  do
3591      }      }
3592    context->ucharptr++;    context->ucharptr++;
3593    
3594  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3595    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3596  #else  #elif defined COMPILE_PCRE16
3597    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
3598    #elif defined COMPILE_PCRE32
3599      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3600  #endif  #endif
3601      {      {
3602    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3603      if (context->length >= 4)      if (context->length >= 4)
3604        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3605  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3606      else if (context->length >= 2)      else if (context->length >= 2)
3607        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3608      else if (context->length >= 1)      else if (context->length >= 1)
3609        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3610  #else  #elif defined COMPILE_PCRE16
3611      else if (context->length >= 2)      else if (context->length >= 2)
3612        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3613  #endif  #endif /* COMPILE_PCRE[8|16] */
3614    #elif defined COMPILE_PCRE32
3615        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3616    #endif /* COMPILE_PCRE[8|16|32] */
3617      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3618    
3619      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2832  do Line 3621  do
3621        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3622        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3623          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);
3624        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));
3625        break;        break;
3626    
3627    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
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    
3642    #endif /* COMPILE_PCRE[8|16] */
3643    
3644        default:        default:
3645        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3646        break;        break;
# Line 2859  do Line 3651  do
3651  #else  #else
3652    
3653    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
 #ifdef COMPILE_PCRE8  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #else  
3654    if (context->length > 0)    if (context->length > 0)
3655      OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3656  #endif  
3657    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3658    
3659    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3660      {      {
3661      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3662      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));
3663      }      }
3664    else    else
3665      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));
3666    
3667  #endif  #endif
3668    
# Line 2910  return cc; Line 3698  return cc;
3698      } \      } \
3699    charoffset = (value);    charoffset = (value);
3700    
3701  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)
3702  {  {
3703  DEFINE_COMPILER;  DEFINE_COMPILER;
3704  jump_list *found = NULL;  jump_list *found = NULL;
3705  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3706  unsigned int c;  pcre_int32 c, charoffset;
3707  int compares;  const pcre_uint32 *other_cases;
3708  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3709  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3710    int compares, invertcmp, numberofcmps;
3711  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3712  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3713  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3714  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3715  unsigned int typeoffset;  pcre_int32 typeoffset;
3716  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3717    
3718  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3719  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3720    detect_partial_match(common, backtracks);
3721  read_char(common);  read_char(common);
3722    
3723  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2942  if ((*cc++ & XCL_MAP) != 0) Line 3730  if ((*cc++ & XCL_MAP) != 0)
3730      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3731  #endif  #endif
3732    
3733    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3734    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3735    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3736    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3737    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);
3738    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3739        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3740        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3741        }
3742    
3743  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3744    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3020  while (*cc != XCL_END) Line 3811  while (*cc != XCL_END)
3811        needschar = TRUE;        needschar = TRUE;
3812        break;        break;
3813    
3814          case PT_CLIST:
3815          needschar = TRUE;
3816          break;
3817    
3818        default:        default:
3819        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3820        break;        break;
# Line 3080  typeoffset = 0; Line 3875  typeoffset = 0;
3875  while (*cc != XCL_END)  while (*cc != XCL_END)
3876    {    {
3877    compares--;    compares--;
3878    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3879    jump = NULL;    jump = NULL;
3880    
3881    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3162  while (*cc != XCL_END) Line 3957  while (*cc != XCL_END)
3957      switch(*cc)      switch(*cc)
3958        {        {
3959        case PT_ANY:        case PT_ANY:
3960        if (list != fallbacks)        if (list != backtracks)
3961          {          {
3962          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))
3963            continue;            continue;
# Line 3229  while (*cc != XCL_END) Line 4024  while (*cc != XCL_END)
4024        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);
4025        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4026        break;        break;
4027    
4028          case PT_CLIST:
4029          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4030    
4031          /* At least three characters are required.
4032             Otherwise this case would be handled by the normal code path. */
4033          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4034          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4035    
4036          /* Optimizing character pairs, if their difference is power of 2. */
4037          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4038            {
4039            if (charoffset == 0)
4040              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4041            else
4042              {
4043              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4044              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4045              }
4046            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4047            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4048            other_cases += 2;
4049            }
4050          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4051            {
4052            if (charoffset == 0)
4053              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4054            else
4055              {
4056              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_w)charoffset);
4057              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4058              }
4059            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4060            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4061    
4062            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4063            COND_VALUE(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4064    
4065            other_cases += 3;
4066            }
4067          else
4068            {
4069            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4070            COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4071            }
4072    
4073          while (*other_cases != NOTACHAR)
4074            {
4075            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4076            COND_VALUE(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, SLJIT_C_EQUAL);
4077            }
4078          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4079          break;
4080        }        }
4081      cc += 2;      cc += 2;
4082      }      }
4083  #endif  #endif
4084    
4085    if (jump != NULL)    if (jump != NULL)
4086      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
4087    }    }
4088    
4089  if (found != NULL)  if (found != NULL)
# Line 3247  if (found != NULL) Line 4095  if (found != NULL)
4095    
4096  #endif  #endif
4097    
4098  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)
4099  {  {
4100  DEFINE_COMPILER;  DEFINE_COMPILER;
4101  int length;  int length;
# Line 3266  switch(type) Line 4114  switch(type)
4114    case OP_SOD:    case OP_SOD:
4115    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4116    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));
4117    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));
4118    return cc;    return cc;
4119    
4120    case OP_SOM:    case OP_SOM:
4121    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4122    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));
4123    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));
4124    return cc;    return cc;
4125    
4126    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4127    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4128    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4129    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));
4130    return cc;    return cc;
4131    
4132    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4133    case OP_DIGIT:    case OP_DIGIT:
4134    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4135    read_char8_type(common);    if (common->digits[0] == -2)
4136    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4137    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4138      /* Flip the starting bit in the negative case. */
4139      if (type == OP_NOT_DIGIT)
4140        common->digits[1] ^= 1;
4141      if (!check_ranges(common, common->digits, backtracks, TRUE))
4142        {
4143        read_char8_type(common);
4144        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4145        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4146        }
4147      if (type == OP_NOT_DIGIT)
4148        common->digits[1] ^= 1;
4149    return cc;    return cc;
4150    
4151    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4152    case OP_WHITESPACE:    case OP_WHITESPACE:
4153    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4154    read_char8_type(common);    read_char8_type(common);
4155    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);
4156    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));
4157    return cc;    return cc;
4158    
4159    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4160    case OP_WORDCHAR:    case OP_WORDCHAR:
4161    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4162    read_char8_type(common);    read_char8_type(common);
4163    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);
4164    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));
4165    return cc;    return cc;
4166    
4167    case OP_ANY:    case OP_ANY:
4168    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4169    read_char(common);    read_char(common);
4170    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4171      {      {
# Line 3317  switch(type) Line 4176  switch(type)
4176        jump[1] = check_str_end(common);        jump[1] = check_str_end(common);
4177    
4178      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4179      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));
4180      if (jump[1] != NULL)      if (jump[1] != NULL)
4181        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4182      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4183      }      }
4184    else    else
4185      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4186    return cc;    return cc;
4187    
4188    case OP_ALLANY:    case OP_ALLANY:
4189    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4190  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4191    if (common->utf)    if (common->utf)
4192      {      {
4193      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4194      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));
4195  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4196    #if defined COMPILE_PCRE8
4197      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4198      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4199      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4200  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4201      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4202      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4203      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4204      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4205      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4206      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4207  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4208      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4209    #endif /* COMPILE_PCRE[8|16] */
4210      return cc;      return cc;
4211      }      }
4212  #endif  #endif
# Line 3355  switch(type) Line 4214  switch(type)
4214    return cc;    return cc;
4215    
4216    case OP_ANYBYTE:    case OP_ANYBYTE:
4217    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4218    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));
4219    return cc;    return cc;
4220    
# Line 3368  switch(type) Line 4227  switch(type)
4227    propdata[2] = cc[0];    propdata[2] = cc[0];
4228    propdata[3] = cc[1];    propdata[3] = cc[1];
4229    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4230    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4231    return cc + 2;    return cc + 2;
4232  #endif  #endif
4233  #endif  #endif
4234    
4235    case OP_ANYNL:    case OP_ANYNL:
4236    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4237    read_char(common);    read_char(common);
4238    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);
4239    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
# Line 3387  switch(type) Line 4246  switch(type)
4246    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));
4247    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4248    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4249    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4250    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4251    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4252    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3395  switch(type) Line 4254  switch(type)
4254    
4255    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4256    case OP_HSPACE:    case OP_HSPACE:
4257    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4258    read_char(common);    read_char(common);
4259    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4260    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));
4261    return cc;    return cc;
4262    
4263    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4264    case OP_VSPACE:    case OP_VSPACE:
4265    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4266    read_char(common);    read_char(common);
4267    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4268    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));
4269    return cc;    return cc;
4270    
4271  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4272    case OP_EXTUNI:    case OP_EXTUNI:
4273    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4274    read_char(common);    read_char(common);
4275    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4276    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));
4277    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4278      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4279      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4280    
4281    label = LABEL();    label = LABEL();
4282    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);
4283    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4284    read_char(common);    read_char(common);
4285    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4286    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));
4287    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);
4288    
4289      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4290      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_w)PRIV(ucp_gbtable));
4291      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4292      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4293      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4294      JUMPTO(SLJIT_C_NOT_ZERO, label);
4295    
4296    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4297    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4298      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4299    
4300    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4301      {      {
4302      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 3445  switch(type) Line 4315  switch(type)
4315      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));
4316      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4317      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4318        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));
4319      else      else
4320        {        {
4321        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
# Line 3453  switch(type) Line 4323  switch(type)
4323        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4324        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);
4325        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);
4326        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4327        check_partial(common, TRUE);        check_partial(common, TRUE);
4328        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4329        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4330        }        }
4331      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4332      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));
4333      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));
4334      }      }
4335    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4336      {      {
4337      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));
4338      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4339      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));
4340      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));
4341      }      }
4342    else    else
4343      {      {
# Line 3476  switch(type) Line 4346  switch(type)
4346      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));
4347      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);
4348      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4349      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4350      /* Equal. */      /* Equal. */
4351      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4352      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4353      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4354    
4355      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4356      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4357        {        {
4358        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));
4359        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));
4360        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));
4361        }        }
4362      else      else
4363        {        {
4364        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4365        read_char(common);        read_char(common);
4366        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));
4367        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4368        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4369        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4370        }        }
4371      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
# Line 3506  switch(type) Line 4376  switch(type)
4376    return cc;    return cc;
4377    
4378    case OP_EOD:    case OP_EOD:
4379    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));
4380    check_partial(common, FALSE);    check_partial(common, FALSE);
4381    return cc;    return cc;
4382    
4383    case OP_CIRC:    case OP_CIRC:
4384    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4385    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));
4386    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));
4387    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));
4388    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));
4389    return cc;    return cc;
4390    
4391    case OP_CIRCM:    case OP_CIRCM:
# Line 3523  switch(type) Line 4393  switch(type)
4393    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));
4394    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4395    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));
4396    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));
4397    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4398    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4399    
4400    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));
4401    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4402      {      {
4403      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));
4404      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4405      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4406      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4407      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));
4408      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));
4409      }      }
4410    else    else
4411      {      {
4412      skip_char_back(common);      skip_char_back(common);
4413      read_char(common);      read_char(common);
4414      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4415      }      }
4416    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4417    return cc;    return cc;
# Line 3549  switch(type) Line 4419  switch(type)
4419    case OP_DOLL:    case OP_DOLL:
4420    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4421    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));
4422    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));
4423    
4424    if (!common->endonly)    if (!common->endonly)
4425      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4426    else    else
4427      {      {
4428      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));
4429      check_partial(common, FALSE);      check_partial(common, FALSE);
4430      }      }
4431    return cc;    return cc;
# Line 3564  switch(type) Line 4434  switch(type)
4434    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4435    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4436    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));
4437    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));
4438    check_partial(common, FALSE);    check_partial(common, FALSE);
4439    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4440    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3574  switch(type) Line 4444  switch(type)
4444      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));
4445      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4446      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4447        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));
4448      else      else
4449        {        {
4450        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4451        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
4452        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));
4453        check_partial(common, TRUE);        check_partial(common, TRUE);
4454        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4455        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4456        }        }
4457    
4458      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4459      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));
4460      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));
4461      }      }
4462    else    else
4463      {      {
4464      peek_char(common);      peek_char(common);
4465      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4466      }      }
4467    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4468    return cc;    return cc;
# Line 3606  switch(type) Line 4476  switch(type)
4476    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))
4477      {      {
4478      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));
4479      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));
4480    
4481      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4482      context.sourcereg = -1;      context.sourcereg = -1;
4483  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4484      context.ucharptr = 0;      context.ucharptr = 0;
4485  #endif  #endif
4486      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4487      }      }
4488    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4489    read_char(common);    read_char(common);
4490  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4491    if (common->utf)    if (common->utf)
# Line 3627  switch(type) Line 4497  switch(type)
4497      c = *cc;      c = *cc;
4498    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4499      {      {
4500      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));
4501      return cc + length;      return cc + length;
4502      }      }
4503    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4504    bit = c ^ oc;    bit = c ^ oc;
4505    if (ispowerof2(bit))    if (is_powerof2(bit))
4506      {      {
4507      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4508      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));
4509      return cc + length;      return cc + length;
4510      }      }
4511    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);
4512    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
4513    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);
4514    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4515    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4516    return cc + length;    return cc + length;
4517    
4518    case OP_NOT:    case OP_NOT:
4519    case OP_NOTI:    case OP_NOTI:
4520    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4521    length = 1;    length = 1;
4522  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4523    if (common->utf)    if (common->utf)
# Line 3658  switch(type) Line 4528  switch(type)
4528        {        {
4529        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4530        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4531          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));
4532        else        else
4533          {          {
4534          /* 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. */
4535          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4536          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));
4537          }          }
4538        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4539        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 3688  switch(type) Line 4558  switch(type)
4558      }      }
4559    
4560    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4561      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));
4562    else    else
4563      {      {
4564      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4565      bit = c ^ oc;      bit = c ^ oc;
4566      if (ispowerof2(bit))      if (is_powerof2(bit))
4567        {        {
4568        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4569        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));
4570        }        }
4571      else      else
4572        {        {
4573        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));
4574        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));
4575        }        }
4576      }      }
4577    return cc + length;    return cc + length;
4578    
4579    case OP_CLASS:    case OP_CLASS:
4580    case OP_NCLASS:    case OP_NCLASS:
4581    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4582    read_char(common);    read_char(common);
4583      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4584        return cc + 32 / sizeof(pcre_uchar);
4585    
4586  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4587    jump[0] = NULL;    jump[0] = NULL;
4588  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3721  switch(type) Line 4594  switch(type)
4594      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4595      if (type == OP_CLASS)      if (type == OP_CLASS)
4596        {        {
4597        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4598        jump[0] = NULL;        jump[0] = NULL;
4599        }        }
4600      }      }
# Line 3731  switch(type) Line 4604  switch(type)
4604    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
4605    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4606    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);
4607    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4608  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4609    if (jump[0] != NULL)    if (jump[0] != NULL)
4610      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4611  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4612    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4613    
4614  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4615    case OP_XCLASS:    case OP_XCLASS:
4616    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4617    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4618  #endif  #endif
4619    
4620    case OP_REVERSE:    case OP_REVERSE:
4621    length = GET(cc, 0);    length = GET(cc, 0);
4622    SLJIT_ASSERT(length > 0);    if (length == 0)
4623        return cc + LINK_SIZE;
4624    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4625  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4626    if (common->utf)    if (common->utf)
# Line 3754  switch(type) Line 4628  switch(type)
4628      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));
4629      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4630      label = LABEL();      label = LABEL();
4631      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));
4632      skip_char_back(common);      skip_char_back(common);
4633      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);
4634      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3764  switch(type) Line 4638  switch(type)
4638      {      {
4639      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));
4640      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));
4641      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));
4642      }      }
4643    check_start_used_ptr(common);    check_start_used_ptr(common);
4644    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3773  SLJIT_ASSERT_STOP(); Line 4647  SLJIT_ASSERT_STOP();
4647  return cc;  return cc;
4648  }  }
4649    
4650  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)
4651  {  {
4652  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4653  /* 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 3825  if (context.length > 0) Line 4699  if (context.length > 0)
4699    {    {
4700    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4701    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);
4702    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));
4703    
4704    context.sourcereg = -1;    context.sourcereg = -1;
4705  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4706    context.ucharptr = 0;    context.ucharptr = 0;
4707  #endif  #endif
4708    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);
4709    return cc;    return cc;
4710    }    }
4711    
4712  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4713  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4714  }  }
4715    
4716  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)
4717  {  {
4718  DEFINE_COMPILER;  DEFINE_COMPILER;
4719  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3847  int offset = GET2(cc, 1) << 1; Line 4721  int offset = GET2(cc, 1) << 1;
4721  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4722  if (!common->jscript_compat)  if (!common->jscript_compat)
4723    {    {
4724    if (fallbacks == NULL)    if (backtracks == NULL)
4725      {      {
4726      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4727      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 3856  if (!common->jscript_compat) Line 4730  if (!common->jscript_compat)
4730      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
4731      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4732      }      }
4733    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)));
4734    }    }
4735  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));
4736  }  }
4737    
4738  /* Forward definitions. */  /* Forward definitions. */
4739  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4740  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4741    
4742  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4743    do \    do \
4744      { \      { \
4745      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4746      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4747        return error; \        return error; \
4748      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4749      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4750      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4751      parent->top = fallback; \      parent->top = backtrack; \
4752      } \      } \
4753    while (0)    while (0)
4754    
4755  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4756    do \    do \
4757      { \      { \
4758      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4759      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4760        return; \        return; \
4761      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4762      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4763      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4764      parent->top = fallback; \      parent->top = backtrack; \
4765      } \      } \
4766    while (0)    while (0)
4767    
4768  #define FALLBACK_AS(type) ((type *)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
4769    
4770  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)
4771  {  {
4772  DEFINE_COMPILER;  DEFINE_COMPILER;
4773  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3904  struct sljit_jump *nopartial; Line 4778  struct sljit_jump *nopartial;
4778  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4779  /* OVECTOR(1) contains the "string begin - 1" constant. */  /* OVECTOR(1) contains the "string begin - 1" constant. */
4780  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
4781    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)));
4782    
4783  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
4784  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
# Line 3921  if (common->utf && *cc == OP_REFI) Line 4795  if (common->utf && *cc == OP_REFI)
4795    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));
4796    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4797    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4798      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));
4799    else    else
4800      {      {
4801      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));
4802      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);
4803      check_partial(common, FALSE);      check_partial(common, FALSE);
4804      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4805      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4806      }      }
4807    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
# Line 3942  else Line 4816  else
4816    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
4817    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);    partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
4818    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
4819      add_jump(compiler, fallbacks, partial);      add_jump(compiler, backtracks, partial);
4820    
4821    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));
4822    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));
4823    
4824    if (common->mode != JIT_COMPILE)    if (common->mode != JIT_COMPILE)
4825      {      {
# Line 3957  else Line 4831  else
4831      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);      partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
4832      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);      OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
4833      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));
4834      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));
4835      JUMPHERE(partial);      JUMPHERE(partial);
4836      check_partial(common, FALSE);      check_partial(common, FALSE);
4837      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4838      JUMPHERE(nopartial);      JUMPHERE(nopartial);
4839      }      }
4840    }    }
# Line 3968  else Line 4842  else
4842  if (jump != NULL)  if (jump != NULL)
4843    {    {
4844    if (emptyfail)    if (emptyfail)
4845      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
4846    else    else
4847      JUMPHERE(jump);      JUMPHERE(jump);
4848    }    }
4849  return cc + 1 + IMM2_SIZE;  return cc + 1 + IMM2_SIZE;
4850  }  }
4851    
4852  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)
4853  {  {
4854  DEFINE_COMPILER;  DEFINE_COMPILER;
4855  fallback_common *fallback;  backtrack_common *backtrack;
4856  pcre_uchar type;  pcre_uchar type;
4857  struct sljit_label *label;  struct sljit_label *label;
4858  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
# Line 3987  pcre_uchar *ccbegin = cc; Line 4861  pcre_uchar *ccbegin = cc;
4861  int min = 0, max = 0;  int min = 0, max = 0;
4862  BOOL minimize;  BOOL minimize;
4863    
4864  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
4865    
4866  type = cc[1 + IMM2_SIZE];  type = cc[1 + IMM2_SIZE];
4867  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
# Line 4039  if (!minimize) Line 4913  if (!minimize)
4913      {      {
4914      allocate_stack(common, 1);      allocate_stack(common, 1);
4915      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4916      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4917      }      }
4918    
4919    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4920      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4921    
4922    label = LABEL();    label = LABEL();
4923    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4924    
4925    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4926      {      {
# Line 4074  if (!minimize) Line 4948  if (!minimize)
4948      }      }
4949    
4950    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4951    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4952    
4953    decrease_call_count(common);    decrease_call_count(common);
4954    return cc;    return cc;
# Line 4092  if (min == 0) Line 4966  if (min == 0)
4966    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4967    }    }
4968  else  else
4969    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4970    
4971  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->matchingpath = LABEL();
4972  if (max > 0)  if (max > 0)
4973    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));
4974    
4975  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_matchingpath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4976  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4977    
4978  if (min > 1)  if (min > 1)
# Line 4106  if (min > 1) Line 4980  if (min > 1)
4980    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4981    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4982    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4983    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);
4984    }    }
4985  else if (max > 0)  else if (max > 0)
4986    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 4119  decrease_call_count(common); Line 4993  decrease_call_count(common);
4993  return cc;  return cc;
4994  }  }
4995    
4996  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)
4997  {  {
4998  DEFINE_COMPILER;  DEFINE_COMPILER;
4999  fallback_common *fallback;  backtrack_common *backtrack;
5000  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5001  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5002  int start = GET(cc, 1);  int start = GET(cc, 1);
5003    
5004  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5005  while (entry != NULL)  while (entry != NULL)
5006    {    {
5007    if (entry->start == start)    if (entry->start == start)
# Line 4172  if (entry->entry == NULL) Line 5046  if (entry->entry == NULL)
5046  else  else
5047    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
5048  /* Leave if the match is failed. */  /* Leave if the match is failed. */
5049  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));
5050  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5051  }  }
5052    
5053  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)
5054  {  {
5055  DEFINE_COMPILER;  DEFINE_COMPILER;
5056  int framesize;  int framesize;
5057  int localptr;  int private_data_ptr;
5058  fallback_common altfallback;  backtrack_common altbacktrack;
5059  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5060  pcre_uchar opcode;  pcre_uchar opcode;
5061  pcre_uchar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5062  jump_list *tmp = NULL;  jump_list *tmp = NULL;
5063  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5064  jump_list **found;  jump_list **found;
5065  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5066  struct sljit_label *save_leavelabel = common->leavelabel;  struct sljit_label *save_quitlabel = common->quitlabel;
5067  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
5068  jump_list *save_leave = common->leave;  jump_list *save_quit = common->quit;
5069  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5070  struct sljit_jump *jump;  struct sljit_jump *jump;
5071  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
# Line 4202  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5076  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5076    bra = *cc;    bra = *cc;
5077    cc++;    cc++;
5078    }    }
5079  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5080  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5081  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
5082  fallback->framesize = framesize;  backtrack->framesize = framesize;
5083  fallback->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5084  opcode = *cc;  opcode = *cc;
5085  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5086  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4215  cc += GET(cc, 1); Line 5089  cc += GET(cc, 1);
5089    
5090  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5091    {    {
5092    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
5093    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5094    free_stack(common, 1);    free_stack(common, 1);
5095    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 4223  if (bra == OP_BRAMINZERO) Line 5097  if (bra == OP_BRAMINZERO)
5097    
5098  if (framesize < 0)  if (framesize < 0)
5099    {    {
5100    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);
5101    allocate_stack(common, 1);    allocate_stack(common, 1);
5102    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5103    }    }
5104  else  else
5105    {    {
5106    allocate_stack(common, framesize + 2);    allocate_stack(common, framesize + 2);
5107    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5108    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));
5109    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5110    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5111    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5112    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
5113    }    }
5114    
5115  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5116  common->leavelabel = NULL;  common->quitlabel = NULL;
5117  common->leave = NULL;  common->quit = NULL;
5118  while (1)  while (1)
5119    {    {
5120    common->acceptlabel = NULL;    common->acceptlabel = NULL;
5121    common->accept = NULL;    common->accept = NULL;
5122    altfallback.top = NULL;    altbacktrack.top = NULL;
5123    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
5124    
5125    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
5126      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5127    
5128    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
5129    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5130    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5131      {      {
5132      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5133      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5134      common->leave = save_leave;      common->quit = save_quit;
5135      common->accept = save_accept;      common->accept = save_accept;
5136      return NULL;      return NULL;
5137      }      }
# Line 4267  while (1) Line 5141  while (1)
5141    
5142    /* Reset stack. */    /* Reset stack. */
5143    if (framesize < 0)    if (framesize < 0)
5144      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);
5145    else {    else {
5146      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5147        {        {
5148        /* 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. */
5149        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));
5150        }        }
5151      else      else
5152        {        {
5153        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);
5154        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5155        }        }
5156    }    }
# Line 4294  while (1) Line 5168  while (1)
5168          {          {
5169          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));
5170          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));
5171          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5172          }          }
5173        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));
5174        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 4302  while (1) Line 5176  while (1)
5176      else if (framesize >= 0)      else if (framesize >= 0)
5177        {        {
5178        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5179        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));
5180        }        }
5181      }      }
5182    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
5183    
5184    compile_fallbackpath(common, altfallback.top);    compile_backtrackingpath(common, altbacktrack.top);
5185    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5186      {      {
5187      common->leavelabel = save_leavelabel;      common->quitlabel = save_quitlabel;
5188      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save_acceptlabel;
5189      common->leave = save_leave;      common->quit = save_quit;
5190      common->accept = save_accept;      common->accept = save_accept;
5191      return NULL;      return NULL;
5192      }      }
5193    set_jumps(altfallback.topfallbacks, LABEL());    set_jumps(altbacktrack.topbacktracks, LABEL());
5194    
5195    if (*cc != OP_ALT)    if (*cc != OP_ALT)
5196      break;      break;
# Line 4325  while (1) Line 5199  while (1)
5199    cc += GET(cc, 1);    cc += GET(cc, 1);
5200    }    }
5201  /* None of them matched. */  /* None of them matched. */
5202  if (common->leave != NULL)  if (common->quit != NULL)
5203    set_jumps(common->leave, LABEL());    set_jumps(common->quit, LABEL());
5204    
5205  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5206    {    {
# Line 4353  if (opcode == OP_ASSERT || opcode == OP_ Line 5227  if (opcode == OP_ASSERT || opcode == OP_
5227        }        }
5228      else      else
5229        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5230      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5231      }      }
5232    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
5233    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 4378  if (opcode == OP_ASSERT || opcode == OP_ Line 5252  if (opcode == OP_ASSERT || opcode == OP_
5252      {      {
5253      if (bra == OP_BRA)      if (bra == OP_BRA)
5254        {        {
5255        /* 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. */
5256        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));
5257        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5258        }        }
5259      else      else
5260        {        {
5261        /* 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. */
5262        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));
5263        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5264        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);
5265        }        }
# Line 4393  if (opcode == OP_ASSERT || opcode == OP_ Line 5267  if (opcode == OP_ASSERT || opcode == OP_
5267    
5268    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5269      {      {
5270      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5271      sljit_set_label(jump, fallback->hotpath);      sljit_set_label(jump, backtrack->matchingpath);
5272      }      }
5273    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5274      {      {
5275      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5276      JUMPHERE(brajump);      JUMPHERE(brajump);
5277      if (framesize >= 0)      if (framesize >= 0)
5278        {        {
5279        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);
5280        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5281        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));
5282        }        }
5283      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5284      }      }
5285    }    }
5286  else  else
# Line 4432  else Line 5306  else
5306        }        }
5307      else      else
5308        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
5309      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5310      }      }
5311    
5312    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5313      fallback->hotpath = LABEL();      backtrack->matchingpath = LABEL();
5314    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5315      {      {
5316      JUMPTO(SLJIT_JUMP, fallback->hotpath);      JUMPTO(SLJIT_JUMP, backtrack->matchingpath);
5317      JUMPHERE(brajump);      JUMPHERE(brajump);
5318      }      }
5319    
5320    if (bra != OP_BRA)    if (bra != OP_BRA)
5321      {      {
5322      SLJIT_ASSERT(found == &fallback->common.topfallbacks);      SLJIT_ASSERT(found == &backtrack->common.topbacktracks);
5323      set_jumps(fallback->common.topfallbacks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5324      fallback->common.topfallbacks = NULL;      backtrack->common.topbacktracks = NULL;
5325      }      }
5326    }    }
5327    
5328  common->leavelabel = save_leavelabel;  common->quitlabel = save_quitlabel;
5329  common->acceptlabel = save_acceptlabel;  common->acceptlabel = save_acceptlabel;
5330  common->leave = save_leave;  common->quit = save_quit;
5331  common->accept = save_accept;  common->accept = save_accept;