/[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 792 by ph10, Wed Dec 7 16:44:48 2011 UTC revision 1002 by zherczeg, Tue Aug 14 09:31:00 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
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
53  system files. */  system files. */
54    
55  #define SLJIT_MALLOC(size) (pcre_malloc)(size)  #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56  #define SLJIT_FREE(ptr) (pcre_free)(ptr)  #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 62  system files. */ Line 62  system files. */
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
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 {
152    /* Pointers first. */    /* Pointers first. */
153    struct sljit_stack *stack;    struct sljit_stack *stack;
154    PCRE_SPTR str;    const pcre_uchar *str;
155    PCRE_SPTR begin;    const pcre_uchar *begin;
156    PCRE_SPTR end;    const pcre_uchar *end;
157    int *offsets;    int *offsets;
158    uschar *ptr;    pcre_uchar *uchar_ptr;
159      pcre_uchar *mark_ptr;
160    /* Everything else after. */    /* Everything else after. */
161    int offsetcount;    int offsetcount;
162    int calllimit;    int calllimit;
163    uschar notbol;    pcre_uint8 notbol;
164    uschar noteol;    pcre_uint8 noteol;
165    uschar notempty;    pcre_uint8 notempty;
166    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
167  } jit_arguments;  } jit_arguments;
168    
169  typedef struct executable_function {  typedef struct executable_functions {
170    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
171    pcre_jit_callback callback;    PUBL(jit_callback) callback;
172    void *userdata;    void *userdata;
173    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
174  } executable_function;  } executable_functions;
175    
176  typedef struct jump_list {  typedef struct jump_list {
177    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 180  typedef struct stub_list { Line 184  typedef struct stub_list {
184    enum stub_types type;    enum stub_types type;
185    int data;    int data;
186    struct sljit_jump *start;    struct sljit_jump *start;
187    struct sljit_label *leave;    struct sljit_label *quit;
188    struct stub_list *next;    struct stub_list *next;
189  } stub_list;  } stub_list;
190    
191  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
192    
193  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
194  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
195  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
196  of its descendants. */  of its descendants. */
197  typedef struct fallback_common {  typedef struct backtrack_common {
198    /* Concatenation stack. */    /* Concatenation stack. */
199    struct fallback_common *prev;    struct backtrack_common *prev;
200    jump_list *nextfallbacks;    jump_list *nextbacktracks;
201    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
202    struct fallback_common *top;    struct backtrack_common *top;
203    jump_list *topfallbacks;    jump_list *topbacktracks;
204    /* Opcode pointer. */    /* Opcode pointer. */
205    uschar *cc;    pcre_uchar *cc;
206  } fallback_common;  } backtrack_common;
207    
208  typedef struct assert_fallback {  typedef struct assert_backtrack {
209    fallback_common common;    backtrack_common common;
210    jump_list *condfailed;    jump_list *condfailed;
211    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
212    int framesize;    int framesize;
213    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
214    int localptr;    int private_data_ptr;
215    /* For iterators. */    /* For iterators. */
216    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
217  } assert_fallback;  } assert_backtrack;
218    
219  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
220    fallback_common common;    backtrack_common common;
221    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
222    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
223    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
224    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
225    /* For greedy ? operator. */    /* For greedy ? operator. */
226    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
227    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
228    union {    union {
229      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
230      jump_list *condfailed;      jump_list *condfailed;
231      assert_fallback *assert;      assert_backtrack *assert;
232      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
233      int framesize;      int framesize;
234    } u;    } u;
235    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
236    int localptr;    int private_data_ptr;
237  } bracket_fallback;  } bracket_backtrack;
238    
239  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
240    fallback_common common;    backtrack_common common;
241    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
242    int localptr;    int private_data_ptr;
243    /* Reverting stack is needed. */    /* Reverting stack is needed. */
244    int framesize;    int framesize;
245    /* Allocated stack size. */    /* Allocated stack size. */
246    int stacksize;    int stacksize;
247  } bracketpos_fallback;  } bracketpos_backtrack;
248    
249  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
250    fallback_common common;    backtrack_common common;
251    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
252  } braminzero_fallback;  } braminzero_backtrack;
253    
254  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
255    fallback_common common;    backtrack_common common;
256    /* Next iteration. */    /* Next iteration. */
257    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
258  } iterator_fallback;  } iterator_backtrack;
259    
260  typedef struct recurse_entry {  typedef struct recurse_entry {
261    struct recurse_entry *next;    struct recurse_entry *next;
# Line 263  typedef struct recurse_entry { Line 267  typedef struct recurse_entry {
267    int start;    int start;
268  } recurse_entry;  } recurse_entry;
269    
270  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
271    fallback_common common;    backtrack_common common;
272  } recurse_fallback;  } recurse_backtrack;
273    
274    #define MAX_RANGE_SIZE 6
275    
276  typedef struct compiler_common {  typedef struct compiler_common {
277    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
278    uschar *start;    pcre_uchar *start;
279    int localsize;  
280    int *localptrs;    /* Maps private data offset to each opcode. */
281    const uschar *fcc;    int *private_data_ptrs;
   sljit_w lcc;  
282    int cbraptr;    int cbraptr;
283      /* OVector starting point. Must be divisible by 2. */
284      int ovector_start;
285      /* Last known position of the requested byte. */
286      int req_char_ptr;
287      /* Head of the last recursion. */
288      int recursive_head;
289      /* First inspected character for partial matching. */
290      int start_used_ptr;
291      /* Starting pointer for partial soft matches. */
292      int hit_start;
293      /* End pointer of the first line. */
294      int first_line_end;
295      /* Points to the marked string. */
296      int mark_ptr;
297    
298      /* Flipped and lower case tables. */
299      const pcre_uint8 *fcc;
300      sljit_w lcc;
301      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
302      int mode;
303      /* Newline control. */
304    int nltype;    int nltype;
305    int newline;    int newline;
306    int bsr_nltype;    int bsr_nltype;
307      /* Dollar endonly. */
308    int endonly;    int endonly;
309      BOOL has_set_som;
310      /* Tables. */
311    sljit_w ctypes;    sljit_w ctypes;
312      int digits[2 + MAX_RANGE_SIZE];
313      /* Named capturing brackets. */
314    sljit_uw name_table;    sljit_uw name_table;
315    sljit_w name_count;    sljit_w name_count;
316    sljit_w name_entry_size;    sljit_w name_entry_size;
317    
318      /* Labels and jump lists. */
319      struct sljit_label *partialmatchlabel;
320      struct sljit_label *quitlabel;
321    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
322    stub_list *stubs;    stub_list *stubs;
323    recurse_entry *entries;    recurse_entry *entries;
324    recurse_entry *currententry;    recurse_entry *currententry;
325      jump_list *partialmatch;
326      jump_list *quit;
327    jump_list *accept;    jump_list *accept;
328    jump_list *calllimit;    jump_list *calllimit;
329    jump_list *stackalloc;    jump_list *stackalloc;
# Line 298  typedef struct compiler_common { Line 335  typedef struct compiler_common {
335    jump_list *casefulcmp;    jump_list *casefulcmp;
336    jump_list *caselesscmp;    jump_list *caselesscmp;
337    BOOL jscript_compat;    BOOL jscript_compat;
338  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
339    BOOL utf8;    BOOL utf;
340  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
341    BOOL useucp;    BOOL use_ucp;
342  #endif  #endif
343    jump_list *utf8readchar;    jump_list *utfreadchar;
344    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
345      jump_list *utfreadtype8;
346  #endif  #endif
347    #endif /* SUPPORT_UTF */
348  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
349    jump_list *getucd;    jump_list *getucd;
350  #endif  #endif
# Line 317  typedef struct compare_context { Line 356  typedef struct compare_context {
356    int length;    int length;
357    int sourcereg;    int sourcereg;
358  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
359    int byteptr;    int ucharptr;
360    union {    union {
361      int asint;      sljit_i asint;
362      short asshort;      sljit_uh asushort;
363    #ifdef COMPILE_PCRE8
364      sljit_ub asbyte;      sljit_ub asbyte;
365      sljit_ub asbytes[4];      sljit_ub asuchars[4];
366    #else
367    #ifdef COMPILE_PCRE16
368        sljit_uh asuchars[2];
369    #endif
370    #endif
371    } c;    } c;
372    union {    union {
373      int asint;      sljit_i asint;
374      short asshort;      sljit_uh asushort;
375    #ifdef COMPILE_PCRE8
376      sljit_ub asbyte;      sljit_ub asbyte;
377      sljit_ub asbytes[4];      sljit_ub asuchars[4];
378    #else
379    #ifdef COMPILE_PCRE16
380        sljit_uh asuchars[2];
381    #endif
382    #endif
383    } oc;    } oc;
384  #endif  #endif
385  } compare_context;  } compare_context;
386    
387  enum {  enum {
388    frame_end = 0,    frame_end = 0,
389    frame_setstrbegin = -1    frame_setstrbegin = -1,
390      frame_setmark = -2
391  };  };
392    
393    /* Undefine sljit macros. */
394    #undef CMP
395    
396  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
397  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
398    
399  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
400  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
401  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
402  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
403  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
404  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
405  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
406  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
407  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
408  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
409    
410  /* Locals layout. */  /* Local space layout. */
411  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
412  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
413  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
414  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
415  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
416  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
417  /* Max limit of recursions. */  /* Max limit of recursions. */
418  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
419  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
420  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
421  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
422  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. */
423  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
424  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
425  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
426  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
427    
428    #ifdef COMPILE_PCRE8
429    #define MOV_UCHAR  SLJIT_MOV_UB
430    #define MOVU_UCHAR SLJIT_MOVU_UB
431    #else
432    #ifdef COMPILE_PCRE16
433    #define MOV_UCHAR  SLJIT_MOV_UH
434    #define MOVU_UCHAR SLJIT_MOVU_UH
435    #else
436    #error Unsupported compiling mode
437    #endif
438    #endif
439    
440  /* Shortcuts. */  /* Shortcuts. */
441  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 397  the start pointers when the end of the c Line 458  the start pointers when the end of the c
458    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))
459  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
460    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
461    #define GET_LOCAL_BASE(dst, dstw, offset) \
462      sljit_get_local_base(compiler, (dst), (dstw), (offset))
463    
464  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
465  {  {
466  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
467  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 409  return cc; Line 472  return cc;
472    
473  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
474   next_opcode   next_opcode
475   get_localspace   get_private_data_length
476   set_localptrs   set_private_data_ptrs
477   get_framesize   get_framesize
478   init_frame   init_frame
479   get_localsize   get_private_data_length_for_copy
480   copy_locals   copy_private_data
481   compile_hotpath   compile_matchingpath
482   compile_fallbackpath   compile_backtrackingpath
483  */  */
484    
485  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
486  {  {
487  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
488  switch(*cc)  switch(*cc)
# Line 468  switch(*cc) Line 531  switch(*cc)
531    case OP_BRAZERO:    case OP_BRAZERO:
532    case OP_BRAMINZERO:    case OP_BRAMINZERO:
533    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
534      case OP_COMMIT:
535    case OP_FAIL:    case OP_FAIL:
536    case OP_ACCEPT:    case OP_ACCEPT:
537    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 475  switch(*cc) Line 539  switch(*cc)
539    return cc + 1;    return cc + 1;
540    
541    case OP_ANYBYTE:    case OP_ANYBYTE:
542  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
543    if (common->utf8) return NULL;    if (common->utf) return NULL;
544  #endif  #endif
545    return cc + 1;    return cc + 1;
546    
# Line 484  switch(*cc) Line 548  switch(*cc)
548    case OP_CHARI:    case OP_CHARI:
549    case OP_NOT:    case OP_NOT:
550    case OP_NOTI:    case OP_NOTI:
   
551    case OP_STAR:    case OP_STAR:
552    case OP_MINSTAR:    case OP_MINSTAR:
553    case OP_PLUS:    case OP_PLUS:
# Line 522  switch(*cc) Line 585  switch(*cc)
585    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
586    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
587    cc += 2;    cc += 2;
588  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
589    if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
590  #endif  #endif
591    return cc;    return cc;
592    
# Line 543  switch(*cc) Line 606  switch(*cc)
606    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
607    case OP_NOTEXACTI:    case OP_NOTEXACTI:
608    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
609    cc += 4;    cc += 2 + IMM2_SIZE;
610  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
611    if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
612  #endif  #endif
613    return cc;    return cc;
614    
615    case OP_NOTPROP:    case OP_NOTPROP:
616    case OP_PROP:    case OP_PROP:
617      return cc + 1 + 2;
618    
619    case OP_TYPEUPTO:    case OP_TYPEUPTO:
620    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
621    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 562  switch(*cc) Line 627  switch(*cc)
627    case OP_RREF:    case OP_RREF:
628    case OP_NRREF:    case OP_NRREF:
629    case OP_CLOSE:    case OP_CLOSE:
630    cc += 3;    cc += 1 + IMM2_SIZE;
631    return cc;    return cc;
632    
633    case OP_CRRANGE:    case OP_CRRANGE:
634    case OP_CRMINRANGE:    case OP_CRMINRANGE:
635    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
636    
637    case OP_CLASS:    case OP_CLASS:
638    case OP_NCLASS:    case OP_NCLASS:
639    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
640    
641  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
642    case OP_XCLASS:    case OP_XCLASS:
643    return cc + GET(cc, 1);    return cc + GET(cc, 1);
644  #endif  #endif
# Line 603  switch(*cc) Line 668  switch(*cc)
668    case OP_CBRAPOS:    case OP_CBRAPOS:
669    case OP_SCBRA:    case OP_SCBRA:
670    case OP_SCBRAPOS:    case OP_SCBRAPOS:
671    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
672    
673      case OP_MARK:
674      return cc + 1 + 2 + cc[1];
675    
676    default:    default:
677    return NULL;    return NULL;
678    }    }
679  }  }
680    
681  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
682        case OP_MINSTAR: \
683        case OP_MINPLUS: \
684        case OP_QUERY: \
685        case OP_MINQUERY: \
686        case OP_MINSTARI: \
687        case OP_MINPLUSI: \
688        case OP_QUERYI: \
689        case OP_MINQUERYI: \
690        case OP_NOTMINSTAR: \
691        case OP_NOTMINPLUS: \
692        case OP_NOTQUERY: \
693        case OP_NOTMINQUERY: \
694        case OP_NOTMINSTARI: \
695        case OP_NOTMINPLUSI: \
696        case OP_NOTQUERYI: \
697        case OP_NOTMINQUERYI:
698    
699    #define CASE_ITERATOR_PRIVATE_DATA_2A \
700        case OP_STAR: \
701        case OP_PLUS: \
702        case OP_STARI: \
703        case OP_PLUSI: \
704        case OP_NOTSTAR: \
705        case OP_NOTPLUS: \
706        case OP_NOTSTARI: \
707        case OP_NOTPLUSI:
708    
709    #define CASE_ITERATOR_PRIVATE_DATA_2B \
710        case OP_UPTO: \
711        case OP_MINUPTO: \
712        case OP_UPTOI: \
713        case OP_MINUPTOI: \
714        case OP_NOTUPTO: \
715        case OP_NOTMINUPTO: \
716        case OP_NOTUPTOI: \
717        case OP_NOTMINUPTOI:
718    
719    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
720        case OP_TYPEMINSTAR: \
721        case OP_TYPEMINPLUS: \
722        case OP_TYPEQUERY: \
723        case OP_TYPEMINQUERY:
724    
725    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
726        case OP_TYPESTAR: \
727        case OP_TYPEPLUS:
728    
729    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
730        case OP_TYPEUPTO: \
731        case OP_TYPEMINUPTO:
732    
733    static int get_class_iterator_size(pcre_uchar *cc)
734  {  {
735  int localspace = 0;  switch(*cc)
736  uschar *alternative;    {
737      case OP_CRSTAR:
738      case OP_CRPLUS:
739      return 2;
740    
741      case OP_CRMINSTAR:
742      case OP_CRMINPLUS:
743      case OP_CRQUERY:
744      case OP_CRMINQUERY:
745      return 1;
746    
747      case OP_CRRANGE:
748      case OP_CRMINRANGE:
749      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
750        return 0;
751      return 2;
752    
753      default:
754      return 0;
755      }
756    }
757    
758    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
759    {
760    int private_data_length = 0;
761    pcre_uchar *alternative;
762    pcre_uchar *end = NULL;
763    int space, size, bracketlen;
764    
765  /* 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. */
766  while (cc < ccend)  while (cc < ccend)
767    {    {
768      space = 0;
769      size = 0;
770      bracketlen = 0;
771    switch(*cc)    switch(*cc)
772      {      {
773        case OP_SET_SOM:
774        common->has_set_som = TRUE;
775        cc += 1;
776        break;
777    
778      case OP_ASSERT:      case OP_ASSERT:
779      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
780      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 629  while (cc < ccend) Line 785  while (cc < ccend)
785      case OP_SBRA:      case OP_SBRA:
786      case OP_SBRAPOS:      case OP_SBRAPOS:
787      case OP_SCOND:      case OP_SCOND:
788      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
789      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
790      break;      break;
791    
792      case OP_CBRAPOS:      case OP_CBRAPOS:
793      case OP_SCBRAPOS:      case OP_SCBRAPOS:
794      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
795      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
796      break;      break;
797    
798      case OP_COND:      case OP_COND:
799      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
800      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
801      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
802        localspace += sizeof(sljit_w);        private_data_length += sizeof(sljit_w);
803        bracketlen = 1 + LINK_SIZE;
804        break;
805    
806        case OP_BRA:
807        bracketlen = 1 + LINK_SIZE;
808        break;
809    
810        case OP_CBRA:
811        case OP_SCBRA:
812        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
813        break;
814    
815        CASE_ITERATOR_PRIVATE_DATA_1
816        space = 1;
817        size = -2;
818        break;
819    
820        CASE_ITERATOR_PRIVATE_DATA_2A
821        space = 2;
822        size = -2;
823        break;
824    
825        CASE_ITERATOR_PRIVATE_DATA_2B
826        space = 2;
827        size = -(2 + IMM2_SIZE);
828        break;
829    
830        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
831        space = 1;
832        size = 1;
833        break;
834    
835        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
836        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
837          space = 2;
838        size = 1;
839        break;
840    
841        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
842        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
843          space = 2;
844        size = 1 + IMM2_SIZE;
845        break;
846    
847        case OP_CLASS:
848        case OP_NCLASS:
849        size += 1 + 32 / sizeof(pcre_uchar);
850        space = get_class_iterator_size(cc + size);
851        break;
852    
853    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
854        case OP_XCLASS:
855        size = GET(cc, 1);
856        space = get_class_iterator_size(cc + size);
857        break;
858    #endif
859    
860        case OP_RECURSE:
861        /* Set its value only once. */
862        if (common->recursive_head == 0)
863          {
864          common->recursive_head = common->ovector_start;
865          common->ovector_start += sizeof(sljit_w);
866          }
867      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
868      break;      break;
869    
870        case OP_MARK:
871        if (common->mark_ptr == 0)
872          {
873          common->mark_ptr = common->ovector_start;
874          common->ovector_start += sizeof(sljit_w);
875          }
876        cc += 1 + 2 + cc[1];
877        break;
878    
879      default:      default:
880      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
881      if (cc == NULL)      if (cc == NULL)
882        return -1;        return -1;
883      break;      break;
884      }      }
885    
886      if (space > 0 && cc >= end)
887        private_data_length += sizeof(sljit_w) * space;
888    
889      if (size != 0)
890        {
891        if (size < 0)
892          {
893          cc += -size;
894    #ifdef SUPPORT_UTF
895          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
896    #endif
897          }
898        else
899          cc += size;
900        }
901    
902      if (bracketlen > 0)
903        {
904        if (cc >= end)
905          {
906          end = bracketend(cc);
907          if (end[-1 - LINK_SIZE] == OP_KET)
908            end = NULL;
909          }
910        cc += bracketlen;
911        }
912    }    }
913  return localspace;  return private_data_length;
914  }  }
915    
916  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
917  {  {
918  uschar *cc = common->start;  pcre_uchar *cc = common->start;
919  uschar *alternative;  pcre_uchar *alternative;
920    pcre_uchar *end = NULL;
921    int space, size, bracketlen;
922    
923  while (cc < ccend)  while (cc < ccend)
924    {    {
925      space = 0;
926      size = 0;
927      bracketlen = 0;
928    switch(*cc)    switch(*cc)
929      {      {
930      case OP_ASSERT:      case OP_ASSERT:
# Line 675  while (cc < ccend) Line 937  while (cc < ccend)
937      case OP_SBRA:      case OP_SBRA:
938      case OP_SBRAPOS:      case OP_SBRAPOS:
939      case OP_SCOND:      case OP_SCOND:
940      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
941      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
942      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
943      break;      break;
944    
945      case OP_CBRAPOS:      case OP_CBRAPOS:
946      case OP_SCBRAPOS:      case OP_SCBRAPOS:
947      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
948      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
949      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
950      break;      break;
951    
952      case OP_COND:      case OP_COND:
# Line 692  while (cc < ccend) Line 954  while (cc < ccend)
954      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
955      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
956        {        {
957        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
958        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
959        }        }
960      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
961        break;
962    
963        case OP_BRA:
964        bracketlen = 1 + LINK_SIZE;
965        break;
966    
967        case OP_CBRA:
968        case OP_SCBRA:
969        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
970        break;
971    
972        CASE_ITERATOR_PRIVATE_DATA_1
973        space = 1;
974        size = -2;
975      break;      break;
976    
977        CASE_ITERATOR_PRIVATE_DATA_2A
978        space = 2;
979        size = -2;
980        break;
981    
982        CASE_ITERATOR_PRIVATE_DATA_2B
983        space = 2;
984        size = -(2 + IMM2_SIZE);
985        break;
986    
987        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
988        space = 1;
989        size = 1;
990        break;
991    
992        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
993        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
994          space = 2;
995        size = 1;
996        break;
997    
998        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
999        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1000          space = 2;
1001        size = 1 + IMM2_SIZE;
1002        break;
1003    
1004        case OP_CLASS:
1005        case OP_NCLASS:
1006        size += 1 + 32 / sizeof(pcre_uchar);
1007        space = get_class_iterator_size(cc + size);
1008        break;
1009    
1010    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1011        case OP_XCLASS:
1012        size = GET(cc, 1);
1013        space = get_class_iterator_size(cc + size);
1014        break;
1015    #endif
1016    
1017      default:      default:
1018      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1019      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1020      break;      break;
1021      }      }
1022    
1023      if (space > 0 && cc >= end)
1024        {
1025        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1026        private_data_ptr += sizeof(sljit_w) * space;
1027        }
1028    
1029      if (size != 0)
1030        {
1031        if (size < 0)
1032          {
1033          cc += -size;
1034    #ifdef SUPPORT_UTF
1035          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1036    #endif
1037          }
1038        else
1039          cc += size;
1040        }
1041    
1042      if (bracketlen > 0)
1043        {
1044        if (cc >= end)
1045          {
1046          end = bracketend(cc);
1047          if (end[-1 - LINK_SIZE] == OP_KET)
1048            end = NULL;
1049          }
1050        cc += bracketlen;
1051        }
1052    }    }
1053  }  }
1054    
1055  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
1056  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1057  {  {
1058  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1059  int length = 0;  int length = 0;
1060  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1061  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1062    BOOL setmark_found = recursive;
1063    
1064  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1065    {    {
# Line 726  while (cc < ccend) Line 1073  while (cc < ccend)
1073    switch(*cc)    switch(*cc)
1074      {      {
1075      case OP_SET_SOM:      case OP_SET_SOM:
1076      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1077      if (!setsom_found)      if (!setsom_found)
1078        {        {
1079        length += 2;        length += 2;
1080        setsom_found = TRUE;        setsom_found = TRUE;
1081        }        }
1082      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1083        break;
1084    
1085        case OP_MARK:
1086        SLJIT_ASSERT(common->mark_ptr != 0);
1087        if (!setmark_found)
1088          {
1089          length += 2;
1090          setmark_found = TRUE;
1091          }
1092        cc += 1 + 2 + cc[1];
1093        break;
1094    
1095        case OP_RECURSE:
1096        if (common->has_set_som && !setsom_found)
1097          {
1098          length += 2;
1099          setsom_found = TRUE;
1100          }
1101        if (common->mark_ptr != 0 && !setmark_found)
1102          {
1103          length += 2;
1104          setmark_found = TRUE;
1105          }
1106        cc += 1 + LINK_SIZE;
1107      break;      break;
1108    
1109      case OP_CBRA:      case OP_CBRA:
# Line 740  while (cc < ccend) Line 1111  while (cc < ccend)
1111      case OP_SCBRA:      case OP_SCBRA:
1112      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1113      length += 3;      length += 3;
1114      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1115      break;      break;
1116    
1117      default:      default:
# Line 758  if (length > 0) Line 1129  if (length > 0)
1129  return -1;  return -1;
1130  }  }
1131    
1132  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
1133  {  {
1134  DEFINE_COMPILER;  DEFINE_COMPILER;
1135  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1136  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1137    BOOL setmark_found = recursive;
1138  int offset;  int offset;
1139    
1140  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1141    SLJIT_UNUSED_ARG(stacktop);
1142  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1143    
1144  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 776  while (cc < ccend) Line 1149  while (cc < ccend)
1149    switch(*cc)    switch(*cc)
1150      {      {
1151      case OP_SET_SOM:      case OP_SET_SOM:
1152      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1153      if (!setsom_found)      if (!setsom_found)
1154        {        {
1155        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 786  while (cc < ccend) Line 1159  while (cc < ccend)
1159        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1160        setsom_found = TRUE;        setsom_found = TRUE;
1161        }        }
1162      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1163        break;
1164    
1165        case OP_MARK:
1166        SLJIT_ASSERT(common->mark_ptr != 0);
1167        if (!setmark_found)
1168          {
1169          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1170          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1171          stackpos += (int)sizeof(sljit_w);
1172          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1173          stackpos += (int)sizeof(sljit_w);
1174          setmark_found = TRUE;
1175          }
1176        cc += 1 + 2 + cc[1];
1177        break;
1178    
1179        case OP_RECURSE:
1180        if (common->has_set_som && !setsom_found)
1181          {
1182          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1183          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1184          stackpos += (int)sizeof(sljit_w);
1185          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1186          stackpos += (int)sizeof(sljit_w);
1187          setsom_found = TRUE;
1188          }
1189        if (common->mark_ptr != 0 && !setmark_found)
1190          {
1191          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1192          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1193          stackpos += (int)sizeof(sljit_w);
1194          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1195          stackpos += (int)sizeof(sljit_w);
1196          setmark_found = TRUE;
1197          }
1198        cc += 1 + LINK_SIZE;
1199      break;      break;
1200    
1201      case OP_CBRA:      case OP_CBRA:
# Line 803  while (cc < ccend) Line 1212  while (cc < ccend)
1212      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1213      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
1214    
1215      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1216      break;      break;
1217    
1218      default:      default:
# Line 816  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1225  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1225  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1226  }  }
1227    
1228  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1229  {  {
1230  int localsize = 2;  int private_data_length = 2;
1231  uschar *alternative;  int size;
1232  /* Calculate the sum of the local variables. */  pcre_uchar *alternative;
1233    /* Calculate the sum of the private machine words. */
1234  while (cc < ccend)  while (cc < ccend)
1235    {    {
1236      size = 0;
1237    switch(*cc)    switch(*cc)
1238      {      {
1239      case OP_ASSERT:      case OP_ASSERT:
# Line 835  while (cc < ccend) Line 1246  while (cc < ccend)
1246      case OP_SBRA:      case OP_SBRA:
1247      case OP_SBRAPOS:      case OP_SBRAPOS:
1248      case OP_SCOND:      case OP_SCOND:
1249      localsize++;      private_data_length++;
1250      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1251      break;      break;
1252    
1253      case OP_CBRA:      case OP_CBRA:
1254      case OP_SCBRA:      case OP_SCBRA:
1255      localsize++;      private_data_length++;
1256      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1257      break;      break;
1258    
1259      case OP_CBRAPOS:      case OP_CBRAPOS:
1260      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1261      localsize += 2;      private_data_length += 2;
1262      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1263      break;      break;
1264    
1265      case OP_COND:      case OP_COND:
1266      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1267      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1268      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1269        localsize++;        private_data_length++;
1270      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1271      break;      break;
1272    
1273        CASE_ITERATOR_PRIVATE_DATA_1
1274        if (PRIVATE_DATA(cc))
1275          private_data_length++;
1276        cc += 2;
1277    #ifdef SUPPORT_UTF
1278        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1279    #endif
1280        break;
1281    
1282        CASE_ITERATOR_PRIVATE_DATA_2A
1283        if (PRIVATE_DATA(cc))
1284          private_data_length += 2;
1285        cc += 2;
1286    #ifdef SUPPORT_UTF
1287        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1288    #endif
1289        break;
1290    
1291        CASE_ITERATOR_PRIVATE_DATA_2B
1292        if (PRIVATE_DATA(cc))
1293          private_data_length += 2;
1294        cc += 2 + IMM2_SIZE;
1295    #ifdef SUPPORT_UTF
1296        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1297    #endif
1298        break;
1299    
1300        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1301        if (PRIVATE_DATA(cc))
1302          private_data_length++;
1303        cc += 1;
1304        break;
1305    
1306        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1307        if (PRIVATE_DATA(cc))
1308          private_data_length += 2;
1309        cc += 1;
1310        break;
1311    
1312        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1313        if (PRIVATE_DATA(cc))
1314          private_data_length += 2;
1315        cc += 1 + IMM2_SIZE;
1316        break;
1317    
1318        case OP_CLASS:
1319        case OP_NCLASS:
1320    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1321        case OP_XCLASS:
1322        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1323    #else
1324        size = 1 + 32 / (int)sizeof(pcre_uchar);
1325    #endif
1326        if (PRIVATE_DATA(cc))
1327          private_data_length += get_class_iterator_size(cc + size);
1328        cc += size;
1329        break;
1330    
1331      default:      default:
1332      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1333      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 866  while (cc < ccend) Line 1335  while (cc < ccend)
1335      }      }
1336    }    }
1337  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1338  return localsize;  return private_data_length;
1339  }  }
1340    
1341  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1342    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1343  {  {
1344  DEFINE_COMPILER;  DEFINE_COMPILER;
1345  int srcw[2];  int srcw[2];
1346  int count;  int count, size;
1347  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1348  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1349  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1350  uschar *alternative;  pcre_uchar *alternative;
1351  enum {  enum {
1352    start,    start,
1353    loop,    loop,
# Line 913  while (status != end) Line 1382  while (status != end)
1382    switch(status)    switch(status)
1383      {      {
1384      case start:      case start:
1385      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1386      count = 1;      count = 1;
1387      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1388      status = loop;      status = loop;
1389      break;      break;
1390    
# Line 939  while (status != end) Line 1408  while (status != end)
1408        case OP_SBRAPOS:        case OP_SBRAPOS:
1409        case OP_SCOND:        case OP_SCOND:
1410        count = 1;        count = 1;
1411        srcw[0] = PRIV(cc);        srcw[0] = PRIVATE_DATA(cc);
1412        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1413        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1414        break;        break;
# Line 948  while (status != end) Line 1417  while (status != end)
1417        case OP_SCBRA:        case OP_SCBRA:
1418        count = 1;        count = 1;
1419        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1420        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1421        break;        break;
1422    
1423        case OP_CBRAPOS:        case OP_CBRAPOS:
1424        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1425        count = 2;        count = 2;
1426        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1427        srcw[0] = PRIV(cc);        srcw[1] = PRIVATE_DATA(cc);
1428        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1429        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1430        break;        break;
1431    
1432        case OP_COND:        case OP_COND:
# Line 966  while (status != end) Line 1435  while (status != end)
1435        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1436          {          {
1437          count = 1;          count = 1;
1438          srcw[0] = PRIV(cc);          srcw[0] = PRIVATE_DATA(cc);
1439          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1440          }          }
1441        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1442        break;        break;
1443    
1444          CASE_ITERATOR_PRIVATE_DATA_1
1445          if (PRIVATE_DATA(cc))
1446            {
1447            count = 1;
1448            srcw[0] = PRIVATE_DATA(cc);
1449            }
1450          cc += 2;
1451    #ifdef SUPPORT_UTF
1452          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1453    #endif
1454          break;
1455    
1456          CASE_ITERATOR_PRIVATE_DATA_2A
1457          if (PRIVATE_DATA(cc))
1458            {
1459            count = 2;
1460            srcw[0] = PRIVATE_DATA(cc);
1461            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1462            }
1463          cc += 2;
1464    #ifdef SUPPORT_UTF
1465          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1466    #endif
1467          break;
1468    
1469          CASE_ITERATOR_PRIVATE_DATA_2B
1470          if (PRIVATE_DATA(cc))
1471            {
1472            count = 2;
1473            srcw[0] = PRIVATE_DATA(cc);
1474            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1475            }
1476          cc += 2 + IMM2_SIZE;
1477    #ifdef SUPPORT_UTF
1478          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1479    #endif
1480          break;
1481    
1482          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1483          if (PRIVATE_DATA(cc))
1484            {
1485            count = 1;
1486            srcw[0] = PRIVATE_DATA(cc);
1487            }
1488          cc += 1;
1489          break;
1490    
1491          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1492          if (PRIVATE_DATA(cc))
1493            {
1494            count = 2;
1495            srcw[0] = PRIVATE_DATA(cc);
1496            srcw[1] = srcw[0] + sizeof(sljit_w);
1497            }
1498          cc += 1;
1499          break;
1500    
1501          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1502          if (PRIVATE_DATA(cc))
1503            {
1504            count = 2;
1505            srcw[0] = PRIVATE_DATA(cc);
1506            srcw[1] = srcw[0] + sizeof(sljit_w);
1507            }
1508          cc += 1 + IMM2_SIZE;
1509          break;
1510    
1511          case OP_CLASS:
1512          case OP_NCLASS:
1513    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1514          case OP_XCLASS:
1515          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1516    #else
1517          size = 1 + 32 / (int)sizeof(pcre_uchar);
1518    #endif
1519          if (PRIVATE_DATA(cc))
1520            switch(get_class_iterator_size(cc + size))
1521              {
1522              case 1:
1523              count = 1;
1524              srcw[0] = PRIVATE_DATA(cc);
1525              break;
1526    
1527              case 2:
1528              count = 2;
1529              srcw[0] = PRIVATE_DATA(cc);
1530              srcw[1] = srcw[0] + sizeof(sljit_w);
1531              break;
1532    
1533              default:
1534              SLJIT_ASSERT_STOP();
1535              break;
1536              }
1537          cc += size;
1538          break;
1539    
1540        default:        default:
1541        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1542        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1074  if (save) Line 1639  if (save)
1639  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1640  }  }
1641    
1642    #undef CASE_ITERATOR_PRIVATE_DATA_1
1643    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1644    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1645    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1646    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1647    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1648    
1649  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1650  {  {
1651  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1084  static SLJIT_INLINE void set_jumps(jump_ Line 1656  static SLJIT_INLINE void set_jumps(jump_
1656  while (list)  while (list)
1657    {    {
1658    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1659    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1660    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1661    list = list->next;    list = list->next;
1662    }    }
# Line 1111  if (list_item) Line 1683  if (list_item)
1683    list_item->type = type;    list_item->type = type;
1684    list_item->data = data;    list_item->data = data;
1685    list_item->start = start;    list_item->start = start;
1686    list_item->leave = LABEL();    list_item->quit = LABEL();
1687    list_item->next = common->stubs;    list_item->next = common->stubs;
1688    common->stubs = list_item;    common->stubs = list_item;
1689    }    }
# Line 1131  while (list_item) Line 1703  while (list_item)
1703      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1704      break;      break;
1705      }      }
1706    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1707    list_item = list_item->next;    list_item = list_item->next;
1708    }    }
1709  common->stubs = NULL;  common->stubs = NULL;
# Line 1174  struct sljit_label *loop; Line 1746  struct sljit_label *loop;
1746  int i;  int i;
1747  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1748  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1749  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1750  if (length < 8)  if (length < 8)
1751    {    {
1752    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1182  if (length < 8) Line 1754  if (length < 8)
1754    }    }
1755  else  else
1756    {    {
1757    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1758    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1759    loop = LABEL();    loop = LABEL();
1760    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1198  struct sljit_label *loop; Line 1770  struct sljit_label *loop;
1770  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1771    
1772  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1773  OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1774  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);
1775    
1776  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1777    if (common->mark_ptr != 0)
1778      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1779  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1780    if (common->mark_ptr != 0)
1781      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1782  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1783  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1784  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1785  /* Unlikely, but possible */  /* Unlikely, but possible */
1786  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1787  loop = LABEL();  loop = LABEL();
1788  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1789  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1790  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1791  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1792    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1793    #endif
1794    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1795  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1796  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1797  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1220  JUMPHERE(earlyexit); Line 1799  JUMPHERE(earlyexit);
1799  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1800  if (topbracket > 1)  if (topbracket > 1)
1801    {    {
1802    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1803    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1804    
1805    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1806    loop = LABEL();    loop = LABEL();
1807    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1808    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1809    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1811    }    }
1812  else  else
1813    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1814  }  }
1815    
1816  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1817    {
1818    DEFINE_COMPILER;
1819    
1820    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1821    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1822    
1823    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1824    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1825    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1826    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1827    
1828    /* Store match begin and end. */
1829    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1830    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1831    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);
1832    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1833    #ifdef COMPILE_PCRE16
1834    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1835    #endif
1836    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1837    
1838    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1839    #ifdef COMPILE_PCRE16
1840    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1841    #endif
1842    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1843    
1844    JUMPTO(SLJIT_JUMP, quit);
1845    }
1846    
1847    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1848    {
1849    /* May destroy TMP1. */
1850    DEFINE_COMPILER;
1851    struct sljit_jump *jump;
1852    
1853    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1854      {
1855      /* The value of -1 must be kept for start_used_ptr! */
1856      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1857      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1858      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1859      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1860      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1861      JUMPHERE(jump);
1862      }
1863    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1864      {
1865      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1866      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1867      JUMPHERE(jump);
1868      }
1869    }
1870    
1871    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1872  {  {
1873  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1874  unsigned int c;  unsigned int c;
1875    
1876  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1877  if (common->utf8)  if (common->utf)
1878    {    {
1879    GETCHAR(c, cc);    GETCHAR(c, cc);
1880    if (c > 127)    if (c > 127)
# Line 1251  if (common->utf8) Line 1885  if (common->utf8)
1885      return FALSE;      return FALSE;
1886  #endif  #endif
1887      }      }
1888    #ifndef COMPILE_PCRE8
1889      return common->fcc[c] != c;
1890    #endif
1891    }    }
1892  else  else
1893  #endif  #endif
1894    c = *cc;    c = *cc;
1895  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1896  }  }
1897    
1898  static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)  static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
1899  {  {
1900  /* Returns with the othercase. */  /* Returns with the othercase. */
1901  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1902  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1903    {    {
1904  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1905    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1271  if (common->utf8 && c > 127) Line 1908  if (common->utf8 && c > 127)
1908  #endif  #endif
1909    }    }
1910  #endif  #endif
1911  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1912  }  }
1913    
1914  static unsigned int char_get_othercase_bit(compiler_common *common, uschar* cc)  static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
1915  {  {
1916  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1917  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1918  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1919  int n;  int n;
1920  #endif  #endif
1921    
1922  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1923  if (common->utf8)  if (common->utf)
1924    {    {
1925    GETCHAR(c, cc);    GETCHAR(c, cc);
1926    if (c <= 127)    if (c <= 127)
# Line 1300  if (common->utf8) Line 1937  if (common->utf8)
1937  else  else
1938    {    {
1939    c = *cc;    c = *cc;
1940    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1941    }    }
1942  #else  #else
1943  c = *cc;  c = *cc;
1944  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1945  #endif  #endif
1946    
1947  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1318  if (c <= 127 && bit == 0x20) Line 1955  if (c <= 127 && bit == 0x20)
1955  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1956    return 0;    return 0;
1957    
1958  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1959  if (common->utf8 && c > 127)  
1960    #ifdef SUPPORT_UTF
1961    if (common->utf && c > 127)
1962    {    {
1963    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1964    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1965      {      {
1966      n--;      n--;
# Line 1329  if (common->utf8 && c > 127) Line 1968  if (common->utf8 && c > 127)
1968      }      }
1969    return (n << 8) | bit;    return (n << 8) | bit;
1970    }    }
1971  #endif  #endif /* SUPPORT_UTF */
1972  return (0 << 8) | bit;  return (0 << 8) | bit;
1973    
1974    #else /* COMPILE_PCRE8 */
1975    
1976    #ifdef COMPILE_PCRE16
1977    #ifdef SUPPORT_UTF
1978    if (common->utf && c > 65535)
1979      {
1980      if (bit >= (1 << 10))
1981        bit >>= 10;
1982      else
1983        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1984      }
1985    #endif /* SUPPORT_UTF */
1986    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1987    #endif /* COMPILE_PCRE16 */
1988    
1989    #endif /* COMPILE_PCRE8 */
1990    }
1991    
1992    static void check_partial(compiler_common *common, BOOL force)
1993    {
1994    /* Checks whether a partial matching is occured. Does not modify registers. */
1995    DEFINE_COMPILER;
1996    struct sljit_jump *jump = NULL;
1997    
1998    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1999    
2000    if (common->mode == JIT_COMPILE)
2001      return;
2002    
2003    if (!force)
2004      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2005    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2006      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2007    
2008    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2009      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2010    else
2011      {
2012      if (common->partialmatchlabel != NULL)
2013        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2014      else
2015        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2016      }
2017    
2018    if (jump != NULL)
2019      JUMPHERE(jump);
2020    }
2021    
2022    static struct sljit_jump *check_str_end(compiler_common *common)
2023    {
2024    /* Does not affect registers. Usually used in a tight spot. */
2025    DEFINE_COMPILER;
2026    struct sljit_jump *jump;
2027    struct sljit_jump *nohit;
2028    struct sljit_jump *return_value;
2029    
2030    if (common->mode == JIT_COMPILE)
2031      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2032    
2033    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2034    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2035      {
2036      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2037      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2038      JUMPHERE(nohit);
2039      return_value = JUMP(SLJIT_JUMP);
2040      }
2041    else
2042      {
2043      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2044      if (common->partialmatchlabel != NULL)
2045        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2046      else
2047        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2048      }
2049    JUMPHERE(jump);
2050    return return_value;
2051  }  }
2052    
2053  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2054  {  {
2055  DEFINE_COMPILER;  DEFINE_COMPILER;
2056  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
2057    
2058    if (common->mode == JIT_COMPILE)
2059      {
2060      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2061      return;
2062      }
2063    
2064    /* Partial matching mode. */
2065    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2066    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2067    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2068      {
2069      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2070      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2071      }
2072    else
2073      {
2074      if (common->partialmatchlabel != NULL)
2075        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2076      else
2077        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2078      }
2079    JUMPHERE(jump);
2080  }  }
2081    
2082  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1344  static void read_char(compiler_common *c Line 2084  static void read_char(compiler_common *c
2084  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2085  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2086  DEFINE_COMPILER;  DEFINE_COMPILER;
2087  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2088  struct sljit_jump *jump;  struct sljit_jump *jump;
2089  #endif  #endif
2090    
2091  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2092  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2093  if (common->utf8)  if (common->utf)
2094    {    {
2095    #ifdef COMPILE_PCRE8
2096    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2097    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2098    #ifdef COMPILE_PCRE16
2099      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2100    #endif
2101    #endif /* COMPILE_PCRE8 */
2102      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2103    JUMPHERE(jump);    JUMPHERE(jump);
2104    }    }
2105  #endif  #endif
2106  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2107  }  }
2108    
2109  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1365  static void peek_char(compiler_common *c Line 2111  static void peek_char(compiler_common *c
2111  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2112  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2113  DEFINE_COMPILER;  DEFINE_COMPILER;
2114  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2115  struct sljit_jump *jump;  struct sljit_jump *jump;
2116  #endif  #endif
2117    
2118  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2119  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2120  if (common->utf8)  if (common->utf)
2121    {    {
2122    #ifdef COMPILE_PCRE8
2123    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2124    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2125    #ifdef COMPILE_PCRE16
2126      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2127    #endif
2128    #endif /* COMPILE_PCRE8 */
2129      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2130    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2131    JUMPHERE(jump);    JUMPHERE(jump);
2132    }    }
# Line 1385  static void read_char8_type(compiler_com Line 2137  static void read_char8_type(compiler_com
2137  {  {
2138  /* 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. */
2139  DEFINE_COMPILER;  DEFINE_COMPILER;
2140  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2141  struct sljit_jump *jump;  struct sljit_jump *jump;
2142  #endif  #endif
2143    
2144  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2145  if (common->utf8)  if (common->utf)
2146    {    {
2147    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2148    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2149    #ifdef COMPILE_PCRE8
2150    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2151    it is a clever early read in most cases. */    it is needed in most cases. */
2152    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2153    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2154    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2155      JUMPHERE(jump);
2156    #else
2157    #ifdef COMPILE_PCRE16
2158      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2159      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2160      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2161    JUMPHERE(jump);    JUMPHERE(jump);
2162      /* Skip low surrogate if necessary. */
2163      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2164      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2165      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2166      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2167      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2168    #endif
2169    #endif /* COMPILE_PCRE8 */
2170    return;    return;
2171    }    }
2172  #endif  #endif
2173  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2174  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2175  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
2176    /* The ctypes array contains only 256 values. */
2177    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2178    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2179    #endif
2180    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2181    #ifdef COMPILE_PCRE16
2182    JUMPHERE(jump);
2183    #endif
2184  }  }
2185    
2186  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2187  {  {
2188  /* Goes one character back. Only affects STR_PTR. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2189  DEFINE_COMPILER;  DEFINE_COMPILER;
2190  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2191  struct sljit_label *label;  struct sljit_label *label;
2192    
2193  if (common->utf8)  if (common->utf)
2194    {    {
2195    label = LABEL();    label = LABEL();
2196    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2197    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2198    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2199    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2200    return;    return;
2201    }    }
2202  #endif  #endif
2203  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2204    if (common->utf)
2205      {
2206      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2207      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2208      /* Skip low surrogate if necessary. */
2209      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2210      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2211      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2212      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2213      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2214      return;
2215      }
2216    #endif
2217    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2218  }  }
2219    
2220  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)
2221  {  {
2222  /* 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. */
2223  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1436  DEFINE_COMPILER; Line 2225  DEFINE_COMPILER;
2225  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2226    {    {
2227    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2228    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));
2229    }    }
2230  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2231    {    {
# Line 1444  else if (nltype == NLTYPE_ANYCRLF) Line 2233  else if (nltype == NLTYPE_ANYCRLF)
2233    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2234    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);
2235    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2236    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));
2237    }    }
2238  else  else
2239    {    {
2240    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2241    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));
2242    }    }
2243  }  }
2244    
2245  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2246  static void do_utf8readchar(compiler_common *common)  
2247    #ifdef COMPILE_PCRE8
2248    static void do_utfreadchar(compiler_common *common)
2249  {  {
2250  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2251  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
2252  DEFINE_COMPILER;  DEFINE_COMPILER;
2253  struct sljit_jump *jump;  struct sljit_jump *jump;
2254    
2255  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2256  /* Searching for the first zero. */  /* Searching for the first zero. */
2257  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
2258  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2259  /* 2 byte sequence */  /* Two byte sequence. */
2260  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2261  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2262  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2263  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2264  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2265  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2266  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2267  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2268  JUMPHERE(jump);  JUMPHERE(jump);
2269    
2270  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
2271  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2272  /* 3 byte sequence */  /* Three byte sequence. */
2273  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2274  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2275  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2276  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2277  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2278  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2279  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2280  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 2);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
2281  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2282  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2283  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2284  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2285  JUMPHERE(jump);  JUMPHERE(jump);
2286    
2287  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2288  jump = JUMP(SLJIT_C_NOT_ZERO);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
 /* 4 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
2289  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2290  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2291  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2292  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2293  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2294  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
2295  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2296  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2297  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2298  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2299  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2300  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2301  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2302  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
2303  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2304  }  }
2305    
2306  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2307  {  {
2308  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2309  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2310  DEFINE_COMPILER;  DEFINE_COMPILER;
2311  struct sljit_jump *jump;  struct sljit_jump *jump;
2312  struct sljit_jump *compare;  struct sljit_jump *compare;
2313    
2314  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2315    
2316  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
2317  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2318  /* 2 byte sequence */  /* Two byte sequence. */
2319  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2320  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2321  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2322  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2323  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1566  sljit_emit_fast_return(compiler, RETURN_ Line 2332  sljit_emit_fast_return(compiler, RETURN_
2332  JUMPHERE(jump);  JUMPHERE(jump);
2333    
2334  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2335  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
2336  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2337  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2338  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2339  }  }
2340    
2341  #endif  #else /* COMPILE_PCRE8 */
2342    
2343    #ifdef COMPILE_PCRE16
2344    static void do_utfreadchar(compiler_common *common)
2345    {
2346    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2347    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2348    DEFINE_COMPILER;
2349    struct sljit_jump *jump;
2350    
2351    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2352    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2353    /* Do nothing, only return. */
2354    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2355    
2356    JUMPHERE(jump);
2357    /* Combine two 16 bit characters. */
2358    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2359    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2360    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2361    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2362    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2363    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2364    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2365    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2366    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2367    }
2368    #endif /* COMPILE_PCRE16 */
2369    
2370    #endif /* COMPILE_PCRE8 */
2371    
2372    #endif /* SUPPORT_UTF */
2373    
2374  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2375    
# Line 1588  DEFINE_COMPILER; Line 2385  DEFINE_COMPILER;
2385    
2386  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2387    
2388  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2389  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2390  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_ucd_stage1);  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
2391  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2392  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2393  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2394  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
2395  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2396  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
2397  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2398  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2399  }  }
# Line 1610  struct sljit_label *newlinelabel = NULL; Line 2407  struct sljit_label *newlinelabel = NULL;
2407  struct sljit_jump *start;  struct sljit_jump *start;
2408  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2409  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2410  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2411  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
2412  #endif  #endif
2413  jump_list *newline = NULL;  jump_list *newline = NULL;
2414  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
2415  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
2416    
2417  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2418      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1624  if (!(hascrorlf || firstline) && (common Line 2421  if (!(hascrorlf || firstline) && (common
2421  if (firstline)  if (firstline)
2422    {    {
2423    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2424    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2425    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2426    
2427    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2428      {      {
2429      mainloop = LABEL();      mainloop = LABEL();
2430      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2431      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2432      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2433      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2434      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);
2435      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);
2436      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      JUMPHERE(end);
2437        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2438      }      }
2439    else    else
2440      {      {
2441      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2442      mainloop = LABEL();      mainloop = LABEL();
2443      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2444      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2445      read_char(common);      read_char(common);
2446      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2447      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2448      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2449        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2450      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2451      }      }
2452    
2453    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2454    }    }
2455    
2456  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1660  start = JUMP(SLJIT_JUMP); Line 2458  start = JUMP(SLJIT_JUMP);
2458  if (newlinecheck)  if (newlinecheck)
2459    {    {
2460    newlinelabel = LABEL();    newlinelabel = LABEL();
2461    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2462    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2463    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2464    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);
2465    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2466    #ifdef COMPILE_PCRE16
2467      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2468    #endif
2469    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2470    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2471    }    }
# Line 1672  if (newlinecheck) Line 2473  if (newlinecheck)
2473  mainloop = LABEL();  mainloop = LABEL();
2474    
2475  /* Increasing the STR_PTR here requires one less jump in the most common case. */  /* Increasing the STR_PTR here requires one less jump in the most common case. */
2476  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2477  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2478  #endif  #endif
2479  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2480    
2481  if (readbyte)  if (readuchar)
2482    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2483    
2484  if (newlinecheck)  if (newlinecheck)
2485    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);
2486    
2487  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2488  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2489  if (common->utf8)  if (common->utf)
2490      {
2491      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2492      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2493      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2494      JUMPHERE(singlechar);
2495      }
2496    #endif
2497    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2498    if (common->utf)
2499    {    {
2500    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2501    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2502      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2503      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2504      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2505    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2506    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
2507    }    }
2508  #endif  #endif
2509  JUMPHERE(start);  JUMPHERE(start);
# Line 1704  if (newlinecheck) Line 2517  if (newlinecheck)
2517  return mainloop;  return mainloop;
2518  }  }
2519    
2520  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2521    {
2522    DEFINE_COMPILER;
2523    struct sljit_label *start;
2524    struct sljit_jump *quit;
2525    struct sljit_jump *found;
2526    pcre_int32 chars[4];
2527    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2528    int location = 0;
2529    pcre_int32 len, c, bit, caseless;
2530    BOOL must_end;
2531    
2532    #ifdef COMPILE_PCRE8
2533    union {
2534        sljit_uh ascombined;
2535        sljit_ub asuchars[2];
2536    } pair;
2537    #else
2538    union {
2539        sljit_ui ascombined;
2540        sljit_uh asuchars[2];
2541    } pair;
2542    #endif
2543    
2544    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2545      return FALSE;
2546    
2547    while (TRUE)
2548      {
2549      caseless = 0;
2550      must_end = TRUE;
2551      switch(*cc)
2552        {
2553        case OP_CHAR:
2554        must_end = FALSE;
2555        cc++;
2556        break;
2557    
2558        case OP_CHARI:
2559        caseless = 1;
2560        must_end = FALSE;
2561        cc++;
2562        break;
2563    
2564        case OP_SOD:
2565        case OP_SOM:
2566        case OP_SET_SOM:
2567        case OP_NOT_WORD_BOUNDARY:
2568        case OP_WORD_BOUNDARY:
2569        case OP_EODN:
2570        case OP_EOD:
2571        case OP_CIRC:
2572        case OP_CIRCM:
2573        case OP_DOLL:
2574        case OP_DOLLM:
2575        /* Zero width assertions. */
2576        cc++;
2577        continue;
2578    
2579        case OP_PLUS:
2580        case OP_MINPLUS:
2581        case OP_POSPLUS:
2582        cc++;
2583        break;
2584    
2585        case OP_EXACT:
2586        cc += 1 + IMM2_SIZE;
2587        break;
2588    
2589        case OP_PLUSI:
2590        case OP_MINPLUSI:
2591        case OP_POSPLUSI:
2592        caseless = 1;
2593        cc++;
2594        break;
2595    
2596        case OP_EXACTI:
2597        caseless = 1;
2598        cc += 1 + IMM2_SIZE;
2599        break;
2600    
2601        default:
2602        return FALSE;
2603        }
2604    
2605      len = 1;
2606    #ifdef SUPPORT_UTF
2607      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2608    #endif
2609    
2610      if (caseless && char_has_othercase(common, cc))
2611        {
2612        caseless = char_get_othercase_bit(common, cc);
2613        if (caseless == 0)
2614          return FALSE;
2615    #ifdef COMPILE_PCRE8
2616        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2617    #else
2618        if ((caseless & 0x100) != 0)
2619          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2620        else
2621          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2622    #endif
2623        }
2624      else
2625        caseless = 0;
2626    
2627      while (len > 0 && location < 2 * 2)
2628        {
2629        c = *cc;
2630        bit = 0;
2631        if (len == (caseless & 0xff))
2632          {
2633          bit = caseless >> 8;
2634          c |= bit;
2635          }
2636    
2637        chars[location] = c;
2638        chars[location + 1] = bit;
2639    
2640        len--;
2641        location += 2;
2642        cc++;
2643        }
2644    
2645      if (location == 2 * 2)
2646        break;
2647      else if (must_end)
2648        return FALSE;
2649      }
2650    
2651    if (firstline)
2652      {
2653      SLJIT_ASSERT(common->first_line_end != 0);
2654      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2655      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2656      }
2657    else
2658      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2659    
2660    start = LABEL();
2661    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2662    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2663    #ifdef COMPILE_PCRE8
2664    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2665    #else /* COMPILE_PCRE8 */
2666    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2667    #endif
2668    
2669    #else /* SLJIT_UNALIGNED */
2670    
2671    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2672    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2673    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2674    #else /* SLJIT_BIG_ENDIAN */
2675    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2676    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2677    #endif /* SLJIT_BIG_ENDIAN */
2678    
2679    #ifdef COMPILE_PCRE8
2680    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2681    #else /* COMPILE_PCRE8 */
2682    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2683    #endif
2684    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2685    
2686    #endif
2687    
2688    if (chars[1] != 0 || chars[3] != 0)
2689      {
2690      pair.asuchars[0] = chars[1];
2691      pair.asuchars[1] = chars[3];
2692      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2693      }
2694    
2695    pair.asuchars[0] = chars[0];
2696    pair.asuchars[1] = chars[2];
2697    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2698    
2699    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2700    JUMPTO(SLJIT_JUMP, start);
2701    JUMPHERE(found);
2702    JUMPHERE(quit);
2703    
2704    if (firstline)
2705      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2706    else
2707      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2708    return TRUE;
2709    }
2710    
2711    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2712  {  {
2713  DEFINE_COMPILER;  DEFINE_COMPILER;
2714  struct sljit_label *start;  struct sljit_label *start;
2715  struct sljit_jump *leave;  struct sljit_jump *quit;
2716  struct sljit_jump *found;  struct sljit_jump *found;
2717  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2718    
2719  if (firstline)  if (firstline)
2720    {    {
2721    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2722    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2723      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2724    }    }
2725    
2726  start = LABEL();  start = LABEL();
2727  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2728  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2729    
2730  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2731    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2732      {
2733      oc = TABLE_GET(first_char, common->fcc, first_char);
2734    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2735      if (first_char > 127 && common->utf)
2736        oc = UCD_OTHERCASE(first_char);
2737    #endif
2738      }
2739    if (first_char == oc)
2740      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2741  else  else
2742    {    {
2743    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2744    if (ispowerof2(bit))    if (ispowerof2(bit))
2745      {      {
2746      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2747      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2748      }      }
2749    else    else
2750      {      {
2751      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, firstbyte);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
2752      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2753      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);
2754      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1744  else Line 2756  else
2756      }      }
2757    }    }
2758    
2759  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #ifdef SUPPORT_UTF8  
 if (common->utf8)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2760  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2761  JUMPHERE(found);  JUMPHERE(found);
2762  JUMPHERE(leave);  JUMPHERE(quit);
2763    
2764  if (firstline)  if (firstline)
2765    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2766  }  }
2767    
2768  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 1767  DEFINE_COMPILER; Line 2771  DEFINE_COMPILER;
2771  struct sljit_label *loop;  struct sljit_label *loop;
2772  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2773  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2774  struct sljit_jump *leave;  struct sljit_jump *quit;
2775  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2776  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2777  jump_list *newline = NULL;  jump_list *newline = NULL;
2778    
2779  if (firstline)  if (firstline)
2780    {    {
2781    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2782    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2783      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2784    }    }
2785    
2786  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1786  if (common->nltype == NLTYPE_FIXED && co Line 2791  if (common->nltype == NLTYPE_FIXED && co
2791    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));
2792    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2793    
2794    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2795    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);
2796    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2797    #ifdef COMPILE_PCRE16
2798      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2799    #endif
2800    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2801    
2802    loop = LABEL();    loop = LABEL();
2803    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2804    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2805    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2806    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2807    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);
2808    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);
2809    
2810    JUMPHERE(leave);    JUMPHERE(quit);
2811    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2812    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2813    
# Line 1823  set_jumps(newline, loop); Line 2831  set_jumps(newline, loop);
2831    
2832  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2833    {    {
2834    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2835    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2836    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2837    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2838    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);
2839    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2840    #ifdef COMPILE_PCRE16
2841      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2842    #endif
2843    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2844    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2845    JUMPHERE(leave);    JUMPHERE(quit);
2846    }    }
2847  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2848  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2849    
2850  if (firstline)  if (firstline)
2851    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2852  }  }
2853    
2854  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)
2855  {  {
2856  DEFINE_COMPILER;  DEFINE_COMPILER;
2857  struct sljit_label *start;  struct sljit_label *start;
2858  struct sljit_jump *leave;  struct sljit_jump *quit;
2859  struct sljit_jump *found;  struct sljit_jump *found;
2860    #ifndef COMPILE_PCRE8
2861    struct sljit_jump *jump;
2862    #endif
2863    
2864  if (firstline)  if (firstline)
2865    {    {
2866    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2867    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2868      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2869    }    }
2870    
2871  start = LABEL();  start = LABEL();
2872  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2873  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2874  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2875  if (common->utf8)  if (common->utf)
2876    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2877  #endif  #endif
2878    #ifndef COMPILE_PCRE8
2879    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2880    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2881    JUMPHERE(jump);
2882    #endif
2883  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2884  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2885  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1867  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2887  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2887  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);
2888  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2889    
2890  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2891  if (common->utf8)  if (common->utf)
2892    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2893  #endif  #endif
2894  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2895  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2896  if (common->utf8)  if (common->utf)
2897    {    {
2898    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2899    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2900      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2901      }
2902    #endif
2903    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2904    if (common->utf)
2905      {
2906      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2907      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2908      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2909      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2910      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2911    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2912    }    }
2913  #endif  #endif
2914  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2915  JUMPHERE(found);  JUMPHERE(found);
2916  JUMPHERE(leave);  JUMPHERE(quit);
2917    
2918  if (firstline)  if (firstline)
2919    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2920  }  }
2921    
2922  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uint16 reqbyte, BOOL has_firstbyte)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
2923  {  {
2924  DEFINE_COMPILER;  DEFINE_COMPILER;
2925  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1897  struct sljit_jump *alreadyfound; Line 2928  struct sljit_jump *alreadyfound;
2928  struct sljit_jump *found;  struct sljit_jump *found;
2929  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2930  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2931  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2932    
2933  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2934    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2935  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2936  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2937  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2938    
2939  if (has_firstbyte)  if (has_firstchar)
2940    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2941  else  else
2942    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2943    
2944  loop = LABEL();  loop = LABEL();
2945  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2946    
2947  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2948  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2949    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2950      {
2951      oc = TABLE_GET(req_char, common->fcc, req_char);
2952    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2953      if (req_char > 127 && common->utf)
2954        oc = UCD_OTHERCASE(req_char);
2955    #endif
2956      }
2957    if (req_char == oc)
2958      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2959  else  else
2960    {    {
2961    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2962    if (ispowerof2(bit))    if (ispowerof2(bit))
2963      {      {
2964      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2965      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2966      }      }
2967    else    else
2968      {      {
2969      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2970      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2971      }      }
2972    }    }
2973  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2974  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2975    
2976  JUMPHERE(found);  JUMPHERE(found);
2977  if (foundoc)  if (foundoc)
2978    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2979  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2980  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2981  JUMPHERE(toolong);  JUMPHERE(toolong);
2982  return notfound;  return notfound;
# Line 1949  DEFINE_COMPILER; Line 2988  DEFINE_COMPILER;
2988  struct sljit_jump *jump;  struct sljit_jump *jump;
2989  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2990    
2991  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2992  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2993    GET_LOCAL_BASE(TMP3, 0, 0);
2994    
2995  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2996  mainloop = LABEL();  mainloop = LABEL();
2997  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2998  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);
2999  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3000  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3001  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));
3002  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));
# Line 1976  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 3016  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
3016  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3017    
3018  JUMPHERE(jump);  JUMPHERE(jump);
3019    if (common->mark_ptr != 0)
3020      {
3021      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3022      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3023      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3024      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3025      JUMPTO(SLJIT_JUMP, mainloop);
3026    
3027      JUMPHERE(jump);
3028      }
3029    
3030  /* Unknown command. */  /* Unknown command. */
3031  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3032  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 1984  JUMPTO(SLJIT_JUMP, mainloop); Line 3035  JUMPTO(SLJIT_JUMP, mainloop);
3035  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3036  {  {
3037  DEFINE_COMPILER;  DEFINE_COMPILER;
3038  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3039  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3040  struct sljit_jump *jump;  struct sljit_jump *jump;
3041  #endif  #endif
3042    
3043  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3044    
3045  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3046  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3047  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3048  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));
3049  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3050  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3051  skip_char_back(common);  skip_char_back(common);
3052    check_start_used_ptr(common);
3053  read_char(common);  read_char(common);
3054    
3055  /* Testing char type. */  /* Testing char type. */
3056  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3057  if (common->useucp)  if (common->use_ucp)
3058    {    {
3059    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3060    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2019  if (common->useucp) Line 3071  if (common->useucp)
3071  else  else
3072  #endif  #endif
3073    {    {
3074  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3075      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3076    #elif defined SUPPORT_UTF
3077    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3078    jump = NULL;    jump = NULL;
3079    if (common->utf8)    if (common->utf)
3080      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3081  #endif  #endif /* COMPILE_PCRE8 */
3082    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3083    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3084    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3085    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3086  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3087      JUMPHERE(jump);
3088    #elif defined SUPPORT_UTF
3089    if (jump != NULL)    if (jump != NULL)
3090      JUMPHERE(jump);      JUMPHERE(jump);
3091  #endif  #endif /* COMPILE_PCRE8 */
3092    }    }
3093  JUMPHERE(beginend);  JUMPHERE(skipread);
3094    
3095  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3096  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3097  peek_char(common);  peek_char(common);
3098    
3099  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3100  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3101  if (common->useucp)  if (common->use_ucp)
3102    {    {
3103    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3104    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2058  if (common->useucp) Line 3114  if (common->useucp)
3114  else  else
3115  #endif  #endif
3116    {    {
3117  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3118      /* TMP2 may be destroyed by peek_char. */
3119      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3120      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3121    #elif defined SUPPORT_UTF
3122    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3123    jump = NULL;    jump = NULL;
3124    if (common->utf8)    if (common->utf)
3125      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3126  #endif  #endif
3127    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3128    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3129    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3130  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3131      JUMPHERE(jump);
3132    #elif defined SUPPORT_UTF
3133    if (jump != NULL)    if (jump != NULL)
3134      JUMPHERE(jump);      JUMPHERE(jump);
3135  #endif  #endif /* COMPILE_PCRE8 */
3136    }    }
3137  JUMPHERE(beginend);  JUMPHERE(skipread);
3138    
3139  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3140  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3141  }  }
3142    
3143    /*
3144      range format:
3145    
3146      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3147      ranges[1] = first bit (0 or 1)
3148      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3149    */
3150    
3151    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3152    {
3153    DEFINE_COMPILER;
3154    struct sljit_jump *jump;
3155    
3156    if (ranges[0] < 0)
3157      return FALSE;
3158    
3159    switch(ranges[0])
3160      {
3161      case 1:
3162      if (readch)
3163        read_char(common);
3164      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3165      return TRUE;
3166    
3167      case 2:
3168      if (readch)
3169        read_char(common);
3170      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3171      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3172      return TRUE;
3173    
3174      case 4:
3175      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3176        {
3177        if (readch)
3178          read_char(common);
3179        if (ranges[1] != 0)
3180          {
3181          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3182          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3183          }
3184        else
3185          {
3186          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3187          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3188          JUMPHERE(jump);
3189          }
3190        return TRUE;
3191        }
3192      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3193        {
3194        if (readch)
3195          read_char(common);
3196        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3197        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3198        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3199        return TRUE;
3200        }
3201      return FALSE;
3202    
3203      default:
3204      return FALSE;
3205      }
3206    }
3207    
3208    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3209    {
3210    int i, bit, length;
3211    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3212    
3213    bit = ctypes[0] & flag;
3214    ranges[0] = -1;
3215    ranges[1] = bit != 0 ? 1 : 0;
3216    length = 0;
3217    
3218    for (i = 1; i < 256; i++)
3219      if ((ctypes[i] & flag) != bit)
3220        {
3221        if (length >= MAX_RANGE_SIZE)
3222          return;
3223        ranges[2 + length] = i;
3224        length++;
3225        bit ^= flag;
3226        }
3227    
3228    if (bit != 0)
3229      {
3230      if (length >= MAX_RANGE_SIZE)
3231        return;
3232      ranges[2 + length] = 256;
3233      length++;
3234      }
3235    ranges[0] = length;
3236    }
3237    
3238    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3239    {
3240    int ranges[2 + MAX_RANGE_SIZE];
3241    pcre_uint8 bit, cbit, all;
3242    int i, byte, length = 0;
3243    
3244    bit = bits[0] & 0x1;
3245    ranges[1] = bit;
3246    /* Can be 0 or 255. */
3247    all = -bit;
3248    
3249    for (i = 0; i < 256; )
3250      {
3251      byte = i >> 3;
3252      if ((i & 0x7) == 0 && bits[byte] == all)
3253        i += 8;
3254      else
3255        {
3256        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3257        if (cbit != bit)
3258          {
3259          if (length >= MAX_RANGE_SIZE)
3260            return FALSE;
3261          ranges[2 + length] = i;
3262          length++;
3263          bit = cbit;
3264          all = -cbit;
3265          }
3266        i++;
3267        }
3268      }
3269    
3270    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3271      {
3272      if (length >= MAX_RANGE_SIZE)
3273        return FALSE;
3274      ranges[2 + length] = 256;
3275      length++;
3276      }
3277    ranges[0] = length;
3278    
3279    return check_ranges(common, ranges, backtracks, FALSE);
3280    }
3281    
3282  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3283  {  {
3284  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3285  DEFINE_COMPILER;  DEFINE_COMPILER;
3286    
3287  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3288    
3289  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3290  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);
3291  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3292  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);
3293  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3294  if (common->utf8)  #ifdef COMPILE_PCRE8
3295    if (common->utf)
3296    {    {
3297    #endif
3298    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3299    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3300    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);
3301    #ifdef COMPILE_PCRE8
3302    }    }
3303  #endif  #endif
3304    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3305  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3306  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3307  }  }
# Line 2106  static void check_hspace(compiler_common Line 3311  static void check_hspace(compiler_common
3311  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3312  DEFINE_COMPILER;  DEFINE_COMPILER;
3313    
3314  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3315    
3316  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);
3317  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3318  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);
3319  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3320  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);
3321  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3322  if (common->utf8)  #ifdef COMPILE_PCRE8
3323    if (common->utf)
3324    {    {
3325    #endif
3326    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3327    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);
3328    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2129  if (common->utf8) Line 3336  if (common->utf8)
3336    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);
3337    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3338    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);
3339    #ifdef COMPILE_PCRE8
3340    }    }
3341  #endif  #endif
3342    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3343  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3344    
3345  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2141  static void check_vspace(compiler_common Line 3350  static void check_vspace(compiler_common
3350  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3351  DEFINE_COMPILER;  DEFINE_COMPILER;
3352    
3353  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3354    
3355  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3356  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);
3357  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3358  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);
3359  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3360  if (common->utf8)  #ifdef COMPILE_PCRE8
3361    if (common->utf)
3362    {    {
3363    #endif
3364    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3365    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3366    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);
3367    #ifdef COMPILE_PCRE8
3368    }    }
3369  #endif  #endif
3370    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3371  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3372    
3373  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2169  DEFINE_COMPILER; Line 3382  DEFINE_COMPILER;
3382  struct sljit_jump *jump;  struct sljit_jump *jump;
3383  struct sljit_label *label;  struct sljit_label *label;
3384    
3385  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3386  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3387  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3388  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3389  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3390  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3391    
3392  label = LABEL();  label = LABEL();
3393  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3394  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3395  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3396  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, IN_UCHARS(1));
3397  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3398    
3399  JUMPHERE(jump);  JUMPHERE(jump);
3400  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3401  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3402  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3403  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2198  DEFINE_COMPILER; Line 3411  DEFINE_COMPILER;
3411  struct sljit_jump *jump;  struct sljit_jump *jump;
3412  struct sljit_label *label;  struct sljit_label *label;
3413    
3414  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3415  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3416    
3417  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3418  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3419  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3420  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3421  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3422  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3423    
3424  label = LABEL();  label = LABEL();
3425  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3426  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3427    #ifndef COMPILE_PCRE8
3428    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3429    #endif
3430  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3431    #ifndef COMPILE_PCRE8
3432    JUMPHERE(jump);
3433    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3434    #endif
3435  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3436    #ifndef COMPILE_PCRE8
3437    JUMPHERE(jump);
3438    #endif
3439  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3440  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, IN_UCHARS(1));
3441  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3442    
3443  JUMPHERE(jump);  JUMPHERE(jump);
3444  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3445  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3446  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3447  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2229  sljit_emit_fast_return(compiler, RETURN_ Line 3452  sljit_emit_fast_return(compiler, RETURN_
3452  #undef CHAR1  #undef CHAR1
3453  #undef CHAR2  #undef CHAR2
3454    
3455  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3456    
3457  static uschar * SLJIT_CALL do_utf8caselesscmp(uschar *src1, jit_arguments *args, uschar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3458  {  {
3459  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3460  int c1, c2;  int c1, c2;
3461  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3462  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3463    
3464  while (src1 < end1)  while (src1 < end1)
3465    {    {
3466    if (src2 >= end2)    if (src2 >= end2)
3467      return 0;      return (pcre_uchar*)1;
3468    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3469    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3470    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
3471    }    }
3472  return src2;  return src2;
3473  }  }
3474    
3475  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3476    
3477  static uschar *byte_sequence_compare(compiler_common *common, BOOL caseless, uschar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
3478      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3479  {  {
3480  DEFINE_COMPILER;  DEFINE_COMPILER;
3481  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3482  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3483  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3484  int utf8length;  int utflength;
3485  #endif  #endif
3486    
3487  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2268  if (caseless && char_has_othercase(commo Line 3489  if (caseless && char_has_othercase(commo
3489    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3490    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3491    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3492    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
3493      othercasechar = cc + (othercasebit >> 8);
3494    othercasebit &= 0xff;    othercasebit &= 0xff;
3495    #else
3496    #ifdef COMPILE_PCRE16
3497      othercasechar = cc + (othercasebit >> 9);
3498      if ((othercasebit & 0x100) != 0)
3499        othercasebit = (othercasebit & 0xff) << 8;
3500      else
3501        othercasebit &= 0xff;
3502    #endif
3503    #endif
3504    }    }
3505    
3506  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3507    {    {
3508    #ifdef COMPILE_PCRE8
3509  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3510    if (context->length >= 4)    if (context->length >= 4)
3511      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3512    else if (context->length >= 2)    else if (context->length >= 2)
3513      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3514    else    else
3515  #endif  #endif
3516      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3517    #else
3518    #ifdef COMPILE_PCRE16
3519    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3520      if (context->length >= 4)
3521        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3522      else
3523    #endif
3524        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3525    #endif
3526    #endif /* COMPILE_PCRE8 */
3527    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3528    }    }
3529    
3530  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3531  utf8length = 1;  utflength = 1;
3532  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3533    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3534    
3535  do  do
3536    {    {
3537  #endif  #endif
3538    
3539    context->length--;    context->length -= IN_UCHARS(1);
3540  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3541    
3542    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3543    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3544      {      {
3545      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3546      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3547      }      }
3548    else    else
3549      {      {
3550      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3551      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3552      }      }
3553    context->byteptr++;    context->ucharptr++;
3554    
3555    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
3556      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3557    #else
3558      if (context->ucharptr >= 2 || context->length == 0)
3559    #endif
3560      {      {
3561      if (context->length >= 4)      if (context->length >= 4)
3562        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);
3563    #ifdef COMPILE_PCRE8
3564      else if (context->length >= 2)      else if (context->length >= 2)
3565        OP1(SLJIT_MOV_SH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3566      else if (context->length >= 1)      else if (context->length >= 1)
3567        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);
3568    #else
3569        else if (context->length >= 2)
3570          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3571    #endif
3572      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3573    
3574      switch(context->byteptr)      switch(context->ucharptr)
3575        {        {
3576        case 4:        case 4 / sizeof(pcre_uchar):
3577        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3578          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);
3579        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));
3580        break;        break;
3581    
3582        case 2:        case 2 / sizeof(pcre_uchar):
3583        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3584          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asshort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
3585        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asshort | context->oc.asshort));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
3586        break;        break;
3587    
3588    #ifdef COMPILE_PCRE8
3589        case 1:        case 1:
3590        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3591          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);
3592        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));
3593        break;        break;
3594    #endif
3595    
3596        default:        default:
3597        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3598        break;        break;
3599        }        }
3600      context->byteptr = 0;      context->ucharptr = 0;
3601      }      }
3602    
3603  #else  #else
3604    
3605    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
3606    #ifdef COMPILE_PCRE8
3607    if (context->length > 0)    if (context->length > 0)
3608      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);
3609    #else
3610      if (context->length > 0)
3611        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3612    #endif
3613    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3614    
3615    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3616      {      {
3617      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3618      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));
3619      }      }
3620    else    else
3621      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));
3622    
3623  #endif  #endif
3624    
3625    cc++;    cc++;
3626  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3627    utf8length--;    utflength--;
3628    }    }
3629  while (utf8length > 0);  while (utflength > 0);
3630  #endif  #endif
3631    
3632  return cc;  return cc;
3633  }  }
3634    
3635  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3636    
3637  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
3638    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2396  return cc; Line 3654  return cc;
3654      } \      } \
3655    charoffset = (value);    charoffset = (value);
3656    
3657  static void compile_xclass_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3658  {  {
3659  DEFINE_COMPILER;  DEFINE_COMPILER;
3660  jump_list *found = NULL;  jump_list *found = NULL;
3661  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3662  unsigned int c;  unsigned int c;
3663  int compares;  int compares;
3664  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3665  uschar *ccbegin;  pcre_uchar *ccbegin;
3666  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3667  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3668  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2414  unsigned int typeoffset; Line 3672  unsigned int typeoffset;
3672  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3673  unsigned int charoffset;  unsigned int charoffset;
3674    
3675  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF must be defined, we are
3676  check_input_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3677    detect_partial_match(common, backtracks);
3678  read_char(common);  read_char(common);
3679    
3680  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
3681    {    {
3682    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3683    if (common->utf8)  #ifndef COMPILE_PCRE8
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685    #elif defined SUPPORT_UTF
3686      if (common->utf)
3687      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3688    #endif
3689    
3690    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3691    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3692    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3693    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3694    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3695    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3696        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3697        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3698        }
3699    
3700    if (common->utf8)  #ifndef COMPILE_PCRE8
3701      JUMPHERE(jump);
3702    #elif defined SUPPORT_UTF
3703      if (common->utf)
3704      JUMPHERE(jump);      JUMPHERE(jump);
3705    #endif
3706    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3707  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3708    charsaved = TRUE;    charsaved = TRUE;
3709  #endif  #endif
3710    cc += 32;    cc += 32 / sizeof(pcre_uchar);
3711    }    }
3712    
3713  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2449  while (*cc != XCL_END) Line 3719  while (*cc != XCL_END)
3719    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3720      {      {
3721      cc += 2;      cc += 2;
3722  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3723      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3724  #endif  #endif
3725  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3726      needschar = TRUE;      needschar = TRUE;
# Line 2459  while (*cc != XCL_END) Line 3729  while (*cc != XCL_END)
3729    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3730      {      {
3731      cc += 2;      cc += 2;
3732  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3733      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3734  #endif  #endif
3735      cc++;      cc++;
3736  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3737      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
3738  #endif  #endif
3739  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3740      needschar = TRUE;      needschar = TRUE;
# Line 2534  if (needstype || needsscript) Line 3804  if (needstype || needsscript)
3804      {      {
3805      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3806        {        {
3807        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, script));        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3808        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3809        }        }
3810      else      else
3811        {        {
3812        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3813        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, script));        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3814        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3815        }        }
3816      }      }
# Line 2558  typeoffset = 0; Line 3828  typeoffset = 0;
3828  while (*cc != XCL_END)  while (*cc != XCL_END)
3829    {    {
3830    compares--;    compares--;
3831    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3832    jump = NULL;    jump = NULL;
3833    
3834    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3835      {      {
3836      cc ++;      cc ++;
3837  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3838      if (common->utf8)      if (common->utf)
3839        {        {
3840        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3841        }        }
# Line 2595  while (*cc != XCL_END) Line 3865  while (*cc != XCL_END)
3865    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3866      {      {
3867      cc ++;      cc ++;
3868  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3869      if (common->utf8)      if (common->utf)
3870        {        {
3871        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3872        }        }
# Line 2604  while (*cc != XCL_END) Line 3874  while (*cc != XCL_END)
3874  #endif  #endif
3875        c = *cc++;        c = *cc++;
3876      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3877  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3878      if (common->utf8)      if (common->utf)
3879        {        {
3880        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3881        }        }
# Line 2640  while (*cc != XCL_END) Line 3910  while (*cc != XCL_END)
3910      switch(*cc)      switch(*cc)
3911        {        {
3912        case PT_ANY:        case PT_ANY:
3913        if (list != fallbacks)        if (list != backtracks)
3914          {          {
3915          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))
3916            continue;            continue;
# Line 2661  while (*cc != XCL_END) Line 3931  while (*cc != XCL_END)
3931        break;        break;
3932    
3933        case PT_GC:        case PT_GC:
3934        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3935        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3936        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, _pcre_ucp_typerange[(int)cc[1] * 2 + 1] - c);        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
3937        break;        break;
3938    
3939        case PT_PC:        case PT_PC:
# Line 2713  while (*cc != XCL_END) Line 3983  while (*cc != XCL_END)
3983  #endif  #endif
3984    
3985    if (jump != NULL)    if (jump != NULL)
3986      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3987    }    }
3988    
3989  if (found != NULL)  if (found != NULL)
# Line 2725  if (found != NULL) Line 3995  if (found != NULL)
3995    
3996  #endif  #endif
3997    
3998  static uschar *compile_char1_hotpath(compiler_common *common, uschar type, uschar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3999  {  {
4000  DEFINE_COMPILER;  DEFINE_COMPILER;
4001  int length;  int length;
4002  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4003  compare_context context;  compare_context context;
4004  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4005  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4006  struct sljit_label *label;  struct sljit_label *label;
4007  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4008  uschar propdata[5];  pcre_uchar propdata[5];
4009  #endif  #endif
4010  #endif  #endif
4011    
# Line 2744  switch(type) Line 4014  switch(type)
4014    case OP_SOD:    case OP_SOD:
4015    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4016    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));
4017    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));
4018    return cc;    return cc;
4019    
4020    case OP_SOM:    case OP_SOM:
4021    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4022    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));
4023    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));
4024    return cc;    return cc;
4025    
4026    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4027    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4028    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4029    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));
4030    return cc;    return cc;
4031    
4032    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4033    case OP_DIGIT:    case OP_DIGIT:
4034    check_input_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4035    read_char8_type(common);    if (common->digits[0] == -2)
4036    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4037    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4038      /* Flip the starting bit in the negative case. */
4039      if (type == OP_NOT_DIGIT)
4040        common->digits[1] ^= 1;
4041      if (!check_ranges(common, common->digits, backtracks, TRUE))
4042        {
4043        read_char8_type(common);
4044        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4045        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4046        }
4047      if (type == OP_NOT_DIGIT)
4048        common->digits[1] ^= 1;
4049    return cc;    return cc;
4050    
4051    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4052    case OP_WHITESPACE:    case OP_WHITESPACE:
4053    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4054    read_char8_type(common);    read_char8_type(common);
4055    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);
4056    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));
4057    return cc;    return cc;
4058    
4059    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4060    case OP_WORDCHAR:    case OP_WORDCHAR:
4061    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4062    read_char8_type(common);    read_char8_type(common);
4063    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);
4064    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));
4065    return cc;    return cc;
4066    
4067    case OP_ANY:    case OP_ANY:
4068    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4069    read_char(common);    read_char(common);
4070    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4071      {      {
4072      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4073      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4074      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4075      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      else
4076      JUMPHERE(jump[1]);        jump[1] = check_str_end(common);
4077    
4078        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4079        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4080        if (jump[1] != NULL)
4081          JUMPHERE(jump[1]);
4082      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4083      }      }
4084    else    else
4085      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4086    return cc;    return cc;
4087    
4088    case OP_ALLANY:    case OP_ALLANY:
4089    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4090  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4091    if (common->utf8)    if (common->utf)
4092      {      {
4093      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4094      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4095    #ifdef COMPILE_PCRE8
4096      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4097      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4098      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4099    #else /* COMPILE_PCRE8 */
4100    #ifdef COMPILE_PCRE16
4101        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4102        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4103        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4104        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4105        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4106        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4107    #endif /* COMPILE_PCRE16 */
4108    #endif /* COMPILE_PCRE8 */
4109      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4110      return cc;      return cc;
4111      }      }
4112