/[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 958 by zherczeg, Wed Apr 11 10:19:10 2012 UTC revision 1242 by zherczeg, Sat Jan 26 17:51:43 2013 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 167  typedef struct executable_functions { Line 170  typedef struct executable_functions {
170    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
171    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
172    void *userdata;    void *userdata;
173      pcre_uint32 top_bracket;
174    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
175  } executable_functions;  } executable_functions;
176    
# Line 181  typedef struct stub_list { Line 185  typedef struct stub_list {
185    enum stub_types type;    enum stub_types type;
186    int data;    int data;
187    struct sljit_jump *start;    struct sljit_jump *start;
188    struct sljit_label *leave;    struct sljit_label *quit;
189    struct stub_list *next;    struct stub_list *next;
190  } stub_list;  } stub_list;
191    
192  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
193    
194  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
195  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
196  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
197  of its descendants. */  of its descendants. */
198  typedef struct fallback_common {  typedef struct backtrack_common {
199    /* Concatenation stack. */    /* Concatenation stack. */
200    struct fallback_common *prev;    struct backtrack_common *prev;
201    jump_list *nextfallbacks;    jump_list *nextbacktracks;
202    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
203    struct fallback_common *top;    struct backtrack_common *top;
204    jump_list *topfallbacks;    jump_list *topbacktracks;
205    /* Opcode pointer. */    /* Opcode pointer. */
206    pcre_uchar *cc;    pcre_uchar *cc;
207  } fallback_common;  } backtrack_common;
208    
209  typedef struct assert_fallback {  typedef struct assert_backtrack {
210    fallback_common common;    backtrack_common common;
211    jump_list *condfailed;    jump_list *condfailed;
212    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
213    int framesize;    int framesize;
214    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
215    int localptr;    int private_data_ptr;
216    /* For iterators. */    /* For iterators. */
217    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
218  } assert_fallback;  } assert_backtrack;
219    
220  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
221    fallback_common common;    backtrack_common common;
222    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
223    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
224    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
225    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
226    /* For greedy ? operator. */    /* For greedy ? operator. */
227    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
228    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
229    union {    union {
230      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
231      jump_list *condfailed;      jump_list *condfailed;
232      assert_fallback *assert;      assert_backtrack *assert;
233      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
234      int framesize;      int framesize;
235    } u;    } u;
236    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
237    int localptr;    int private_data_ptr;
238  } bracket_fallback;  } bracket_backtrack;
239    
240  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
241    fallback_common common;    backtrack_common common;
242    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
243    int localptr;    int private_data_ptr;
244    /* Reverting stack is needed. */    /* Reverting stack is needed. */
245    int framesize;    int framesize;
246    /* Allocated stack size. */    /* Allocated stack size. */
247    int stacksize;    int stacksize;
248  } bracketpos_fallback;  } bracketpos_backtrack;
249    
250  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
251    fallback_common common;    backtrack_common common;
252    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
253  } braminzero_fallback;  } braminzero_backtrack;
254    
255  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
256    fallback_common common;    backtrack_common common;
257    /* Next iteration. */    /* Next iteration. */
258    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
259  } iterator_fallback;  } iterator_backtrack;
260    
261  typedef struct recurse_entry {  typedef struct recurse_entry {
262    struct recurse_entry *next;    struct recurse_entry *next;
# Line 264  typedef struct recurse_entry { Line 268  typedef struct recurse_entry {
268    int start;    int start;
269  } recurse_entry;  } recurse_entry;
270    
271  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
272    fallback_common common;    backtrack_common common;
273  } recurse_fallback;  } recurse_backtrack;
274    
275    #define MAX_RANGE_SIZE 6
276    
277  typedef struct compiler_common {  typedef struct compiler_common {
278    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
279    pcre_uchar *start;    pcre_uchar *start;
280    
281    /* Opcode local area direct map. */    /* Maps private data offset to each opcode. */
282    int *localptrs;    int *private_data_ptrs;
283      /* Tells whether the capturing bracket is optimized. */
284      pcre_uint8 *optimized_cbracket;
285      /* Starting offset of private data for capturing brackets. */
286    int cbraptr;    int cbraptr;
287    /* OVector starting point. Must be divisible by 2. */    /* OVector starting point. Must be divisible by 2. */
288    int ovector_start;    int ovector_start;
# Line 290  typedef struct compiler_common { Line 299  typedef struct compiler_common {
299    /* Points to the marked string. */    /* Points to the marked string. */
300    int mark_ptr;    int mark_ptr;
301    
302    /* Other  */    /* Flipped and lower case tables. */
303    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
304    sljit_w lcc;    sljit_sw lcc;
305      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
306    int mode;    int mode;
307      /* Newline control. */
308    int nltype;    int nltype;
309    int newline;    int newline;
310    int bsr_nltype;    int bsr_nltype;
311      /* Dollar endonly. */
312    int endonly;    int endonly;
313    BOOL has_set_som;    BOOL has_set_som;
314    sljit_w ctypes;    /* Tables. */
315      sljit_sw ctypes;
316      int digits[2 + MAX_RANGE_SIZE];
317      /* Named capturing brackets. */
318    sljit_uw name_table;    sljit_uw name_table;
319    sljit_w name_count;    sljit_sw name_count;
320    sljit_w name_entry_size;    sljit_sw name_entry_size;
321    
322    /* Labels and jump lists. */    /* Labels and jump lists. */
323    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
324    struct sljit_label *leavelabel;    struct sljit_label *quitlabel;
325    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
326    stub_list *stubs;    stub_list *stubs;
327    recurse_entry *entries;    recurse_entry *entries;
328    recurse_entry *currententry;    recurse_entry *currententry;
329    jump_list *partialmatch;    jump_list *partialmatch;
330    jump_list *leave;    jump_list *quit;
331    jump_list *accept;    jump_list *accept;
332    jump_list *calllimit;    jump_list *calllimit;
333    jump_list *stackalloc;    jump_list *stackalloc;
# Line 329  typedef struct compiler_common { Line 344  typedef struct compiler_common {
344  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
345    BOOL use_ucp;    BOOL use_ucp;
346  #endif  #endif
347    #ifndef COMPILE_PCRE32
348    jump_list *utfreadchar;    jump_list *utfreadchar;
349    #endif
350  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
351    jump_list *utfreadtype8;    jump_list *utfreadtype8;
352  #endif  #endif
# Line 347  typedef struct compare_context { Line 364  typedef struct compare_context {
364  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
365    int ucharptr;    int ucharptr;
366    union {    union {
367      sljit_i asint;      sljit_si asint;
368      sljit_uh asushort;      sljit_uh asushort;
369  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
370      sljit_ub asbyte;      sljit_ub asbyte;
371      sljit_ub asuchars[4];      sljit_ub asuchars[4];
372  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
373      sljit_uh asuchars[2];      sljit_uh asuchars[2];
374  #endif  #elif defined COMPILE_PCRE32
375        sljit_ui asuchars[1];
376  #endif  #endif
377    } c;    } c;
378    union {    union {
379      sljit_i asint;      sljit_si asint;
380      sljit_uh asushort;      sljit_uh asushort;
381  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
382      sljit_ub asbyte;      sljit_ub asbyte;
383      sljit_ub asuchars[4];      sljit_ub asuchars[4];
384  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
385      sljit_uh asuchars[2];      sljit_uh asuchars[2];
386  #endif  #elif defined COMPILE_PCRE32
387        sljit_ui asuchars[1];
388  #endif  #endif
389    } oc;    } oc;
390  #endif  #endif
# Line 383  enum { Line 400  enum {
400  #undef CMP  #undef CMP
401    
402  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
403  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
404    
405  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
406  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
407  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
408  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_SAVED_REG1
409  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_SAVED_REG2
410  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
411  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
412  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
413  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
414  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
415    
416  /* Locals layout. */  /* Local space layout. */
417  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
418  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
419  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
420  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
421  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
422  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
423  /* Max limit of recursions. */  /* Max limit of recursions. */
424  #define CALL_LIMIT       (4 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
425  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
426  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
427  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
428  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
429  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
430  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
431  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))
432  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
433    
434  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
435  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
436  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
437  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
438  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
439  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
440    #elif defined COMPILE_PCRE32
441    #define MOV_UCHAR  SLJIT_MOV_UI
442    #define MOVU_UCHAR SLJIT_MOVU_UI
443  #else  #else
444  #error Unsupported compiling mode  #error Unsupported compiling mode
445  #endif  #endif
 #endif  
446    
447  /* Shortcuts. */  /* Shortcuts. */
448  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 445  the start pointers when the end of the c Line 463  the start pointers when the end of the c
463    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
464  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
465    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))
466  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
467    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
468  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
469    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
470    
# Line 461  return cc; Line 479  return cc;
479    
480  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
481   next_opcode   next_opcode
482   get_localspace   get_private_data_length
483   set_localptrs   set_private_data_ptrs
484   get_framesize   get_framesize
485   init_frame   init_frame
486   get_localsize   get_private_data_length_for_copy
487   copy_locals   copy_private_data
488   compile_hotpath   compile_matchingpath
489   compile_fallbackpath   compile_backtrackingpath
490  */  */
491    
492  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 667  switch(*cc) Line 685  switch(*cc)
685    }    }
686  }  }
687    
688  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
689        case OP_MINSTAR: \
690        case OP_MINPLUS: \
691        case OP_QUERY: \
692        case OP_MINQUERY: \
693        case OP_MINSTARI: \
694        case OP_MINPLUSI: \
695        case OP_QUERYI: \
696        case OP_MINQUERYI: \
697        case OP_NOTMINSTAR: \
698        case OP_NOTMINPLUS: \
699        case OP_NOTQUERY: \
700        case OP_NOTMINQUERY: \
701        case OP_NOTMINSTARI: \
702        case OP_NOTMINPLUSI: \
703        case OP_NOTQUERYI: \
704        case OP_NOTMINQUERYI:
705    
706    #define CASE_ITERATOR_PRIVATE_DATA_2A \
707        case OP_STAR: \
708        case OP_PLUS: \
709        case OP_STARI: \
710        case OP_PLUSI: \
711        case OP_NOTSTAR: \
712        case OP_NOTPLUS: \
713        case OP_NOTSTARI: \
714        case OP_NOTPLUSI:
715    
716    #define CASE_ITERATOR_PRIVATE_DATA_2B \
717        case OP_UPTO: \
718        case OP_MINUPTO: \
719        case OP_UPTOI: \
720        case OP_MINUPTOI: \
721        case OP_NOTUPTO: \
722        case OP_NOTMINUPTO: \
723        case OP_NOTUPTOI: \
724        case OP_NOTMINUPTOI:
725    
726    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
727        case OP_TYPEMINSTAR: \
728        case OP_TYPEMINPLUS: \
729        case OP_TYPEQUERY: \
730        case OP_TYPEMINQUERY:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
733        case OP_TYPESTAR: \
734        case OP_TYPEPLUS:
735    
736    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
737        case OP_TYPEUPTO: \
738        case OP_TYPEMINUPTO:
739    
740    static int get_class_iterator_size(pcre_uchar *cc)
741  {  {
742  int localspace = 0;  switch(*cc)
743      {
744      case OP_CRSTAR:
745      case OP_CRPLUS:
746      return 2;
747    
748      case OP_CRMINSTAR:
749      case OP_CRMINPLUS:
750      case OP_CRQUERY:
751      case OP_CRMINQUERY:
752      return 1;
753    
754      case OP_CRRANGE:
755      case OP_CRMINRANGE:
756      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
757        return 0;
758      return 2;
759    
760      default:
761      return 0;
762      }
763    }
764    
765    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
766    {
767    int private_data_length = 0;
768  pcre_uchar *alternative;  pcre_uchar *alternative;
769    pcre_uchar *name;
770    pcre_uchar *end = NULL;
771    int space, size, i;
772    pcre_uint32 bracketlen;
773    
774  /* 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. */
775  while (cc < ccend)  while (cc < ccend)
776    {    {
777      space = 0;
778      size = 0;
779      bracketlen = 0;
780    switch(*cc)    switch(*cc)
781      {      {
782      case OP_SET_SOM:      case OP_SET_SOM:
# Line 681  while (cc < ccend) Line 784  while (cc < ccend)
784      cc += 1;      cc += 1;
785      break;      break;
786    
787        case OP_REF:
788        case OP_REFI:
789        common->optimized_cbracket[GET2(cc, 1)] = 0;
790        cc += 1 + IMM2_SIZE;
791        break;
792    
793      case OP_ASSERT:      case OP_ASSERT:
794      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
795      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 690  while (cc < ccend) Line 799  while (cc < ccend)
799      case OP_BRAPOS:      case OP_BRAPOS:
800      case OP_SBRA:      case OP_SBRA:
801      case OP_SBRAPOS:      case OP_SBRAPOS:
802      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
803      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
804      break;      break;
805    
806      case OP_CBRAPOS:      case OP_CBRAPOS:
807      case OP_SCBRAPOS:      case OP_SCBRAPOS:
808      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
809      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
810        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
811      break;      break;
812    
813      case OP_COND:      case OP_COND:
814      /* Might be a hidden SCOND. */      case OP_SCOND:
815      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
816      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
817        localspace += sizeof(sljit_w);        {
818      cc += 1 + LINK_SIZE;        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          common->optimized_cbracket[bracketlen] = 0;
820          }
821        else if (bracketlen == OP_NCREF)
822          {
823          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
824          name = (pcre_uchar *)common->name_table;
825          alternative = name;
826          for (i = 0; i < common->name_count; i++)
827            {
828            if (GET2(name, 0) == bracketlen) break;
829            name += common->name_entry_size;
830            }
831          SLJIT_ASSERT(i != common->name_count);
832    
833          for (i = 0; i < common->name_count; i++)
834            {
835            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
836              common->optimized_cbracket[GET2(alternative, 0)] = 0;
837            alternative += common->name_entry_size;
838            }
839          }
840    
841        if (*cc == OP_COND)
842          {
843          /* Might be a hidden SCOND. */
844          alternative = cc + GET(cc, 1);
845          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
846            private_data_length += sizeof(sljit_sw);
847          }
848        else
849          private_data_length += sizeof(sljit_sw);
850        bracketlen = 1 + LINK_SIZE;
851        break;
852    
853        case OP_BRA:
854        bracketlen = 1 + LINK_SIZE;
855        break;
856    
857        case OP_CBRA:
858        case OP_SCBRA:
859        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_1
863        space = 1;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2A
868        space = 2;
869        size = -2;
870        break;
871    
872        CASE_ITERATOR_PRIVATE_DATA_2B
873        space = 2;
874        size = -(2 + IMM2_SIZE);
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
878        space = 1;
879        size = 1;
880        break;
881    
882        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
883        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
884          space = 2;
885        size = 1;
886        break;
887    
888        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
889        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
890          space = 2;
891        size = 1 + IMM2_SIZE;
892        break;
893    
894        case OP_CLASS:
895        case OP_NCLASS:
896        size += 1 + 32 / sizeof(pcre_uchar);
897        space = get_class_iterator_size(cc + size);
898        break;
899    
900    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
901        case OP_XCLASS:
902        size = GET(cc, 1);
903        space = get_class_iterator_size(cc + size);
904      break;      break;
905    #endif
906    
907      case OP_RECURSE:      case OP_RECURSE:
908      /* Set its value only once. */      /* Set its value only once. */
909      if (common->recursive_head == 0)      if (common->recursive_head == 0)
910        {        {
911        common->recursive_head = common->ovector_start;        common->recursive_head = common->ovector_start;
912        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
913        }        }
914      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
915      break;      break;
# Line 723  while (cc < ccend) Line 918  while (cc < ccend)
918      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
919        {        {
920        common->mark_ptr = common->ovector_start;        common->mark_ptr = common->ovector_start;
921        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
922        }        }
923      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
924      break;      break;
# Line 734  while (cc < ccend) Line 929  while (cc < ccend)
929        return -1;        return -1;
930      break;      break;
931      }      }
932    
933      if (space > 0 && cc >= end)
934        private_data_length += sizeof(sljit_sw) * space;
935    
936      if (size != 0)
937        {
938        if (size < 0)
939          {
940          cc += -size;
941    #ifdef SUPPORT_UTF
942          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
943    #endif
944          }
945        else
946          cc += size;
947        }
948    
949      if (bracketlen != 0)
950        {
951        if (cc >= end)
952          {
953          end = bracketend(cc);
954          if (end[-1 - LINK_SIZE] == OP_KET)
955            end = NULL;
956          }
957        cc += bracketlen;
958        }
959    }    }
960  return localspace;  return private_data_length;
961  }  }
962    
963  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)
964  {  {
965  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
966  pcre_uchar *alternative;  pcre_uchar *alternative;
967    pcre_uchar *end = NULL;
968    int space, size, bracketlen;
969    
970  while (cc < ccend)  while (cc < ccend)
971    {    {
972      space = 0;
973      size = 0;
974      bracketlen = 0;
975    switch(*cc)    switch(*cc)
976      {      {
977      case OP_ASSERT:      case OP_ASSERT:
# Line 756  while (cc < ccend) Line 984  while (cc < ccend)
984      case OP_SBRA:      case OP_SBRA:
985      case OP_SBRAPOS:      case OP_SBRAPOS:
986      case OP_SCOND:      case OP_SCOND:
987      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
988      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
989      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
990      break;      break;
991    
992      case OP_CBRAPOS:      case OP_CBRAPOS:
993      case OP_SCBRAPOS:      case OP_SCBRAPOS:
994      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
995      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
996      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
997      break;      break;
998    
999      case OP_COND:      case OP_COND:
# Line 773  while (cc < ccend) Line 1001  while (cc < ccend)
1001      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1002      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1003        {        {
1004        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1005        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1006        }        }
1007      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1008        break;
1009    
1010        case OP_BRA:
1011        bracketlen = 1 + LINK_SIZE;
1012        break;
1013    
1014        case OP_CBRA:
1015        case OP_SCBRA:
1016        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1017        break;
1018    
1019        CASE_ITERATOR_PRIVATE_DATA_1
1020        space = 1;
1021        size = -2;
1022        break;
1023    
1024        CASE_ITERATOR_PRIVATE_DATA_2A
1025        space = 2;
1026        size = -2;
1027        break;
1028    
1029        CASE_ITERATOR_PRIVATE_DATA_2B
1030        space = 2;
1031        size = -(2 + IMM2_SIZE);
1032        break;
1033    
1034        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1035        space = 1;
1036        size = 1;
1037        break;
1038    
1039        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1040        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1041          space = 2;
1042        size = 1;
1043        break;
1044    
1045        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1046        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1047          space = 2;
1048        size = 1 + IMM2_SIZE;
1049        break;
1050    
1051        case OP_CLASS:
1052        case OP_NCLASS:
1053        size += 1 + 32 / sizeof(pcre_uchar);
1054        space = get_class_iterator_size(cc + size);
1055        break;
1056    
1057    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1058        case OP_XCLASS:
1059        size = GET(cc, 1);
1060        space = get_class_iterator_size(cc + size);
1061      break;      break;
1062    #endif
1063    
1064      default:      default:
1065      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1066      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1067      break;      break;
1068      }      }
1069    
1070      if (space > 0 && cc >= end)
1071        {
1072        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1073        private_data_ptr += sizeof(sljit_sw) * space;
1074        }
1075    
1076      if (size != 0)
1077        {
1078        if (size < 0)
1079          {
1080          cc += -size;
1081    #ifdef SUPPORT_UTF
1082          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1083    #endif
1084          }
1085        else
1086          cc += size;
1087        }
1088    
1089      if (bracketlen > 0)
1090        {
1091        if (cc >= end)
1092          {
1093          end = bracketend(cc);
1094          if (end[-1 - LINK_SIZE] == OP_KET)
1095            end = NULL;
1096          }
1097        cc += bracketlen;
1098        }
1099    }    }
1100  }  }
1101    
# Line 889  while (cc < ccend) Line 1201  while (cc < ccend)
1201        {        {
1202        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1203        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1204        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1205        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1206        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1207        setsom_found = TRUE;        setsom_found = TRUE;
1208        }        }
1209      cc += 1;      cc += 1;
# Line 903  while (cc < ccend) Line 1215  while (cc < ccend)
1215        {        {
1216        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1217        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1218        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1219        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1220        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1221        setmark_found = TRUE;        setmark_found = TRUE;
1222        }        }
1223      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
# Line 916  while (cc < ccend) Line 1228  while (cc < ccend)
1228        {        {
1229        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1230        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1231        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1232        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1233        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1234        setsom_found = TRUE;        setsom_found = TRUE;
1235        }        }
1236      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1237        {        {
1238        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1239        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1240        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1241        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1242        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1243        setmark_found = TRUE;        setmark_found = TRUE;
1244        }        }
1245      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
# Line 939  while (cc < ccend) Line 1251  while (cc < ccend)
1251      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1252      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1253      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1254      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1255      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1256      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
1257      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1258      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1259      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1260      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1261    
1262      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1263      break;      break;
# Line 960  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1272  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1272  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1273  }  }
1274    
1275  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)
1276  {  {
1277  int localsize = 2;  int private_data_length = 2;
1278    int size;
1279  pcre_uchar *alternative;  pcre_uchar *alternative;
1280  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1281  while (cc < ccend)  while (cc < ccend)
1282    {    {
1283      size = 0;
1284    switch(*cc)    switch(*cc)
1285      {      {
1286      case OP_ASSERT:      case OP_ASSERT:
# Line 979  while (cc < ccend) Line 1293  while (cc < ccend)
1293      case OP_SBRA:      case OP_SBRA:
1294      case OP_SBRAPOS:      case OP_SBRAPOS:
1295      case OP_SCOND:      case OP_SCOND:
1296      localsize++;      private_data_length++;
1297      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1298      break;      break;
1299    
1300      case OP_CBRA:      case OP_CBRA:
1301      case OP_SCBRA:      case OP_SCBRA:
1302      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1303          private_data_length++;
1304      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1305      break;      break;
1306    
1307      case OP_CBRAPOS:      case OP_CBRAPOS:
1308      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1309      localsize += 2;      private_data_length += 2;
1310      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1311      break;      break;
1312    
# Line 999  while (cc < ccend) Line 1314  while (cc < ccend)
1314      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1315      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1316      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1317        localsize++;        private_data_length++;
1318      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1319      break;      break;
1320    
1321        CASE_ITERATOR_PRIVATE_DATA_1
1322        if (PRIVATE_DATA(cc))
1323          private_data_length++;
1324        cc += 2;
1325    #ifdef SUPPORT_UTF
1326        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1327    #endif
1328        break;
1329    
1330        CASE_ITERATOR_PRIVATE_DATA_2A
1331        if (PRIVATE_DATA(cc))
1332          private_data_length += 2;
1333        cc += 2;
1334    #ifdef SUPPORT_UTF
1335        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1336    #endif
1337        break;
1338    
1339        CASE_ITERATOR_PRIVATE_DATA_2B
1340        if (PRIVATE_DATA(cc))
1341          private_data_length += 2;
1342        cc += 2 + IMM2_SIZE;
1343    #ifdef SUPPORT_UTF
1344        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1345    #endif
1346        break;
1347    
1348        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1349        if (PRIVATE_DATA(cc))
1350          private_data_length++;
1351        cc += 1;
1352        break;
1353    
1354        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1355        if (PRIVATE_DATA(cc))
1356          private_data_length += 2;
1357        cc += 1;
1358        break;
1359    
1360        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1361        if (PRIVATE_DATA(cc))
1362          private_data_length += 2;
1363        cc += 1 + IMM2_SIZE;
1364        break;
1365    
1366        case OP_CLASS:
1367        case OP_NCLASS:
1368    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1369        case OP_XCLASS:
1370        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1371    #else
1372        size = 1 + 32 / (int)sizeof(pcre_uchar);
1373    #endif
1374        if (PRIVATE_DATA(cc))
1375          private_data_length += get_class_iterator_size(cc + size);
1376        cc += size;
1377        break;
1378    
1379      default:      default:
1380      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1381      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1010  while (cc < ccend) Line 1383  while (cc < ccend)
1383      }      }
1384    }    }
1385  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1386  return localsize;  return private_data_length;
1387  }  }
1388    
1389  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,
1390    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1391  {  {
1392  DEFINE_COMPILER;  DEFINE_COMPILER;
1393  int srcw[2];  int srcw[2];
1394  int count;  int count, size;
1395  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1396  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1397  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1035  stacktop = STACK(stacktop - 1); Line 1408  stacktop = STACK(stacktop - 1);
1408    
1409  if (!save)  if (!save)
1410    {    {
1411    stackptr += sizeof(sljit_w);    stackptr += sizeof(sljit_sw);
1412    if (stackptr < stacktop)    if (stackptr < stacktop)
1413      {      {
1414      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1415      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1416      tmp1empty = FALSE;      tmp1empty = FALSE;
1417      }      }
1418    if (stackptr < stacktop)    if (stackptr < stacktop)
1419      {      {
1420      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1421      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1422      tmp2empty = FALSE;      tmp2empty = FALSE;
1423      }      }
1424    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
# Line 1083  while (status != end) Line 1456  while (status != end)
1456        case OP_SBRAPOS:        case OP_SBRAPOS:
1457        case OP_SCOND:        case OP_SCOND:
1458        count = 1;        count = 1;
1459        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1460        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1461        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1462        break;        break;
1463    
1464        case OP_CBRA:        case OP_CBRA:
1465        case OP_SCBRA:        case OP_SCBRA:
1466        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1467        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1468            count = 1;
1469            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1470            }
1471        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1472        break;        break;
1473    
1474        case OP_CBRAPOS:        case OP_CBRAPOS:
1475        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1476        count = 2;        count = 2;
1477          srcw[0] = PRIVATE_DATA(cc);
1478        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1479        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1480        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1481        break;        break;
1482    
# Line 1110  while (status != end) Line 1486  while (status != end)
1486        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1487          {          {
1488          count = 1;          count = 1;
1489          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1490          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1491          }          }
1492        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1493        break;        break;
1494    
1495          CASE_ITERATOR_PRIVATE_DATA_1
1496          if (PRIVATE_DATA(cc))
1497            {
1498            count = 1;
1499            srcw[0] = PRIVATE_DATA(cc);
1500            }
1501          cc += 2;
1502    #ifdef SUPPORT_UTF
1503          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1504    #endif
1505          break;
1506    
1507          CASE_ITERATOR_PRIVATE_DATA_2A
1508          if (PRIVATE_DATA(cc))
1509            {
1510            count = 2;
1511            srcw[0] = PRIVATE_DATA(cc);
1512            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1513            }
1514          cc += 2;
1515    #ifdef SUPPORT_UTF
1516          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1517    #endif
1518          break;
1519    
1520          CASE_ITERATOR_PRIVATE_DATA_2B
1521          if (PRIVATE_DATA(cc))
1522            {
1523            count = 2;
1524            srcw[0] = PRIVATE_DATA(cc);
1525            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1526            }
1527          cc += 2 + IMM2_SIZE;
1528    #ifdef SUPPORT_UTF
1529          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1530    #endif
1531          break;
1532    
1533          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1534          if (PRIVATE_DATA(cc))
1535            {
1536            count = 1;
1537            srcw[0] = PRIVATE_DATA(cc);
1538            }
1539          cc += 1;
1540          break;
1541    
1542          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1543          if (PRIVATE_DATA(cc))
1544            {
1545            count = 2;
1546            srcw[0] = PRIVATE_DATA(cc);
1547            srcw[1] = srcw[0] + sizeof(sljit_sw);
1548            }
1549          cc += 1;
1550          break;
1551    
1552          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1553          if (PRIVATE_DATA(cc))
1554            {
1555            count = 2;
1556            srcw[0] = PRIVATE_DATA(cc);
1557            srcw[1] = srcw[0] + sizeof(sljit_sw);
1558            }
1559          cc += 1 + IMM2_SIZE;
1560          break;
1561    
1562          case OP_CLASS:
1563          case OP_NCLASS:
1564    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1565          case OP_XCLASS:
1566          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1567    #else
1568          size = 1 + 32 / (int)sizeof(pcre_uchar);
1569    #endif
1570          if (PRIVATE_DATA(cc))
1571            switch(get_class_iterator_size(cc + size))
1572              {
1573              case 1:
1574              count = 1;
1575              srcw[0] = PRIVATE_DATA(cc);
1576              break;
1577    
1578              case 2:
1579              count = 2;
1580              srcw[0] = PRIVATE_DATA(cc);
1581              srcw[1] = srcw[0] + sizeof(sljit_sw);
1582              break;
1583    
1584              default:
1585              SLJIT_ASSERT_STOP();
1586              break;
1587              }
1588          cc += size;
1589          break;
1590    
1591        default:        default:
1592        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1593        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1138  while (status != end) Line 1610  while (status != end)
1610          if (!tmp1empty)          if (!tmp1empty)
1611            {            {
1612            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1613            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1614            }            }
1615          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1616          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1149  while (status != end) Line 1621  while (status != end)
1621          if (!tmp2empty)          if (!tmp2empty)
1622            {            {
1623            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1624            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1625            }            }
1626          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1627          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1166  while (status != end) Line 1638  while (status != end)
1638          if (!tmp1empty)          if (!tmp1empty)
1639            {            {
1640            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1641            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1642            }            }
1643          tmp1next = FALSE;          tmp1next = FALSE;
1644          }          }
# Line 1178  while (status != end) Line 1650  while (status != end)
1650          if (!tmp2empty)          if (!tmp2empty)
1651            {            {
1652            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1653            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1654            }            }
1655          tmp1next = TRUE;          tmp1next = TRUE;
1656          }          }
# Line 1193  if (save) Line 1665  if (save)
1665      if (!tmp1empty)      if (!tmp1empty)
1666        {        {
1667        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1668        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1669        }        }
1670      if (!tmp2empty)      if (!tmp2empty)
1671        {        {
1672        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1673        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1674        }        }
1675      }      }
1676    else    else
# Line 1206  if (save) Line 1678  if (save)
1678      if (!tmp2empty)      if (!tmp2empty)
1679        {        {
1680        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1681        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1682        }        }
1683      if (!tmp1empty)      if (!tmp1empty)
1684        {        {
1685        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1686        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1687        }        }
1688      }      }
1689    }    }
1690  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1691  }  }
1692    
1693  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1694    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1695    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1696    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1697    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1698    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1699    
1700    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1701  {  {
1702  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1703  }  }
# Line 1228  static SLJIT_INLINE void set_jumps(jump_ Line 1707  static SLJIT_INLINE void set_jumps(jump_
1707  while (list)  while (list)
1708    {    {
1709    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1710    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1711    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1712    list = list->next;    list = list->next;
1713    }    }
# Line 1255  if (list_item) Line 1734  if (list_item)
1734    list_item->type = type;    list_item->type = type;
1735    list_item->data = data;    list_item->data = data;
1736    list_item->start = start;    list_item->start = start;
1737    list_item->leave = LABEL();    list_item->quit = LABEL();
1738    list_item->next = common->stubs;    list_item->next = common->stubs;
1739    common->stubs = list_item;    common->stubs = list_item;
1740    }    }
# Line 1275  while (list_item) Line 1754  while (list_item)
1754      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1755      break;      break;
1756      }      }
1757    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1758    list_item = list_item->next;    list_item = list_item->next;
1759    }    }
1760  common->stubs = NULL;  common->stubs = NULL;
# Line 1294  static SLJIT_INLINE void allocate_stack( Line 1773  static SLJIT_INLINE void allocate_stack(
1773  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
1774  DEFINE_COMPILER;  DEFINE_COMPILER;
1775    
1776  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1777  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
1778  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1779  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1308  add_stub(common, stack_alloc, 0, CMP(SLJ Line 1787  add_stub(common, stack_alloc, 0, CMP(SLJ
1787  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1788  {  {
1789  DEFINE_COMPILER;  DEFINE_COMPILER;
1790  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1791  }  }
1792    
1793  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1318  struct sljit_label *loop; Line 1797  struct sljit_label *loop;
1797  int i;  int i;
1798  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1799  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1800  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1801  if (length < 8)  if (length < 8)
1802    {    {
1803    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
1804      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1805    }    }
1806  else  else
1807    {    {
1808    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));
1809    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);
1810    loop = LABEL();    loop = LABEL();
1811    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1812    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
1813    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1814    }    }
1815  }  }
# Line 1345  struct sljit_jump *earlyexit; Line 1824  struct sljit_jump *earlyexit;
1824  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1825  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1826    
1827  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1828  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1829    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1830  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1831  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
1832    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
1833  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1834  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1835  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1836  /* Unlikely, but possible */  /* Unlikely, but possible */
1837  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
1838  loop = LABEL();  loop = LABEL();
1839  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
1840  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_sw));
1841  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1842  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1843  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);
1844  #endif  #endif
1845  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1846  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1847  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1848  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1849    
1850  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1851  if (topbracket > 1)  if (topbracket > 1)
1852    {    {
1853    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
1854    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
1855    
1856    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1857    loop = LABEL();    loop = LABEL();
1858    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
1859    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1860    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1861    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
1862    }    }
1863  else  else
1864    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1865  }  }
1866    
1867  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)
1868  {  {
1869  DEFINE_COMPILER;  DEFINE_COMPILER;
1870    
1871  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1872  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1873    
1874  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
1875  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1876  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1877  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
1878    
1879  /* Store match begin and end. */  /* Store match begin and end. */
1880  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1881  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1882  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_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1883  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);
1884  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1885  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);
1886  #endif  #endif
1887  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1888    
1889  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
1890  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1891  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1892  #endif  #endif
1893  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
1894    
1895  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
1896  }  }
1897    
1898  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1524  if (c <= 127 && bit == 0x20) Line 2003  if (c <= 127 && bit == 0x20)
2003    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2004    
2005  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2006  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2007    return 0;    return 0;
2008    
2009  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2010    
2011  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2012  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1543  if (common->utf && c > 127) Line 2022  if (common->utf && c > 127)
2022  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2023  return (0 << 8) | bit;  return (0 << 8) | bit;
2024    
2025  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2026    
 #ifdef COMPILE_PCRE16  
2027  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2028  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2029    {    {
# Line 1556  if (common->utf && c > 65535) Line 2034  if (common->utf && c > 65535)
2034    }    }
2035  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2036  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2037    
2038  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2039  }  }
2040    
2041  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 1622  JUMPHERE(jump); Line 2099  JUMPHERE(jump);
2099  return return_value;  return return_value;
2100  }  }
2101    
2102  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2103  {  {
2104  DEFINE_COMPILER;  DEFINE_COMPILER;
2105  struct sljit_jump *jump;  struct sljit_jump *jump;
2106    
2107  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2108    {    {
2109    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));
2110    return;    return;
2111    }    }
2112    
2113  /* Partial matching mode. */  /* Partial matching mode. */
2114  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2115  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));
2116  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2117    {    {
2118    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);
2119    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2120    }    }
2121  else  else
2122    {    {
# Line 1656  static void read_char(compiler_common *c Line 2133  static void read_char(compiler_common *c
2133  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2134  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2135  DEFINE_COMPILER;  DEFINE_COMPILER;
2136  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2137  struct sljit_jump *jump;  struct sljit_jump *jump;
2138  #endif  #endif
2139    
2140  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2141  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2142  if (common->utf)  if (common->utf)
2143    {    {
2144  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2146  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2147    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2148  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2149    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2150    JUMPHERE(jump);    JUMPHERE(jump);
2151    }    }
2152  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2153  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));
2154  }  }
2155    
# Line 1683  static void peek_char(compiler_common *c Line 2158  static void peek_char(compiler_common *c
2158  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2159  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2160  DEFINE_COMPILER;  DEFINE_COMPILER;
2161  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2162  struct sljit_jump *jump;  struct sljit_jump *jump;
2163  #endif  #endif
2164    
2165  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2166  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2167  if (common->utf)  if (common->utf)
2168    {    {
2169  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2171  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2172    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2173  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2174    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2175    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2176    JUMPHERE(jump);    JUMPHERE(jump);
2177    }    }
2178  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2179  }  }
2180    
2181  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2182  {  {
2183  /* 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. */
2184  DEFINE_COMPILER;  DEFINE_COMPILER;
2185  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2186  struct sljit_jump *jump;  struct sljit_jump *jump;
2187  #endif  #endif
2188    
# Line 1718  if (common->utf) Line 2191  if (common->utf)
2191    {    {
2192    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2193    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));
2194  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2195    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2196    it is needed in most cases. */    it is needed in most cases. */
2197    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2198    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2199    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2200    JUMPHERE(jump);    JUMPHERE(jump);
2201  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2202    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2203    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2204    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 1734  if (common->utf) Line 2206  if (common->utf)
2206    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2207    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2208    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2209    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2210    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2211    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2212  #endif  #elif defined COMPILE_PCRE32
2213  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2214      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2215      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2216      JUMPHERE(jump);
2217    #endif /* COMPILE_PCRE[8|16|32] */
2218    return;    return;
2219    }    }
2220  #endif  #endif /* SUPPORT_UTF */
2221  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2222  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));
2223  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2224  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2225  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2226  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2227  #endif  #endif
2228  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2229  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2230  JUMPHERE(jump);  JUMPHERE(jump);
2231  #endif  #endif
2232  }  }
# Line 1759  static void skip_char_back(compiler_comm Line 2235  static void skip_char_back(compiler_comm
2235  {  {
2236  /* 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. */
2237  DEFINE_COMPILER;  DEFINE_COMPILER;
2238  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2239    #if defined COMPILE_PCRE8
2240  struct sljit_label *label;  struct sljit_label *label;
2241    
2242  if (common->utf)  if (common->utf)
# Line 1771  if (common->utf) Line 2248  if (common->utf)
2248    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2249    return;    return;
2250    }    }
2251  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2252  if (common->utf)  if (common->utf)
2253    {    {
2254    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 1780  if (common->utf) Line 2256  if (common->utf)
2256    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2257    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2258    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2259    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2260    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2261    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2262    return;    return;
2263    }    }
2264  #endif  #endif /* COMPILE_PCRE[8|16] */
2265    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2266  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));
2267  }  }
2268    
2269  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)
2270  {  {
2271  /* 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. */
2272  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1797  DEFINE_COMPILER; Line 2274  DEFINE_COMPILER;
2274  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2275    {    {
2276    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2277    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));
2278    }    }
2279  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2280    {    {
2281    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
2282    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2283    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);
2284    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2285    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));
2286    }    }
2287  else  else
2288    {    {
2289    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2290    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));
2291    }    }
2292  }  }
2293    
2294  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2295    
2296  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2297  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2298  {  {
2299  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 1904  sljit_emit_fast_return(compiler, RETURN_ Line 2381  sljit_emit_fast_return(compiler, RETURN_
2381  JUMPHERE(jump);  JUMPHERE(jump);
2382    
2383  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2384  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2385  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2386  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2387  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2388  }  }
2389    
2390  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2391    
 #ifdef COMPILE_PCRE16  
2392  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2393  {  {
2394  /* 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 1937  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2413  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2413  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2414  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2415  }  }
 #endif /* COMPILE_PCRE16 */  
2416    
2417  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2418    
2419  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2420    
# Line 1959  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 2434  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
2434    
2435  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2436  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2437  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
2438  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2439  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2440  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2441  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2442  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2443  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
2444  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2445  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2446  }  }
# Line 1979  struct sljit_label *newlinelabel = NULL; Line 2454  struct sljit_label *newlinelabel = NULL;
2454  struct sljit_jump *start;  struct sljit_jump *start;
2455  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2456  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2457  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2458  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2459  #endif  #endif
2460  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 1994  if (firstline) Line 2469  if (firstline)
2469    {    {
2470    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2471    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2472    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);  
2473    
2474    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2475      {      {
# Line 2006  if (firstline) Line 2480  if (firstline)
2480      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2481      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);
2482      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);
2483        JUMPHERE(end);
2484      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));
2485      }      }
2486    else    else
# Line 2017  if (firstline) Line 2492  if (firstline)
2492      read_char(common);      read_char(common);
2493      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2494      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2495        JUMPHERE(end);
2496      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);
2497      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2498      }      }
2499    
2500    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2501    }    }
2502    
2503  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2034  if (newlinecheck) Line 2509  if (newlinecheck)
2509    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2510    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2511    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);
2512    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2513  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2514    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2515  #endif  #endif
2516    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2517    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2057  if (newlinecheck) Line 2532  if (newlinecheck)
2532    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);
2533    
2534  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));
2535  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2536    #if defined COMPILE_PCRE8
2537  if (common->utf)  if (common->utf)
2538    {    {
2539    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2540    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_sw)PRIV(utf8_table4) - 0xc0);
2541    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2542    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2543    }    }
2544  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2545  if (common->utf)  if (common->utf)
2546    {    {
2547    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2548    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2549    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);
2550    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2551    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2552    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2553    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2554    }    }
2555  #endif  #endif /* COMPILE_PCRE[8|16] */
2556    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2557  JUMPHERE(start);  JUMPHERE(start);
2558    
2559  if (newlinecheck)  if (newlinecheck)
# Line 2089  if (newlinecheck) Line 2565  if (newlinecheck)
2565  return mainloop;  return mainloop;
2566  }  }
2567    
2568    #define MAX_N_CHARS 3
2569    
2570    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2571    {
2572    DEFINE_COMPILER;
2573    struct sljit_label *start;
2574    struct sljit_jump *quit;
2575    pcre_uint32 chars[MAX_N_CHARS * 2];
2576    pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2577    int location = 0;
2578    pcre_int32 len, c, bit, caseless;
2579    int must_stop;
2580    
2581    /* We do not support alternatives now. */
2582    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2583      return FALSE;
2584    
2585    while (TRUE)
2586      {
2587      caseless = 0;
2588      must_stop = 1;
2589      switch(*cc)
2590        {
2591        case OP_CHAR:
2592        must_stop = 0;
2593        cc++;
2594        break;
2595    
2596        case OP_CHARI:
2597        caseless = 1;
2598        must_stop = 0;
2599        cc++;
2600        break;
2601    
2602        case OP_SOD:
2603        case OP_SOM:
2604        case OP_SET_SOM:
2605        case OP_NOT_WORD_BOUNDARY:
2606        case OP_WORD_BOUNDARY:
2607        case OP_EODN:
2608        case OP_EOD:
2609        case OP_CIRC:
2610        case OP_CIRCM:
2611        case OP_DOLL:
2612        case OP_DOLLM:
2613        /* Zero width assertions. */
2614        cc++;
2615        continue;
2616    
2617        case OP_PLUS:
2618        case OP_MINPLUS:
2619        case OP_POSPLUS:
2620        cc++;
2621        break;
2622    
2623        case OP_EXACT:
2624        cc += 1 + IMM2_SIZE;
2625        break;
2626    
2627        case OP_PLUSI:
2628        case OP_MINPLUSI:
2629        case OP_POSPLUSI:
2630        caseless = 1;
2631        cc++;
2632        break;
2633    
2634        case OP_EXACTI:
2635        caseless = 1;
2636        cc += 1 + IMM2_SIZE;
2637        break;
2638    
2639        default:
2640        must_stop = 2;
2641        break;
2642        }
2643    
2644      if (must_stop == 2)
2645          break;
2646    
2647      len = 1;
2648    #ifdef SUPPORT_UTF
2649      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2650    #endif
2651    
2652      if (caseless && char_has_othercase(common, cc))
2653        {
2654        caseless = char_get_othercase_bit(common, cc);
2655        if (caseless == 0)
2656          return FALSE;
2657    #ifdef COMPILE_PCRE8
2658        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2659    #else
2660        if ((caseless & 0x100) != 0)
2661          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2662        else
2663          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2664    #endif
2665        }
2666      else
2667        caseless = 0;
2668    
2669      while (len > 0 && location < MAX_N_CHARS * 2)
2670        {
2671        c = *cc;
2672        bit = 0;
2673        if (len == (caseless & 0xff))
2674          {
2675          bit = caseless >> 8;
2676          c |= bit;
2677          }
2678    
2679        chars[location] = c;
2680        chars[location + 1] = bit;
2681    
2682        len--;
2683        location += 2;
2684        cc++;
2685        }
2686    
2687      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2688        break;
2689      }
2690    
2691    /* At least two characters are required. */
2692    if (location < 2 * 2)
2693        return FALSE;
2694    
2695    if (firstline)
2696      {
2697      SLJIT_ASSERT(common->first_line_end != 0);
2698      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2699      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2700      }
2701    else
2702      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2703    
2704    start = LABEL();
2705    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2706    
2707    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2708    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2709    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2710    if (chars[1] != 0)
2711      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2712    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2713    if (location > 2 * 2)
2714      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2715    if (chars[3] != 0)
2716      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2717    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2718    if (location > 2 * 2)
2719      {
2720      if (chars[5] != 0)
2721        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2722      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2723      }
2724    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2725    
2726    JUMPHERE(quit);
2727    
2728    if (firstline)
2729      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2730    else
2731      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2732    return TRUE;
2733    }
2734    
2735    #undef MAX_N_CHARS
2736    
2737  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)
2738  {  {
2739  DEFINE_COMPILER;  DEFINE_COMPILER;
2740  struct sljit_label *start;  struct sljit_label *start;
2741  struct sljit_jump *leave;  struct sljit_jump *quit;
2742  struct sljit_jump *found;  struct sljit_jump *found;
2743  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2744    
2745  if (firstline)  if (firstline)
2746    {    {
2747    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2748      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2749    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);
2750    }    }
2751    
2752  start = LABEL();  start = LABEL();
2753  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2754  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2755    
2756  oc = first_char;  oc = first_char;
# Line 2121  if (first_char == oc) Line 2767  if (first_char == oc)
2767  else  else
2768    {    {
2769    bit = first_char ^ oc;    bit = first_char ^ oc;
2770    if (ispowerof2(bit))    if (is_powerof2(bit))
2771      {      {
2772      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2773      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 2129  else Line 2775  else
2775    else    else
2776      {      {
2777      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
2778      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2779      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
2780      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2781      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
2782      }      }
2783    }    }
2784    
2785  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  
2786  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2787  JUMPHERE(found);  JUMPHERE(found);
2788  JUMPHERE(leave);  JUMPHERE(quit);
2789    
2790  if (firstline)  if (firstline)
2791    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2792  }  }
2793    
2794  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 2170  DEFINE_COMPILER; Line 2797  DEFINE_COMPILER;
2797  struct sljit_label *loop;  struct sljit_label *loop;
2798  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2799  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2800  struct sljit_jump *leave;  struct sljit_jump *quit;
2801  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2802  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2803  jump_list *newline = NULL;  jump_list *newline = NULL;
2804    
2805  if (firstline)  if (firstline)
2806    {    {
2807    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2808      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2809    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);
2810    }    }
2811    
# Line 2191  if (common->nltype == NLTYPE_FIXED && co Line 2819  if (common->nltype == NLTYPE_FIXED && co
2819    
2820    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2821    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);
2822    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
2823  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2824    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2825  #endif  #endif
2826    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2827    
2828    loop = LABEL();    loop = LABEL();
2829    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));
2830    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2831    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2832    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2833    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);
2834    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);
2835    
2836    JUMPHERE(leave);    JUMPHERE(quit);
2837    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2838    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2839    
# Line 2229  set_jumps(newline, loop); Line 2857  set_jumps(newline, loop);
2857    
2858  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2859    {    {
2860    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2861    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2862    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2863    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2864    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);
2865    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2866  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2867    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2868  #endif  #endif
2869    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2870    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2871    JUMPHERE(leave);    JUMPHERE(quit);
2872    }    }
2873  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2874  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2875    
2876  if (firstline)  if (firstline)
2877    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2878  }  }
2879    
2880  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)
2881  {  {
2882  DEFINE_COMPILER;  DEFINE_COMPILER;
2883  struct sljit_label *start;  struct sljit_label *start;
2884  struct sljit_jump *leave;  struct sljit_jump *quit;
2885  struct sljit_jump *found;  struct sljit_jump *found;
2886  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2887  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 2261  struct sljit_jump *jump; Line 2889  struct sljit_jump *jump;
2889    
2890  if (firstline)  if (firstline)
2891    {    {
2892    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2893      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2894    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);
2895    }    }
2896    
2897  start = LABEL();  start = LABEL();
2898  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2899  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2900  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2901  if (common->utf)  if (common->utf)
# Line 2289  if (common->utf) Line 2918  if (common->utf)
2918    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2919  #endif  #endif
2920  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));
2921  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2922    #if defined COMPILE_PCRE8
2923  if (common->utf)  if (common->utf)
2924    {    {
2925    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2926    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_sw)PRIV(utf8_table4) - 0xc0);
2927    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2928    }    }
2929  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2930  if (common->utf)  if (common->utf)
2931    {    {
2932    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2933    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2934    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);
2935    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2936    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2937    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2938    }    }
2939  #endif  #endif /* COMPILE_PCRE[8|16] */
2940    #endif /* SUPPORT_UTF */
2941  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2942  JUMPHERE(found);  JUMPHERE(found);
2943  JUMPHERE(leave);  JUMPHERE(quit);
2944    
2945  if (firstline)  if (firstline)
2946    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2947  }  }
2948    
2949  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 2325  struct sljit_jump *alreadyfound; Line 2955  struct sljit_jump *alreadyfound;
2955  struct sljit_jump *found;  struct sljit_jump *found;
2956  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2957  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2958  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2959    
2960  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
2961  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 2356  if (req_char == oc) Line 2986  if (req_char == oc)
2986  else  else
2987    {    {
2988    bit = req_char ^ oc;    bit = req_char ^ oc;
2989    if (ispowerof2(bit))    if (is_powerof2(bit))
2990      {      {
2991      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2992      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 2394  mainloop = LABEL(); Line 3024  mainloop = LABEL();
3024  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3025  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);
3026  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3027  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_sw));
3028  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3029  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_sw));
3030  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3031    
3032  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2407  sljit_emit_fast_return(compiler, RETURN_ Line 3037  sljit_emit_fast_return(compiler, RETURN_
3037  JUMPHERE(jump);  JUMPHERE(jump);
3038  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
3039  /* Set string begin. */  /* Set string begin. */
3040  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3041  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3042  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
3043  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3044    
# Line 2416  JUMPHERE(jump); Line 3046  JUMPHERE(jump);
3046  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
3047    {    {
3048    jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);    jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3049    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3050    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3051    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3052    JUMPTO(SLJIT_JUMP, mainloop);    JUMPTO(SLJIT_JUMP, mainloop);
3053    
# Line 2425  if (common->mark_ptr != 0) Line 3055  if (common->mark_ptr != 0)
3055    }    }
3056    
3057  /* Unknown command. */  /* Unknown command. */
3058  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3059  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3060  }  }
3061    
# Line 2458  if (common->use_ucp) Line 3088  if (common->use_ucp)
3088    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3089    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3090    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3091    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3092    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3093    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3094    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3095    JUMPHERE(jump);    JUMPHERE(jump);
3096    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3097    }    }
# Line 2502  if (common->use_ucp) Line 3132  if (common->use_ucp)
3132    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3133    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3134    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3135    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3136    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3137    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3138    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3139    JUMPHERE(jump);    JUMPHERE(jump);
3140    }    }
3141  else  else
# Line 2537  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE Line 3167  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSE
3167  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3168  }  }
3169    
3170    /*
3171      range format:
3172    
3173      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3174      ranges[1] = first bit (0 or 1)
3175      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3176    */
3177    
3178    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3179    {
3180    DEFINE_COMPILER;
3181    struct sljit_jump *jump;
3182    
3183    if (ranges[0] < 0)
3184      return FALSE;
3185    
3186    switch(ranges[0])
3187      {
3188      case 1:
3189      if (readch)
3190        read_char(common);
3191      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3192      return TRUE;
3193    
3194      case 2:
3195      if (readch)
3196        read_char(common);
3197      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3198      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3199      return TRUE;
3200    
3201      case 4:
3202      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3203        {
3204        if (readch)
3205          read_char(common);
3206        if (ranges[1] != 0)
3207          {
3208          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3209          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3210          }
3211        else
3212          {
3213          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3214          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3215          JUMPHERE(jump);
3216          }
3217        return TRUE;
3218        }
3219      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3220        {
3221        if (readch)
3222          read_char(common);
3223        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3224        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3225        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3226        return TRUE;
3227        }
3228      return FALSE;
3229    
3230      default:
3231      return FALSE;
3232      }
3233    }
3234    
3235    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3236    {
3237    int i, bit, length;
3238    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3239    
3240    bit = ctypes[0] & flag;
3241    ranges[0] = -1;
3242    ranges[1] = bit != 0 ? 1 : 0;
3243    length = 0;
3244    
3245    for (i = 1; i < 256; i++)
3246      if ((ctypes[i] & flag) != bit)
3247        {
3248        if (length >= MAX_RANGE_SIZE)
3249          return;
3250        ranges[2 + length] = i;
3251        length++;
3252        bit ^= flag;
3253        }
3254    
3255    if (bit != 0)
3256      {
3257      if (length >= MAX_RANGE_SIZE)
3258        return;
3259      ranges[2 + length] = 256;
3260      length++;
3261      }
3262    ranges[0] = length;
3263    }
3264    
3265    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3266    {
3267    int ranges[2 + MAX_RANGE_SIZE];
3268    pcre_uint8 bit, cbit, all;
3269    int i, byte, length = 0;
3270    
3271    bit = bits[0] & 0x1;
3272    ranges[1] = bit;
3273    /* Can be 0 or 255. */
3274    all = -bit;
3275    
3276    for (i = 0; i < 256; )
3277      {
3278      byte = i >> 3;
3279      if ((i & 0x7) == 0 && bits[byte] == all)
3280        i += 8;
3281      else
3282        {
3283        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3284        if (cbit != bit)
3285          {
3286          if (length >= MAX_RANGE_SIZE)
3287            return FALSE;
3288          ranges[2 + length] = i;
3289          length++;
3290          bit = cbit;
3291          all = -cbit;
3292          }
3293        i++;
3294        }
3295      }
3296    
3297    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3298      {
3299      if (length >= MAX_RANGE_SIZE)
3300        return FALSE;
3301      ranges[2 + length] = 256;
3302      length++;
3303      }
3304    ranges[0] = length;
3305    
3306    return check_ranges(common, ranges, backtracks, FALSE);
3307    }
3308    
3309  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3310  {  {
3311  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
# Line 2546  sljit_emit_fast_enter(compiler, RETURN_A Line 3315  sljit_emit_fast_enter(compiler, RETURN_A
3315    
3316  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3317  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);
3318  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3319  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);
3320  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3321  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3322  if (common->utf)  if (common->utf)
3323    {    {
3324  #endif  #endif
3325    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3326    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3327    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3328  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3329    }    }
3330  #endif  #endif
3331  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3332  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3333  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3334  }  }
3335    
# Line 2572  DEFINE_COMPILER; Line 3341  DEFINE_COMPILER;
3341  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3342    
3343  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);
3344  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3345  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);
3346  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3347  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);
3348  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3349  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3350  if (common->utf)  if (common->utf)
3351    {    {
3352  #endif  #endif
3353    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3354    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
3355    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3356    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
3357    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3358    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3359    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
3360    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3361    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
3362    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3363    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
3364    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3365    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
3366  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3367    }    }
3368  #endif  #endif
3369  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3370  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3371    
3372  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3373  }  }
# Line 2612  sljit_emit_fast_enter(compiler, RETURN_A Line 3381  sljit_emit_fast_enter(compiler, RETURN_A
3381    
3382  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3383  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);
3384  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3385  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);
3386  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3387  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3388  if (common->utf)  if (common->utf)
3389    {    {
3390  #endif  #endif
3391    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3392    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3393    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3394  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3395    }    }
3396  #endif  #endif
3397  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3398  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3399    
3400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3401  }  }
# Line 2715  sljit_emit_fast_return(compiler, RETURN_ Line 3484  sljit_emit_fast_return(compiler, RETURN_
3484  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)
3485  {  {
3486  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3487  int c1, c2;  pcre_uint32 c1, c2;
3488  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3489  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3490    const ucd_record *ur;
3491    const pcre_uint32 *pp;
3492    
3493  while (src1 < end1)  while (src1 < end1)
3494    {    {
# Line 2725  while (src1 < end1) Line 3496  while (src1 < end1)
3496      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3497    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3498    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3499    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3500      if (c1 != c2 && c1 != c2 + ur->other_case)
3501        {
3502        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3503        for (;;)
3504          {
3505          if (c1 < *pp) return NULL;
3506          if (c1 == *pp++) break;
3507          }
3508        }
3509    }    }
3510  return src2;  return src2;
3511  }  }
# Line 2733  return src2; Line 3513  return src2;
3513  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3514    
3515  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,
3516      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3517  {  {
3518  DEFINE_COMPILER;  DEFINE_COMPILER;
3519  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2747  if (caseless && char_has_othercase(commo Line 3527  if (caseless && char_has_othercase(commo
3527    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3528    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3529    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3530  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3531    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3532    othercasebit &= 0xff;    othercasebit &= 0xff;
3533  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3534  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3535      ever are characters outside the BMP whose othercase differs in only one
3536      bit from itself (there currently are none), this code will need to be
3537      revised for COMPILE_PCRE32. */
3538    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3539    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3540      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3541    else    else
3542      othercasebit &= 0xff;      othercasebit &= 0xff;
3543  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3544    }    }
3545    
3546  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3547    {    {
3548  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3549  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3550    if (context->length >= 4)    if (context->length >= 4)
3551      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 2772  if (context->sourcereg == -1) Line 3554  if (context->sourcereg == -1)
3554    else    else
3555  #endif  #endif
3556      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3557  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3558  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3559    if (context->length >= 4)    if (context->length >= 4)
3560      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3561    else    else
3562  #endif  #endif
3563      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3564  #endif  #elif defined COMPILE_PCRE32
3565  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3566    #endif /* COMPILE_PCRE[8|16|32] */
3567    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3568    }    }
3569    
# Line 2795  do Line 3577  do
3577  #endif  #endif
3578    
3579    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3580  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3581    
3582    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3583    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 2810  do Line 3592  do
3592      }      }
3593    context->ucharptr++;    context->ucharptr++;
3594    
3595  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3596    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))
3597  #else  #else
3598    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
# Line 2818  do Line 3600  do
3600      {      {
3601      if (context->length >= 4)      if (context->length >= 4)
3602        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);
 #ifdef COMPILE_PCRE8  
3603      else if (context->length >= 2)      else if (context->length >= 2)
3604        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);
3605    #if defined COMPILE_PCRE8
3606      else if (context->length >= 1)      else if (context->length >= 1)
3607        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);
3608  #else  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3609      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3610    
3611      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2834  do Line 3613  do
3613        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3614        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3615          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);
3616        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));
3617        break;        break;
3618    
3619        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3620        if (context->oc.asushort != 0)        if (context->oc.asushort != 0)
3621          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);
3622        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));
3623        break;        break;
3624    
3625  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3626        case 1:        case 1:
3627        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3628          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);
3629        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));
3630        break;        break;
3631  #endif  #endif
3632    
# Line 2860  do Line 3639  do
3639    
3640  #else  #else
3641    
3642    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3643  #ifdef COMPILE_PCRE8    if (context->length >= 1)
3644    if (context->length > 0)      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3645      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #else  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3646    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3647    
3648    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3649      {      {
3650      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3651      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));
3652      }      }
3653    else    else
3654      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));
3655    
3656  #endif  #endif
3657    
# Line 2912  return cc; Line 3687  return cc;
3687      } \      } \
3688    charoffset = (value);    charoffset = (value);
3689    
3690  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)
3691  {  {
3692  DEFINE_COMPILER;  DEFINE_COMPILER;
3693  jump_list *found = NULL;  jump_list *found = NULL;
3694  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3695  unsigned int c;  pcre_int32 c, charoffset;
3696  int compares;  const pcre_uint32 *other_cases;
3697  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3698  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3699    int compares, invertcmp, numberofcmps;
3700  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3701  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3702  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3703  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3704  unsigned int typeoffset;  pcre_int32 typeoffset;
3705  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3706    
3707  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3708  fallback_at_str_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3709    detect_partial_match(common, backtracks);
3710  read_char(common);  read_char(common);
3711    
3712  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2944  if ((*cc++ & XCL_MAP) != 0) Line 3719  if ((*cc++ & XCL_MAP) != 0)
3719      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3720  #endif  #endif
3721    
3722    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3723    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3724    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3725    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3726    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
3727    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3728        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3729        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3730        }
3731    
3732  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3733    JUMPHERE(jump);    JUMPHERE(jump);
# Line 3022  while (*cc != XCL_END) Line 3800  while (*cc != XCL_END)
3800        needschar = TRUE;        needschar = TRUE;
3801        break;        break;
3802    
3803          case PT_CLIST:
3804          needschar = TRUE;
3805          break;
3806    
3807        default:        default:
3808        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3809        break;        break;
# Line 3058  if (needstype || needsscript) Line 3840  if (needstype || needsscript)
3840      {      {
3841      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3842        {        {
3843        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3844        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3845        }        }
3846      else      else
3847        {        {
3848        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3849        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3850        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3851        }        }
3852      }      }
# Line 3082  typeoffset = 0; Line 3864  typeoffset = 0;
3864  while (*cc != XCL_END)  while (*cc != XCL_END)
3865    {    {
3866    compares--;    compares--;
3867    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3868    jump = NULL;    jump = NULL;
3869    
3870    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 3100  while (*cc != XCL_END) Line 3882  while (*cc != XCL_END)
3882      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3883        {        {
3884        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3885        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
3886        numberofcmps++;        numberofcmps++;
3887        }        }
3888      else if (numberofcmps > 0)      else if (numberofcmps > 0)
3889        {        {
3890        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3891        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3892        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3893        numberofcmps = 0;        numberofcmps = 0;
3894        }        }
# Line 3139  while (*cc != XCL_END) Line 3921  while (*cc != XCL_END)
3921      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3922        {        {
3923        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3924        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
3925        numberofcmps++;        numberofcmps++;
3926        }        }
3927      else if (numberofcmps > 0)      else if (numberofcmps > 0)
3928        {        {
3929        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3930        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3931        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3932        numberofcmps = 0;        numberofcmps = 0;
3933        }        }
# Line 3164  while (*cc != XCL_END) Line 3946  while (*cc != XCL_END)
3946      switch(*cc)      switch(*cc)
3947        {        {
3948        case PT_ANY:        case PT_ANY:
3949        if (list != fallbacks)        if (list != backtracks)
3950          {          {
3951          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))
3952            continue;            continue;
# Line 3176  while (*cc != XCL_END) Line 3958  while (*cc != XCL_END)
3958    
3959        case PT_LAMP:        case PT_LAMP:
3960        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
3961        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3962        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
3963        COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3964        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
3965        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3966        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3967        break;        break;
3968    
# Line 3207  while (*cc != XCL_END) Line 3989  while (*cc != XCL_END)
3989          }          }
3990        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
3991        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
3992        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3993        if (*cc == PT_SPACE)        if (*cc == PT_SPACE)
3994          JUMPHERE(jump);          JUMPHERE(jump);
3995    
3996        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
3997        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
3998        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3999        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4000        break;        break;
4001    
4002        case PT_WORD:        case PT_WORD:
4003        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
4004        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4005        /* ... fall through */        /* ... fall through */
4006    
4007        case PT_ALNUM:        case PT_ALNUM:
4008        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
4009        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4010        COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4011        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
4012        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4013        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4014          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4015          break;
4016    
4017          case PT_CLIST:
4018          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4019    
4020          /* At least three characters are required.
4021             Otherwise this case would be handled by the normal code path. */
4022          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4023          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4024    
4025          /* Optimizing character pairs, if their difference is power of 2. */
4026          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4027            {
4028            if (charoffset == 0)
4029              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4030            else
4031              {
4032              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4033              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4034              }
4035            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4036            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4037            other_cases += 2;
4038            }
4039          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4040            {
4041            if (charoffset == 0)
4042              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4043            else
4044              {
4045              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4046              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4047              }
4048            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4049            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4050    
4051            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4052            OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4053    
4054            other_cases += 3;
4055            }
4056          else
4057            {
4058            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4059            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4060            }
4061    
4062          while (*other_cases != NOTACHAR)
4063            {
4064            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4065            OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4066            }
4067        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4068        break;        break;
4069        }        }
# Line 3237  while (*cc != XCL_END) Line 4072  while (*cc != XCL_END)
4072  #endif  #endif
4073    
4074    if (jump != NULL)    if (jump != NULL)
4075      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
4076    }    }
4077    
4078  if (found != NULL)  if (found != NULL)
# Line 3249  if (found != NULL) Line 4084  if (found != NULL)
4084    
4085  #endif  #endif
4086    
4087  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)
4088  {  {
4089  DEFINE_COMPILER;  DEFINE_COMPILER;
4090  int length;  int length;
# Line 3268  switch(type) Line 4103  switch(type)
4103    case OP_SOD:    case OP_SOD:
4104    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4105    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));
4106    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));
4107    return cc;    return cc;
4108    
4109    case OP_SOM:    case OP_SOM:
4110    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4111    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));
4112    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));
4113    return cc;    return cc;
4114    
4115    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4116    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4117    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4118    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));
4119    return cc;    return cc;
4120    
4121    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4122    case OP_DIGIT:    case OP_DIGIT:
4123    fallback_at_str_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4124    read_char8_type(common);    if (common->digits[0] == -2)
4125    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4126    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4127      /* Flip the starting bit in the negative case. */
4128      if (type == OP_NOT_DIGIT)
4129        common->digits[1] ^= 1;
4130      if (!check_ranges(common, common->digits, backtracks, TRUE))
4131        {
4132        read_char8_type(common);
4133        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4134        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4135        }
4136      if (type == OP_NOT_DIGIT)
4137        common->digits[1] ^= 1;
4138    return cc;    return cc;
4139    
4140    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4141    case OP_WHITESPACE:    case OP_WHITESPACE:
4142    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4143    read_char8_type(common);    read_char8_type(common);
4144    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);
4145    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));
4146    return cc;    return cc;
4147    
4148    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4149    case OP_WORDCHAR:    case OP_WORDCHAR:
4150    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4151    read_char8_type(common);    read_char8_type(common);
4152    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);
4153    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));
4154    return cc;    return cc;
4155    
4156    case OP_ANY:    case OP_ANY:
4157    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4158    read_char(common);    read_char(common);
4159    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4160      {      {
# Line 3319  switch(type) Line 4165  switch(type)
4165        jump[1] = check_str_end(common);        jump[1] = check_str_end(common);
4166    
4167      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4168      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));
4169      if (jump[1] != NULL)      if (jump[1] != NULL)
4170        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4171      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4172      }      }
4173    else    else
4174      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4175    return cc;    return cc;
4176    
4177    case OP_ALLANY:    case OP_ALLANY:
4178    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4179  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4180    if (common->utf)    if (common->utf)
4181      {      {
4182      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4183      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));
4184  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4185    #if defined COMPILE_PCRE8
4186      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4187      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_sw)PRIV(utf8_table4) - 0xc0);
4188      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4189  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4190      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4191      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4192      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);
4193      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4194      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4195      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4196  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4197      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4198    #endif /* COMPILE_PCRE[8|16] */
4199      return cc;      return cc;
4200      }      }
4201  #endif  #endif
# Line 3357  switch(type) Line 4203  switch(type)
4203    return cc;    return cc;
4204    
4205    case OP_ANYBYTE:    case OP_ANYBYTE:
4206    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4207    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));
4208    return cc;    return cc;
4209    
# Line 3370  switch(type) Line 4216  switch(type)
4216    propdata[2] = cc[0];    propdata[2] = cc[0];
4217    propdata[3] = cc[1];    propdata[3] = cc[1];
4218    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4219    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4220    return cc + 2;    return cc + 2;
4221  #endif  #endif
4222  #endif  #endif
4223    
4224    case OP_ANYNL:    case OP_ANYNL:
4225    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4226    read_char(common);    read_char(common);
4227    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);
4228    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
# Line 3389  switch(type) Line 4235  switch(type)
4235    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));
4236    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4237    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4238    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4239    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4240    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4241    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3397  switch(type) Line 4243  switch(type)
4243    
4244    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4245    case OP_HSPACE:    case OP_HSPACE:
4246    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4247    read_char(common);    read_char(common);
4248    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4249    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));
4250    return cc;    return cc;
4251    
4252    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4253    case OP_VSPACE:    case OP_VSPACE:
4254    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4255    read_char(common);    read_char(common);
4256    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4257    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));
4258    return cc;    return cc;
4259    
4260  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4261    case OP_EXTUNI:    case OP_EXTUNI:
4262    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4263    read_char(common);    read_char(common);
4264    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4265    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4266    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4267      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4268      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4269    
4270    label = LABEL();    label = LABEL();
4271    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);
4272    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4273    read_char(common);    read_char(common);
4274    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4275    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4276    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);
4277    
4278      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4279      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
4280      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4281      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4282      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4283      JUMPTO(SLJIT_C_NOT_ZERO, label);
4284    
4285    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4286    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4287      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4288    
4289    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4290      {      {
4291      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 3447  switch(type) Line 4304  switch(type)
4304      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));
4305      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4306      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4307        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));
4308      else      else
4309        {        {
4310        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4311        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);
4312        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS);
4313        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);
4314        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4315        add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4316        check_partial(common, TRUE);        check_partial(common, TRUE);
4317        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4318        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4319        }        }
4320      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4321      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));
4322      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));
4323      }      }
4324    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4325      {      {
4326      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));
4327      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4328      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));
4329      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));
4330      }      }
4331    else    else
4332      {      {
# Line 3478  switch(type) Line 4335  switch(type)
4335      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));
4336      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);
4337      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4338      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4339      /* Equal. */      /* Equal. */
4340      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4341      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4342      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4343    
4344      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4345      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4346        {        {
4347        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));
4348        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));
4349        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));
4350        }        }
4351      else      else
4352        {        {
4353        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4354        read_char(common);        read_char(common);
4355        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));
4356        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4357        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4358        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4359        }        }
4360      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
# Line 3508  switch(type) Line 4365  switch(type)
4365    return cc;    return cc;
4366    
4367    case OP_EOD:    case OP_EOD:
4368    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));
4369    check_partial(common, FALSE);    check_partial(common, FALSE);
4370    return cc;    return cc;
4371    
4372    case OP_CIRC:    case OP_CIRC:
4373    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4374    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));
4375    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));
4376    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));
4377    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));
4378    return cc;    return cc;
4379    
4380    case OP_CIRCM:    case OP_CIRCM:
# Line 3525  switch(type) Line 4382  switch(type)
4382    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));
4383    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4384    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));
4385    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));
4386    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4387    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4388    
4389    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));
4390    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4391      {      {
4392      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));
4393      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4394      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4395      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4396      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));
4397      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));
4398      }      }
4399    else    else
4400      {      {
4401      skip_char_back(common);      skip_char_back(common);
4402      read_char(common);      read_char(common);
4403      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4404      }      }
4405    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4406    return cc;    return cc;
# Line 3551  switch(type) Line 4408  switch(type)
4408    case OP_DOLL:    case OP_DOLL:
4409    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4410    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));
4411    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));
4412    
4413    if (!common->endonly)    if (!common->endonly)
4414      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_matchingpath(common, OP_EODN, cc, backtracks);
4415    else    else
4416      {      {
4417      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));
4418      check_partial(common, FALSE);      check_partial(common, FALSE);
4419      }      }
4420    return cc;    return cc;
# Line 3566  switch(type) Line 4423  switch(type)
4423    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4424    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4425    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));
4426    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));
4427    check_partial(common, FALSE);    check_partial(common, FALSE);
4428    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4429    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
# Line 3576  switch(type) Line 4433  switch(type)
4433      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));
4434      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4435      if (common->mode == JIT_COMPILE)      if (common->mode == JIT_COMPILE)
4436        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));
4437      else      else
4438        {        {
4439        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4440        /* STR_PTR = STR_END - IN_UCHARS(1) */        /* STR_PTR = STR_END - IN_UCHARS(1) */
4441        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));
4442        check_partial(common, TRUE);        check_partial(common, TRUE);
4443        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4444        JUMPHERE(jump[1]);        JUMPHERE(jump[1]);
4445        }        }
4446    
4447      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4448      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));
4449      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));
4450      }      }
4451    else    else
4452      {      {
4453      peek_char(common);      peek_char(common);
4454      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4455      }      }
4456    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4457    return cc;    return cc;
# Line 3608  switch(type) Line 4465  switch(type)
4465    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))
4466      {      {
4467      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));
4468      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));
4469    
4470      context.length = IN_UCHARS(length);      context.length = IN_UCHARS(length);
4471      context.sourcereg = -1;      context.sourcereg = -1;
4472  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4473      context.ucharptr = 0;      context.ucharptr = 0;
4474  #endif  #endif
4475      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
4476      }      }
4477    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4478    read_char(common);    read_char(common);
4479  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4480    if (common->utf)    if (common->utf)
# Line 3629  switch(type) Line 4486  switch(type)
4486      c = *cc;      c = *cc;
4487    if (type == OP_CHAR || !char_has_othercase(common, cc))    if (type == OP_CHAR || !char_has_othercase(common, cc))
4488      {      {
4489      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));
4490      return cc + length;      return cc + length;
4491      }      }
4492    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4493    bit = c ^ oc;    bit = c ^ oc;
4494    if (ispowerof2(bit))    if (is_powerof2(bit))
4495      {      {
4496      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4497      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));
4498      return cc + length;      return cc + length;
4499      }      }
4500    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);
4501    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4502    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);
4503    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4504    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4505    return cc + length;    return cc + length;
4506    
4507    case OP_NOT:    case OP_NOT:
4508    case OP_NOTI:    case OP_NOTI:
4509    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4510    length = 1;    length = 1;
4511  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4512    if (common->utf)    if (common->utf)
# Line 3660  switch(type) Line 4517  switch(type)
4517        {        {
4518        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4519        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
4520          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));
4521        else        else
4522          {          {
4523          /* 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. */
4524          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
4525          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));
4526          }          }
4527        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4528        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));
4529        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4530        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4531        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4532        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
4533        return cc + 1;        return cc + 1;
# Line 3690  switch(type) Line 4547  switch(type)
4547      }      }
4548    
4549    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
4550      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));
4551    else    else
4552      {      {
4553      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4554      bit = c ^ oc;      bit = c ^ oc;
4555      if (ispowerof2(bit))      if (is_powerof2(bit))
4556        {        {
4557        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4558        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));
4559        }        }
4560      else      else
4561        {        {
4562        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));
4563        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));
4564        }        }
4565      }      }
4566    return cc + length;    return cc + length;
4567    
4568    case OP_CLASS:    case OP_CLASS:
4569    case OP_NCLASS:    case OP_NCLASS:
4570    fallback_at_str_end(common, fallbacks);    detect_partial_match(common, backtracks);
4571    read_char(common);    read_char(common);
4572      if (check_class_ranges(common, (const pcre_uint8 *)cc, type == OP_NCLASS, backtracks))
4573        return cc + 32 / sizeof(pcre_uchar);
4574    
4575  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4576    jump[0] = NULL;    jump[0] = NULL;
4577  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
# Line 3723  switch(type) Line 4583  switch(type)
4583      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
4584      if (type == OP_CLASS)      if (type == OP_CLASS)
4585        {        {
4586        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
4587        jump[0] = NULL;        jump[0] = NULL;
4588        }        }
4589      }      }
4590  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4591    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4592    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4593    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4594    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4595    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);
4596    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4597  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
4598    if (jump[0] != NULL)    if (jump[0] != NULL)
4599      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4600  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4601    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4602    
4603  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4604    case OP_XCLASS:    case OP_XCLASS:
4605    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4606    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
4607  #endif  #endif
4608    
# Line 3757  switch(type) Line 4617  switch(type)
4617      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));
4618      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
4619      label = LABEL();      label = LABEL();
4620      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));
4621      skip_char_back(common);      skip_char_back(common);
4622      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);
4623      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
# Line 3767  switch(type) Line 4627  switch(type)
4627      {      {
4628      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));
4629      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));
4630      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));
4631      }      }
4632    check_start_used_ptr(common);    check_start_used_ptr(common);
4633    return cc + LINK_SIZE;    return cc + LINK_SIZE;
# Line 3776  SLJIT_ASSERT_STOP(); Line 4636  SLJIT_ASSERT_STOP();
4636  return cc;  return cc;
4637  }  }
4638    
4639  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)
4640  {  {
4641  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
4642  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
# Line 3828  if (context.length > 0) Line 4688  if (context.length > 0)
4688    {    {
4689    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
4690    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);
4691    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));
4692    
4693    context.sourcereg = -1;    context.sourcereg = -1;
4694  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
4695    context.ucharptr = 0;    context.ucharptr = 0;
4696  #endif  #endif
4697    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);
4698    return cc;    return cc;
4699    }    }
4700    
4701  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
4702  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_matchingpath(common, *cc, cc + 1, backtracks);
4703  }  }
4704    
4705  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)
4706  {  {
4707  DEFINE_COMPILER;  DEFINE_COMPILER;
4708  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3850  int offset = GET2(cc, 1) << 1; Line 4710  int offset = GET2(cc, 1) << 1;
4710  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4711  if (!common->jscript_compat)  if (!common->jscript_compat)
4712    {    {
4713    if (fallbacks == NULL)    if (backtracks == NULL)
4714      {      {
4715      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
4716      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));
4717      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4718      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
4719      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4720      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
4721      }      }
4722    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)));
4723    }    }
4724  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));
4725  }  }
4726    
4727  /* Forward definitions. */  /* Forward definitions. */
4728  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);  static void compile_matchingpath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
4729  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackingpath(compiler_common *, struct backtrack_common *);
4730    
4731  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
4732    do \    do \
4733      { \      { \
4734      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4735      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4736        return error; \        return error; \
4737      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4738      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4739      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4740      parent->top = fallback; \      parent->top = backtrack; \
4741      } \      } \
4742    while (0)    while (0)
4743    
4744  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
4745    do \    do \
4746      { \      { \
4747      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
4748      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
4749        return; \        return; \
4750      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
4751      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
4752      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
4753      parent->top = fallback; \      parent->top = backtrack; \
4754      } \      } \