/[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 736 by zherczeg, Sun Oct 16 15:48:03 2011 UTC revision 1009 by zherczeg, Wed Aug 22 12:01:22 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) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
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 79  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 105  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  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
174    } executable_functions;
175    
176  typedef struct jump_list {  typedef struct jump_list {
177    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 176  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 259  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;
282    sljit_w lcc;    /* Tells whether the capturing bracket is optimized. */
283      pcre_uint8 *optimized_cbracket;
284      /* Starting offset of private data for capturing brackets. */
285    int cbraptr;    int cbraptr;
286      /* OVector starting point. Must be divisible by 2. */
287      int ovector_start;
288      /* Last known position of the requested byte. */
289      int req_char_ptr;
290      /* Head of the last recursion. */
291      int recursive_head;
292      /* First inspected character for partial matching. */
293      int start_used_ptr;
294      /* Starting pointer for partial soft matches. */
295      int hit_start;
296      /* End pointer of the first line. */
297      int first_line_end;
298      /* Points to the marked string. */
299      int mark_ptr;
300    
301      /* Flipped and lower case tables. */
302      const pcre_uint8 *fcc;
303      sljit_w lcc;
304      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
305      int mode;
306      /* Newline control. */
307    int nltype;    int nltype;
308    int newline;    int newline;
309    int bsr_nltype;    int bsr_nltype;
310      /* Dollar endonly. */
311    int endonly;    int endonly;
312      BOOL has_set_som;
313      /* Tables. */
314    sljit_w ctypes;    sljit_w ctypes;
315      int digits[2 + MAX_RANGE_SIZE];
316      /* Named capturing brackets. */
317      sljit_uw name_table;
318      sljit_w name_count;
319      sljit_w name_entry_size;
320    
321      /* Labels and jump lists. */
322      struct sljit_label *partialmatchlabel;
323      struct sljit_label *quitlabel;
324    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
325    stub_list *stubs;    stub_list *stubs;
326    recurse_entry *entries;    recurse_entry *entries;
327    recurse_entry *currententry;    recurse_entry *currententry;
328      jump_list *partialmatch;
329      jump_list *quit;
330    jump_list *accept;    jump_list *accept;
331    jump_list *calllimit;    jump_list *calllimit;
332    jump_list *stackalloc;    jump_list *stackalloc;
# Line 291  typedef struct compiler_common { Line 338  typedef struct compiler_common {
338    jump_list *casefulcmp;    jump_list *casefulcmp;
339    jump_list *caselesscmp;    jump_list *caselesscmp;
340    BOOL jscript_compat;    BOOL jscript_compat;
341  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
342    BOOL utf8;    BOOL utf;
343  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
344    BOOL useucp;    BOOL use_ucp;
345  #endif  #endif
346    jump_list *utf8readchar;    jump_list *utfreadchar;
347    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
348      jump_list *utfreadtype8;
349  #endif  #endif
350    #endif /* SUPPORT_UTF */
351  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
352    jump_list *getucd;    jump_list *getucd;
353  #endif  #endif
# Line 310  typedef struct compare_context { Line 359  typedef struct compare_context {
359    int length;    int length;
360    int sourcereg;    int sourcereg;
361  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
362    int byteptr;    int ucharptr;
363    union {    union {
364      int asint;      sljit_i asint;
365      short asshort;      sljit_uh asushort;
366    #ifdef COMPILE_PCRE8
367      sljit_ub asbyte;      sljit_ub asbyte;
368      sljit_ub asbytes[4];      sljit_ub asuchars[4];
369    #else
370    #ifdef COMPILE_PCRE16
371        sljit_uh asuchars[2];
372    #endif
373    #endif
374    } c;    } c;
375    union {    union {
376      int asint;      sljit_i asint;
377      short asshort;      sljit_uh asushort;
378    #ifdef COMPILE_PCRE8
379      sljit_ub asbyte;      sljit_ub asbyte;
380      sljit_ub asbytes[4];      sljit_ub asuchars[4];
381    #else
382    #ifdef COMPILE_PCRE16
383        sljit_uh asuchars[2];
384    #endif
385    #endif
386    } oc;    } oc;
387  #endif  #endif
388  } compare_context;  } compare_context;
389    
390  enum {  enum {
391    frame_end = 0,    frame_end = 0,
392    frame_setstrbegin = -1    frame_setstrbegin = -1,
393      frame_setmark = -2
394  };  };
395    
396    /* Undefine sljit macros. */
397    #undef CMP
398    
399  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
400  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
401    
402  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
403  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
404  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
405  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
406  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
407  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
408  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
409  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
410  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
411  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
412    
413  /* Locals layout. */  /* Local space layout. */
414  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
415  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_w))
416  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_w))
417  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
418  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
419  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
420  /* Max limit of recursions. */  /* Max limit of recursions. */
421  #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))  
422  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
423  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
424  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
425  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. */
426  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
427  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
428  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
429  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
430    
431    #ifdef COMPILE_PCRE8
432    #define MOV_UCHAR  SLJIT_MOV_UB
433    #define MOVU_UCHAR SLJIT_MOVU_UB
434    #else
435    #ifdef COMPILE_PCRE16
436    #define MOV_UCHAR  SLJIT_MOV_UH
437    #define MOVU_UCHAR SLJIT_MOVU_UH
438    #else
439    #error Unsupported compiling mode
440    #endif
441    #endif
442    
443  /* Shortcuts. */  /* Shortcuts. */
444  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 390  the start pointers when the end of the c Line 461  the start pointers when the end of the c
461    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))
462  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
463    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
464    #define GET_LOCAL_BASE(dst, dstw, offset) \
465      sljit_get_local_base(compiler, (dst), (dstw), (offset))
466    
467  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
468  {  {
469  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));
470  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 402  return cc; Line 475  return cc;
475    
476  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
477   next_opcode   next_opcode
478   get_localspace   get_private_data_length
479   set_localptrs   set_private_data_ptrs
480   get_framesize   get_framesize
481   init_frame   init_frame
482   get_localsize   get_private_data_length_for_copy
483   copy_locals   copy_private_data
484   compile_hotpath   compile_matchingpath
485   compile_fallbackpath   compile_backtrackingpath
486  */  */
487    
488  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
489  {  {
490  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
491  switch(*cc)  switch(*cc)
# Line 461  switch(*cc) Line 534  switch(*cc)
534    case OP_BRAZERO:    case OP_BRAZERO:
535    case OP_BRAMINZERO:    case OP_BRAMINZERO:
536    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
537      case OP_COMMIT:
538    case OP_FAIL:    case OP_FAIL:
539    case OP_ACCEPT:    case OP_ACCEPT:
540    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 468  switch(*cc) Line 542  switch(*cc)
542    return cc + 1;    return cc + 1;
543    
544    case OP_ANYBYTE:    case OP_ANYBYTE:
545  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
546    if (common->utf8) return NULL;    if (common->utf) return NULL;
547  #endif  #endif
548    return cc + 1;    return cc + 1;
549    
# Line 477  switch(*cc) Line 551  switch(*cc)
551    case OP_CHARI:    case OP_CHARI:
552    case OP_NOT:    case OP_NOT:
553    case OP_NOTI:    case OP_NOTI:
   
554    case OP_STAR:    case OP_STAR:
555    case OP_MINSTAR:    case OP_MINSTAR:
556    case OP_PLUS:    case OP_PLUS:
# Line 515  switch(*cc) Line 588  switch(*cc)
588    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
589    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
590    cc += 2;    cc += 2;
591  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
592    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]);
593  #endif  #endif
594    return cc;    return cc;
595    
# Line 536  switch(*cc) Line 609  switch(*cc)
609    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
610    case OP_NOTEXACTI:    case OP_NOTEXACTI:
611    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
612    cc += 4;    cc += 2 + IMM2_SIZE;
613  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
614    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]);
615  #endif  #endif
616    return cc;    return cc;
617    
618    case OP_NOTPROP:    case OP_NOTPROP:
619    case OP_PROP:    case OP_PROP:
620      return cc + 1 + 2;
621    
622    case OP_TYPEUPTO:    case OP_TYPEUPTO:
623    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
624    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 551  switch(*cc) Line 626  switch(*cc)
626    case OP_REF:    case OP_REF:
627    case OP_REFI:    case OP_REFI:
628    case OP_CREF:    case OP_CREF:
629      case OP_NCREF:
630      case OP_RREF:
631      case OP_NRREF:
632    case OP_CLOSE:    case OP_CLOSE:
633    cc += 3;    cc += 1 + IMM2_SIZE;
634    return cc;    return cc;
635    
636    case OP_CRRANGE:    case OP_CRRANGE:
637    case OP_CRMINRANGE:    case OP_CRMINRANGE:
638    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
639    
640    case OP_CLASS:    case OP_CLASS:
641    case OP_NCLASS:    case OP_NCLASS:
642    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
643    
644  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
645    case OP_XCLASS:    case OP_XCLASS:
646    return cc + GET(cc, 1);    return cc + GET(cc, 1);
647  #endif  #endif
# Line 593  switch(*cc) Line 671  switch(*cc)
671    case OP_CBRAPOS:    case OP_CBRAPOS:
672    case OP_SCBRA:    case OP_SCBRA:
673    case OP_SCBRAPOS:    case OP_SCBRAPOS:
674    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
675    
676      case OP_MARK:
677      return cc + 1 + 2 + cc[1];
678    
679    default:    default:
680    return NULL;    return NULL;
681    }    }
682  }  }
683    
684  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
685        case OP_MINSTAR: \
686        case OP_MINPLUS: \
687        case OP_QUERY: \
688        case OP_MINQUERY: \
689        case OP_MINSTARI: \
690        case OP_MINPLUSI: \
691        case OP_QUERYI: \
692        case OP_MINQUERYI: \
693        case OP_NOTMINSTAR: \
694        case OP_NOTMINPLUS: \
695        case OP_NOTQUERY: \
696        case OP_NOTMINQUERY: \
697        case OP_NOTMINSTARI: \
698        case OP_NOTMINPLUSI: \
699        case OP_NOTQUERYI: \
700        case OP_NOTMINQUERYI:
701    
702    #define CASE_ITERATOR_PRIVATE_DATA_2A \
703        case OP_STAR: \
704        case OP_PLUS: \
705        case OP_STARI: \
706        case OP_PLUSI: \
707        case OP_NOTSTAR: \
708        case OP_NOTPLUS: \
709        case OP_NOTSTARI: \
710        case OP_NOTPLUSI:
711    
712    #define CASE_ITERATOR_PRIVATE_DATA_2B \
713        case OP_UPTO: \
714        case OP_MINUPTO: \
715        case OP_UPTOI: \
716        case OP_MINUPTOI: \
717        case OP_NOTUPTO: \
718        case OP_NOTMINUPTO: \
719        case OP_NOTUPTOI: \
720        case OP_NOTMINUPTOI:
721    
722    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
723        case OP_TYPEMINSTAR: \
724        case OP_TYPEMINPLUS: \
725        case OP_TYPEQUERY: \
726        case OP_TYPEMINQUERY:
727    
728    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
729        case OP_TYPESTAR: \
730        case OP_TYPEPLUS:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
733        case OP_TYPEUPTO: \
734        case OP_TYPEMINUPTO:
735    
736    static int get_class_iterator_size(pcre_uchar *cc)
737    {
738    switch(*cc)
739      {
740      case OP_CRSTAR:
741      case OP_CRPLUS:
742      return 2;
743    
744      case OP_CRMINSTAR:
745      case OP_CRMINPLUS:
746      case OP_CRQUERY:
747      case OP_CRMINQUERY:
748      return 1;
749    
750      case OP_CRRANGE:
751      case OP_CRMINRANGE:
752      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
753        return 0;
754      return 2;
755    
756      default:
757      return 0;
758      }
759    }
760    
761    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
762  {  {
763  int localspace = 0;  int private_data_length = 0;
764  uschar *alternative;  pcre_uchar *alternative;
765    pcre_uchar *name;
766    pcre_uchar *end = NULL;
767    int space, size, bracketlen, i;
768    
769  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
770  while (cc < ccend)  while (cc < ccend)
771    {    {
772      space = 0;
773      size = 0;
774      bracketlen = 0;
775    switch(*cc)    switch(*cc)
776      {      {
777        case OP_SET_SOM:
778        common->has_set_som = TRUE;
779        cc += 1;
780        break;
781    
782        case OP_REF:
783        case OP_REFI:
784        common->optimized_cbracket[GET2(cc, 1)] = 0;
785        cc += 1 + IMM2_SIZE;
786        break;
787    
788      case OP_ASSERT:      case OP_ASSERT:
789      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
790      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 618  while (cc < ccend) Line 794  while (cc < ccend)
794      case OP_BRAPOS:      case OP_BRAPOS:
795      case OP_SBRA:      case OP_SBRA:
796      case OP_SBRAPOS:      case OP_SBRAPOS:
797      case OP_SCOND:      private_data_length += sizeof(sljit_w);
798      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
799      break;      break;
800    
801      case OP_CBRAPOS:      case OP_CBRAPOS:
802      case OP_SCBRAPOS:      case OP_SCBRAPOS:
803      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_w);
804      cc += 1 + LINK_SIZE + 2;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
805        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
806      break;      break;
807    
808      case OP_COND:      case OP_COND:
809      /* Might be a hidden SCOND. */      case OP_SCOND:
810      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
811      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
812        localspace += sizeof(sljit_w);        {
813          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
814          common->optimized_cbracket[bracketlen] = 0;
815          }
816        else if (bracketlen == OP_NCREF)
817          {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          name = (pcre_uchar *)common->name_table;
820          alternative = name;
821          for (i = 0; i < common->name_count; i++)
822            {
823            if (GET2(name, 0) == bracketlen) break;
824            name += common->name_entry_size;
825            }
826          SLJIT_ASSERT(i != common->name_count);
827    
828          for (i = 0; i < common->name_count; i++)
829            {
830            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
831              common->optimized_cbracket[GET2(alternative, 0)] = 0;
832            alternative += common->name_entry_size;
833            }
834          }
835    
836        if (*cc == OP_COND)
837          {
838          /* Might be a hidden SCOND. */
839          alternative = cc + GET(cc, 1);
840          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
841            private_data_length += sizeof(sljit_w);
842          }
843        else
844          private_data_length += sizeof(sljit_w);
845        bracketlen = 1 + LINK_SIZE;
846        break;
847    
848        case OP_BRA:
849        bracketlen = 1 + LINK_SIZE;
850        break;
851    
852        case OP_CBRA:
853        case OP_SCBRA:
854        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
855        break;
856    
857        CASE_ITERATOR_PRIVATE_DATA_1
858        space = 1;
859        size = -2;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_2A
863        space = 2;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2B
868        space = 2;
869        size = -(2 + IMM2_SIZE);
870        break;
871    
872        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
873        space = 1;
874        size = 1;
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
878        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
879          space = 2;
880        size = 1;
881        break;
882    
883        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
884        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
885          space = 2;
886        size = 1 + IMM2_SIZE;
887        break;
888    
889        case OP_CLASS:
890        case OP_NCLASS:
891        size += 1 + 32 / sizeof(pcre_uchar);
892        space = get_class_iterator_size(cc + size);
893        break;
894    
895    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
896        case OP_XCLASS:
897        size = GET(cc, 1);
898        space = get_class_iterator_size(cc + size);
899        break;
900    #endif
901    
902        case OP_RECURSE:
903        alternative = common->start + GET(cc, 1);
904        if (alternative != common->start)
905          common->optimized_cbracket[GET2(alternative, 1 + LINK_SIZE)] = 0;
906        /* Set its value only once. */
907        if (common->recursive_head == 0)
908          {
909          common->recursive_head = common->ovector_start;
910          common->ovector_start += sizeof(sljit_w);
911          }
912      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
913      break;      break;
914    
915        case OP_MARK:
916        if (common->mark_ptr == 0)
917          {
918          common->mark_ptr = common->ovector_start;
919          common->ovector_start += sizeof(sljit_w);
920          }
921        cc += 1 + 2 + cc[1];
922        break;
923    
924      default:      default:
925      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
926      if (cc == NULL)      if (cc == NULL)
927        return -1;        return -1;
928      break;      break;
929      }      }
930    
931      if (space > 0 && cc >= end)
932        private_data_length += sizeof(sljit_w) * space;
933    
934      if (size != 0)
935        {
936        if (size < 0)
937          {
938          cc += -size;
939    #ifdef SUPPORT_UTF
940          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
941    #endif
942          }
943        else
944          cc += size;
945        }
946    
947      if (bracketlen > 0)
948        {
949        if (cc >= end)
950          {
951          end = bracketend(cc);
952          if (end[-1 - LINK_SIZE] == OP_KET)
953            end = NULL;
954          }
955        cc += bracketlen;
956        }
957    }    }
958  return localspace;  return private_data_length;
959  }  }
960    
961  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)
962  {  {
963  uschar *cc = common->start;  pcre_uchar *cc = common->start;
964  uschar *alternative;  pcre_uchar *alternative;
965    pcre_uchar *end = NULL;
966    int space, size, bracketlen;
967    
968  while (cc < ccend)  while (cc < ccend)
969    {    {
970      space = 0;
971      size = 0;
972      bracketlen = 0;
973    switch(*cc)    switch(*cc)
974      {      {
975      case OP_ASSERT:      case OP_ASSERT:
# Line 665  while (cc < ccend) Line 982  while (cc < ccend)
982      case OP_SBRA:      case OP_SBRA:
983      case OP_SBRAPOS:      case OP_SBRAPOS:
984      case OP_SCOND:      case OP_SCOND:
985      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
986      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
987      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
988      break;      break;
989    
990      case OP_CBRAPOS:      case OP_CBRAPOS:
991      case OP_SCBRAPOS:      case OP_SCBRAPOS:
992      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
993      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_w);
994      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
995      break;      break;
996    
997      case OP_COND:      case OP_COND:
# Line 682  while (cc < ccend) Line 999  while (cc < ccend)
999      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1000      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1001        {        {
1002        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1003        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_w);
1004        }        }
1005      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1006        break;
1007    
1008        case OP_BRA:
1009        bracketlen = 1 + LINK_SIZE;
1010        break;
1011    
1012        case OP_CBRA:
1013        case OP_SCBRA:
1014        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1015        break;
1016    
1017        CASE_ITERATOR_PRIVATE_DATA_1
1018        space = 1;
1019        size = -2;
1020        break;
1021    
1022        CASE_ITERATOR_PRIVATE_DATA_2A
1023        space = 2;
1024        size = -2;
1025        break;
1026    
1027        CASE_ITERATOR_PRIVATE_DATA_2B
1028        space = 2;
1029        size = -(2 + IMM2_SIZE);
1030        break;
1031    
1032        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1033        space = 1;
1034        size = 1;
1035        break;
1036    
1037        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1038        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1039          space = 2;
1040        size = 1;
1041        break;
1042    
1043        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1044        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1045          space = 2;
1046        size = 1 + IMM2_SIZE;
1047        break;
1048    
1049        case OP_CLASS:
1050        case OP_NCLASS:
1051        size += 1 + 32 / sizeof(pcre_uchar);
1052        space = get_class_iterator_size(cc + size);
1053        break;
1054    
1055    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1056        case OP_XCLASS:
1057        size = GET(cc, 1);
1058        space = get_class_iterator_size(cc + size);
1059      break;      break;
1060    #endif
1061    
1062      default:      default:
1063      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1064      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1065      break;      break;
1066      }      }
1067    
1068      if (space > 0 && cc >= end)
1069        {
1070        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1071        private_data_ptr += sizeof(sljit_w) * space;
1072        }
1073    
1074      if (size != 0)
1075        {
1076        if (size < 0)
1077          {
1078          cc += -size;
1079    #ifdef SUPPORT_UTF
1080          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1081    #endif
1082          }
1083        else
1084          cc += size;
1085        }
1086    
1087      if (bracketlen > 0)
1088        {
1089        if (cc >= end)
1090          {
1091          end = bracketend(cc);
1092          if (end[-1 - LINK_SIZE] == OP_KET)
1093            end = NULL;
1094          }
1095        cc += bracketlen;
1096        }
1097    }    }
1098  }  }
1099    
1100  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
1101  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1102  {  {
1103  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1104  int length = 0;  int length = 0;
1105  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1106  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1107    BOOL setmark_found = recursive;
1108    
1109  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1110    {    {
# Line 716  while (cc < ccend) Line 1118  while (cc < ccend)
1118    switch(*cc)    switch(*cc)
1119      {      {
1120      case OP_SET_SOM:      case OP_SET_SOM:
1121      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1122      if (!setsom_found)      if (!setsom_found)
1123        {        {
1124        length += 2;        length += 2;
1125        setsom_found = TRUE;        setsom_found = TRUE;
1126        }        }
1127      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1128        break;
1129    
1130        case OP_MARK:
1131        SLJIT_ASSERT(common->mark_ptr != 0);
1132        if (!setmark_found)
1133          {
1134          length += 2;
1135          setmark_found = TRUE;
1136          }
1137        cc += 1 + 2 + cc[1];
1138        break;
1139    
1140        case OP_RECURSE:
1141        if (common->has_set_som && !setsom_found)
1142          {
1143          length += 2;
1144          setsom_found = TRUE;
1145          }
1146        if (common->mark_ptr != 0 && !setmark_found)
1147          {
1148          length += 2;
1149          setmark_found = TRUE;
1150          }
1151        cc += 1 + LINK_SIZE;
1152      break;      break;
1153    
1154      case OP_CBRA:      case OP_CBRA:
# Line 730  while (cc < ccend) Line 1156  while (cc < ccend)
1156      case OP_SCBRA:      case OP_SCBRA:
1157      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1158      length += 3;      length += 3;
1159      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1160      break;      break;
1161    
1162      default:      default:
# Line 748  if (length > 0) Line 1174  if (length > 0)
1174  return -1;  return -1;
1175  }  }
1176    
1177  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)
1178  {  {
1179  DEFINE_COMPILER;  DEFINE_COMPILER;
1180  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1181  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1182    BOOL setmark_found = recursive;
1183  int offset;  int offset;
1184    
1185  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1186    SLJIT_UNUSED_ARG(stacktop);
1187  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1188    
1189  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 766  while (cc < ccend) Line 1194  while (cc < ccend)
1194    switch(*cc)    switch(*cc)
1195      {      {
1196      case OP_SET_SOM:      case OP_SET_SOM:
1197      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1198      if (!setsom_found)      if (!setsom_found)
1199        {        {
1200        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 776  while (cc < ccend) Line 1204  while (cc < ccend)
1204        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1205        setsom_found = TRUE;        setsom_found = TRUE;
1206        }        }
1207      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1208        break;
1209    
1210        case OP_MARK:
1211        SLJIT_ASSERT(common->mark_ptr != 0);
1212        if (!setmark_found)
1213          {
1214          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1215          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1216          stackpos += (int)sizeof(sljit_w);
1217          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1218          stackpos += (int)sizeof(sljit_w);
1219          setmark_found = TRUE;
1220          }
1221        cc += 1 + 2 + cc[1];
1222        break;
1223    
1224        case OP_RECURSE:
1225        if (common->has_set_som && !setsom_found)
1226          {
1227          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1228          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1229          stackpos += (int)sizeof(sljit_w);
1230          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1231          stackpos += (int)sizeof(sljit_w);
1232          setsom_found = TRUE;
1233          }
1234        if (common->mark_ptr != 0 && !setmark_found)
1235          {
1236          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1237          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1238          stackpos += (int)sizeof(sljit_w);
1239          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1240          stackpos += (int)sizeof(sljit_w);
1241          setmark_found = TRUE;
1242          }
1243        cc += 1 + LINK_SIZE;
1244      break;      break;
1245    
1246      case OP_CBRA:      case OP_CBRA:
# Line 793  while (cc < ccend) Line 1257  while (cc < ccend)
1257      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1258      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
1259    
1260      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1261      break;      break;
1262    
1263      default:      default:
# Line 806  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1270  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1270  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1271  }  }
1272    
1273  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)
1274  {  {
1275  int localsize = 2;  int private_data_length = 2;
1276  uschar *alternative;  int size;
1277  /* Calculate the sum of the local variables. */  pcre_uchar *alternative;
1278    /* Calculate the sum of the private machine words. */
1279  while (cc < ccend)  while (cc < ccend)
1280    {    {
1281      size = 0;
1282    switch(*cc)    switch(*cc)
1283      {      {
1284      case OP_ASSERT:      case OP_ASSERT:
# Line 825  while (cc < ccend) Line 1291  while (cc < ccend)
1291      case OP_SBRA:      case OP_SBRA:
1292      case OP_SBRAPOS:      case OP_SBRAPOS:
1293      case OP_SCOND:      case OP_SCOND:
1294      localsize++;      private_data_length++;
1295      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1296      break;      break;
1297    
1298      case OP_CBRA:      case OP_CBRA:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1301      cc += 1 + LINK_SIZE + 2;        private_data_length++;
1302        cc += 1 + LINK_SIZE + IMM2_SIZE;
1303      break;      break;
1304    
1305      case OP_CBRAPOS:      case OP_CBRAPOS:
1306      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1307      localsize += 2;      SLJIT_ASSERT(common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0);
1308      cc += 1 + LINK_SIZE + 2;      private_data_length += 2;
1309        cc += 1 + LINK_SIZE + IMM2_SIZE;
1310      break;      break;
1311    
1312      case OP_COND:      case OP_COND:
1313      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1314      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1315      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1316        localsize++;        private_data_length++;
1317      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1318      break;      break;
1319    
1320        CASE_ITERATOR_PRIVATE_DATA_1
1321        if (PRIVATE_DATA(cc))
1322          private_data_length++;
1323        cc += 2;
1324    #ifdef SUPPORT_UTF
1325        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1326    #endif
1327        break;
1328    
1329        CASE_ITERATOR_PRIVATE_DATA_2A
1330        if (PRIVATE_DATA(cc))
1331          private_data_length += 2;
1332        cc += 2;
1333    #ifdef SUPPORT_UTF
1334        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1335    #endif
1336        break;
1337    
1338        CASE_ITERATOR_PRIVATE_DATA_2B
1339        if (PRIVATE_DATA(cc))
1340          private_data_length += 2;
1341        cc += 2 + IMM2_SIZE;
1342    #ifdef SUPPORT_UTF
1343        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1344    #endif
1345        break;
1346    
1347        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1348        if (PRIVATE_DATA(cc))
1349          private_data_length++;
1350        cc += 1;
1351        break;
1352    
1353        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1354        if (PRIVATE_DATA(cc))
1355          private_data_length += 2;
1356        cc += 1;
1357        break;
1358    
1359        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1360        if (PRIVATE_DATA(cc))
1361          private_data_length += 2;
1362        cc += 1 + IMM2_SIZE;
1363        break;
1364    
1365        case OP_CLASS:
1366        case OP_NCLASS:
1367    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1368        case OP_XCLASS:
1369        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1370    #else
1371        size = 1 + 32 / (int)sizeof(pcre_uchar);
1372    #endif
1373        if (PRIVATE_DATA(cc))
1374          private_data_length += get_class_iterator_size(cc + size);
1375        cc += size;
1376        break;
1377    
1378      default:      default:
1379      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1380      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 856  while (cc < ccend) Line 1382  while (cc < ccend)
1382      }      }
1383    }    }
1384  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1385  return localsize;  return private_data_length;
1386  }  }
1387    
1388  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1389    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1390  {  {
1391  DEFINE_COMPILER;  DEFINE_COMPILER;
1392  int srcw[2];  int srcw[2];
1393  int count;  int count, size;
1394  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1395  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1396  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1397  uschar *alternative;  pcre_uchar *alternative;
1398  enum {  enum {
1399    start,    start,
1400    loop,    loop,
# Line 903  while (status != end) Line 1429  while (status != end)
1429    switch(status)    switch(status)
1430      {      {
1431      case start:      case start:
1432      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1433      count = 1;      count = 1;
1434      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1435      status = loop;      status = loop;
1436      break;      break;
1437    
# Line 929  while (status != end) Line 1455  while (status != end)
1455        case OP_SBRAPOS:        case OP_SBRAPOS:
1456        case OP_SCOND:        case OP_SCOND:
1457        count = 1;        count = 1;
1458        srcw[0] = PRIV(cc);        srcw[0] = PRIVATE_DATA(cc);
1459        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1460        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1461        break;        break;
1462    
1463        case OP_CBRA:        case OP_CBRA:
1464        case OP_SCBRA:        case OP_SCBRA:
1465        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1466        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1467        cc += 1 + LINK_SIZE + 2;          count = 1;
1468            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1469            }
1470          cc += 1 + LINK_SIZE + IMM2_SIZE;
1471        break;        break;
1472    
1473        case OP_CBRAPOS:        case OP_CBRAPOS:
1474        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1475        count = 2;        count = 2;
1476          srcw[0] = PRIVATE_DATA(cc);
1477        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1478        srcw[0] = PRIV(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1479        SLJIT_ASSERT(srcw[0] != 0);        cc += 1 + LINK_SIZE + IMM2_SIZE;
       cc += 1 + LINK_SIZE + 2;  
1480        break;        break;
1481    
1482        case OP_COND:        case OP_COND:
# Line 956  while (status != end) Line 1485  while (status != end)
1485        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1486          {          {
1487          count = 1;          count = 1;
1488          srcw[0] = PRIV(cc);          srcw[0] = PRIVATE_DATA(cc);
1489          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1490          }          }
1491        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1492        break;        break;
1493    
1494        default:        CASE_ITERATOR_PRIVATE_DATA_1
1495        cc = next_opcode(common, cc);        if (PRIVATE_DATA(cc))
1496        SLJIT_ASSERT(cc != NULL);          {
1497            count = 1;
1498            srcw[0] = PRIVATE_DATA(cc);
1499            }
1500          cc += 2;
1501    #ifdef SUPPORT_UTF
1502          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1503    #endif
1504          break;
1505    
1506          CASE_ITERATOR_PRIVATE_DATA_2A
1507          if (PRIVATE_DATA(cc))
1508            {
1509            count = 2;
1510            srcw[0] = PRIVATE_DATA(cc);
1511            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1512            }
1513          cc += 2;
1514    #ifdef SUPPORT_UTF
1515          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1516    #endif
1517          break;
1518    
1519          CASE_ITERATOR_PRIVATE_DATA_2B
1520          if (PRIVATE_DATA(cc))
1521            {
1522            count = 2;
1523            srcw[0] = PRIVATE_DATA(cc);
1524            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);
1525            }
1526          cc += 2 + IMM2_SIZE;
1527    #ifdef SUPPORT_UTF
1528          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1529    #endif
1530          break;
1531    
1532          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1533          if (PRIVATE_DATA(cc))
1534            {
1535            count = 1;
1536            srcw[0] = PRIVATE_DATA(cc);
1537            }
1538          cc += 1;
1539          break;
1540    
1541          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1542          if (PRIVATE_DATA(cc))
1543            {
1544            count = 2;
1545            srcw[0] = PRIVATE_DATA(cc);
1546            srcw[1] = srcw[0] + sizeof(sljit_w);
1547            }
1548          cc += 1;
1549          break;
1550    
1551          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1552          if (PRIVATE_DATA(cc))
1553            {
1554            count = 2;
1555            srcw[0] = PRIVATE_DATA(cc);
1556            srcw[1] = srcw[0] + sizeof(sljit_w);
1557            }
1558          cc += 1 + IMM2_SIZE;
1559          break;
1560    
1561          case OP_CLASS:
1562          case OP_NCLASS:
1563    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1564          case OP_XCLASS:
1565          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1566    #else
1567          size = 1 + 32 / (int)sizeof(pcre_uchar);
1568    #endif
1569          if (PRIVATE_DATA(cc))
1570            switch(get_class_iterator_size(cc + size))
1571              {
1572              case 1:
1573              count = 1;
1574              srcw[0] = PRIVATE_DATA(cc);
1575              break;
1576    
1577              case 2:
1578              count = 2;
1579              srcw[0] = PRIVATE_DATA(cc);
1580              srcw[1] = srcw[0] + sizeof(sljit_w);
1581              break;
1582    
1583              default:
1584              SLJIT_ASSERT_STOP();
1585              break;
1586              }
1587          cc += size;
1588          break;
1589    
1590          default:
1591          cc = next_opcode(common, cc);
1592          SLJIT_ASSERT(cc != NULL);
1593        break;        break;
1594        }        }
1595      break;      break;
# Line 1064  if (save) Line 1689  if (save)
1689  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1690  }  }
1691    
1692    #undef CASE_ITERATOR_PRIVATE_DATA_1
1693    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1694    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1695    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1696    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1697    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1698    
1699  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1700  {  {
1701  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1074  static SLJIT_INLINE void set_jumps(jump_ Line 1706  static SLJIT_INLINE void set_jumps(jump_
1706  while (list)  while (list)
1707    {    {
1708    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1709    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1710    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1711    list = list->next;    list = list->next;
1712    }    }
# Line 1101  if (list_item) Line 1733  if (list_item)
1733    list_item->type = type;    list_item->type = type;
1734    list_item->data = data;    list_item->data = data;
1735    list_item->start = start;    list_item->start = start;
1736    list_item->leave = LABEL();    list_item->quit = LABEL();
1737    list_item->next = common->stubs;    list_item->next = common->stubs;
1738    common->stubs = list_item;    common->stubs = list_item;
1739    }    }
# Line 1121  while (list_item) Line 1753  while (list_item)
1753      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1754      break;      break;
1755      }      }
1756    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1757    list_item = list_item->next;    list_item = list_item->next;
1758    }    }
1759  common->stubs = NULL;  common->stubs = NULL;
# Line 1164  struct sljit_label *loop; Line 1796  struct sljit_label *loop;
1796  int i;  int i;
1797  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1798  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1799  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));
1800  if (length < 8)  if (length < 8)
1801    {    {
1802    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1172  if (length < 8) Line 1804  if (length < 8)
1804    }    }
1805  else  else
1806    {    {
1807    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));
1808    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1809    loop = LABEL();    loop = LABEL();
1810    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);
# Line 1188  struct sljit_label *loop; Line 1820  struct sljit_label *loop;
1820  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1821    
1822  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1823  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));
1824  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);
1825    
1826  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1827    if (common->mark_ptr != 0)
1828      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1829  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));
1830    if (common->mark_ptr != 0)
1831      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1832  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1833  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1834  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1835  /* Unlikely, but possible */  /* Unlikely, but possible */
1836  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1837  loop = LABEL();  loop = LABEL();
1838  OP2(SLJIT_SUB, SLJIT_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);
1839  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));
1840  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1841  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1842    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1843    #endif
1844    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1845  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1846  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1847  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1210  JUMPHERE(earlyexit); Line 1849  JUMPHERE(earlyexit);
1849  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1850  if (topbracket > 1)  if (topbracket > 1)
1851    {    {
1852    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1853    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1854    
1855    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1856    loop = LABEL();    loop = LABEL();
1857    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)));
1858    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);
1859    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);
1860    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1861    }    }
1862  else  else
1863    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1864  }  }
1865    
1866  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1867    {
1868    DEFINE_COMPILER;
1869    
1870    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1871    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1872    
1873    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1874    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1875    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1876    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1877    
1878    /* Store match begin and end. */
1879    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1880    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1881    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1882    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1883    #ifdef COMPILE_PCRE16
1884    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1885    #endif
1886    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1887    
1888    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1889    #ifdef COMPILE_PCRE16
1890    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1891    #endif
1892    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1893    
1894    JUMPTO(SLJIT_JUMP, quit);
1895    }
1896    
1897    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1898    {
1899    /* May destroy TMP1. */
1900    DEFINE_COMPILER;
1901    struct sljit_jump *jump;
1902    
1903    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1904      {
1905      /* The value of -1 must be kept for start_used_ptr! */
1906      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1907      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1908      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1909      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1910      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1911      JUMPHERE(jump);
1912      }
1913    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1914      {
1915      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1916      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1917      JUMPHERE(jump);
1918      }
1919    }
1920    
1921    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1922  {  {
1923  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1924  unsigned int c;  unsigned int c;
1925    
1926  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1927  if (common->utf8)  if (common->utf)
1928    {    {
1929    GETCHAR(c, cc);    GETCHAR(c, cc);
1930    if (c > 127)    if (c > 127)
# Line 1241  if (common->utf8) Line 1935  if (common->utf8)
1935      return FALSE;      return FALSE;
1936  #endif  #endif
1937      }      }
1938    #ifndef COMPILE_PCRE8
1939      return common->fcc[c] != c;
1940    #endif
1941    }    }
1942  else  else
1943  #endif  #endif
1944    c = *cc;    c = *cc;
1945  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1946  }  }
1947    
1948  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)
1949  {  {
1950  /* Returns with the othercase. */  /* Returns with the othercase. */
1951  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1952  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1953    {    {
1954  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1955    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1261  if (common->utf8 && c > 127) Line 1958  if (common->utf8 && c > 127)
1958  #endif  #endif
1959    }    }
1960  #endif  #endif
1961  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1962  }  }
1963    
1964  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)
1965  {  {
1966  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1967  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1968  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1969  int n;  int n;
1970  #endif  #endif
1971    
1972  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1973  if (common->utf8)  if (common->utf)
1974    {    {
1975    GETCHAR(c, cc);    GETCHAR(c, cc);
1976    if (c <= 127)    if (c <= 127)
# Line 1290  if (common->utf8) Line 1987  if (common->utf8)
1987  else  else
1988    {    {
1989    c = *cc;    c = *cc;
1990    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1991    }    }
1992  #else  #else
1993  c = *cc;  c = *cc;
1994  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1995  #endif  #endif
1996    
1997  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1308  if (c <= 127 && bit == 0x20) Line 2005  if (c <= 127 && bit == 0x20)
2005  if (!ispowerof2(bit))  if (!ispowerof2(bit))
2006    return 0;    return 0;
2007    
2008  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
2009  if (common->utf8 && c > 127)  
2010    #ifdef SUPPORT_UTF
2011    if (common->utf && c > 127)
2012    {    {
2013    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
2014    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
2015      {      {
2016      n--;      n--;
# Line 1319  if (common->utf8 && c > 127) Line 2018  if (common->utf8 && c > 127)
2018      }      }
2019    return (n << 8) | bit;    return (n << 8) | bit;
2020    }    }
2021  #endif  #endif /* SUPPORT_UTF */
2022  return (0 << 8) | bit;  return (0 << 8) | bit;
2023    
2024    #else /* COMPILE_PCRE8 */
2025    
2026    #ifdef COMPILE_PCRE16
2027    #ifdef SUPPORT_UTF
2028    if (common->utf && c > 65535)
2029      {
2030      if (bit >= (1 << 10))
2031        bit >>= 10;
2032      else
2033        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
2034      }
2035    #endif /* SUPPORT_UTF */
2036    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
2037    #endif /* COMPILE_PCRE16 */
2038    
2039    #endif /* COMPILE_PCRE8 */
2040    }
2041    
2042    static void check_partial(compiler_common *common, BOOL force)
2043    {
2044    /* Checks whether a partial matching is occured. Does not modify registers. */
2045    DEFINE_COMPILER;
2046    struct sljit_jump *jump = NULL;
2047    
2048    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2049    
2050    if (common->mode == JIT_COMPILE)
2051      return;
2052    
2053    if (!force)
2054      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2055    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2056      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2057    
2058    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2059      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2060    else
2061      {
2062      if (common->partialmatchlabel != NULL)
2063        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2064      else
2065        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2066      }
2067    
2068    if (jump != NULL)
2069      JUMPHERE(jump);
2070    }
2071    
2072    static struct sljit_jump *check_str_end(compiler_common *common)
2073    {
2074    /* Does not affect registers. Usually used in a tight spot. */
2075    DEFINE_COMPILER;
2076    struct sljit_jump *jump;
2077    struct sljit_jump *nohit;
2078    struct sljit_jump *return_value;
2079    
2080    if (common->mode == JIT_COMPILE)
2081      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2082    
2083    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2084    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2085      {
2086      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2087      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2088      JUMPHERE(nohit);
2089      return_value = JUMP(SLJIT_JUMP);
2090      }
2091    else
2092      {
2093      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2094      if (common->partialmatchlabel != NULL)
2095        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2096      else
2097        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2098      }
2099    JUMPHERE(jump);
2100    return return_value;
2101  }  }
2102    
2103  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2104  {  {
2105  DEFINE_COMPILER;  DEFINE_COMPILER;
2106  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
2107    
2108    if (common->mode == JIT_COMPILE)
2109      {
2110      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2111      return;
2112      }
2113    
2114    /* Partial matching mode. */
2115    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2116    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2117    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2118      {
2119      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2120      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2121      }
2122    else
2123      {
2124      if (common->partialmatchlabel != NULL)
2125        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2126      else
2127        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2128      }
2129    JUMPHERE(jump);
2130  }  }
2131    
2132  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1334  static void read_char(compiler_common *c Line 2134  static void read_char(compiler_common *c
2134  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2135  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2136  DEFINE_COMPILER;  DEFINE_COMPILER;
2137  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2138  struct sljit_jump *jump;  struct sljit_jump *jump;
2139  #endif  #endif
2140    
2141  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2142  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2143  if (common->utf8)  if (common->utf)
2144    {    {
2145    #ifdef COMPILE_PCRE8
2146    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2147    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2148    #ifdef COMPILE_PCRE16
2149      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2150    #endif
2151    #endif /* COMPILE_PCRE8 */
2152      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2153    JUMPHERE(jump);    JUMPHERE(jump);
2154    }    }
2155  #endif  #endif
2156  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));
2157  }  }
2158    
2159  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1355  static void peek_char(compiler_common *c Line 2161  static void peek_char(compiler_common *c
2161  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2162  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2163  DEFINE_COMPILER;  DEFINE_COMPILER;
2164  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2165  struct sljit_jump *jump;  struct sljit_jump *jump;
2166  #endif  #endif
2167    
2168  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2169  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2170  if (common->utf8)  if (common->utf)
2171    {    {
2172    #ifdef COMPILE_PCRE8
2173    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2174    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2175    #ifdef COMPILE_PCRE16
2176      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2177    #endif
2178    #endif /* COMPILE_PCRE8 */
2179      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2180    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2181    JUMPHERE(jump);    JUMPHERE(jump);
2182    }    }
# Line 1375  static void read_char8_type(compiler_com Line 2187  static void read_char8_type(compiler_com
2187  {  {
2188  /* 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. */
2189  DEFINE_COMPILER;  DEFINE_COMPILER;
2190  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2191  struct sljit_jump *jump;  struct sljit_jump *jump;
2192  #endif  #endif
2193    
2194  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2195  if (common->utf8)  if (common->utf)
2196    {    {
2197    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2198    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));
2199    #ifdef COMPILE_PCRE8
2200    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2201    it is a clever early read in most cases. */    it is needed in most cases. */
2202    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2203    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2204    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2205      JUMPHERE(jump);
2206    #else
2207    #ifdef COMPILE_PCRE16
2208      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2209      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2210      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2211    JUMPHERE(jump);    JUMPHERE(jump);
2212      /* Skip low surrogate if necessary. */
2213      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2214      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2215      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2216      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2217      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2218    #endif
2219    #endif /* COMPILE_PCRE8 */
2220    return;    return;
2221    }    }
2222  #endif  #endif
2223  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2224  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));
2225  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
2226    /* The ctypes array contains only 256 values. */
2227    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2228    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2229    #endif
2230    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2231    #ifdef COMPILE_PCRE16
2232    JUMPHERE(jump);
2233    #endif
2234  }  }
2235    
2236  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2237  {  {
2238  /* 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. */
2239  DEFINE_COMPILER;  DEFINE_COMPILER;
2240  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2241  struct sljit_label *label;  struct sljit_label *label;
2242    
2243  if (common->utf8)  if (common->utf)
2244    {    {
2245    label = LABEL();    label = LABEL();
2246    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2247    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));
2248    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2249    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2250    return;    return;
2251    }    }
2252  #endif  #endif
2253  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2254    if (common->utf)
2255      {
2256      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2257      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2258      /* Skip low surrogate if necessary. */
2259      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2260      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2261      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2262      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2263      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2264      return;
2265      }
2266    #endif
2267    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2268  }  }
2269    
2270  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)
2271  {  {
2272  /* 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. */
2273  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1426  DEFINE_COMPILER; Line 2275  DEFINE_COMPILER;
2275  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2276    {    {
2277    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2278    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));
2279    }    }
2280  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2281    {    {
# Line 1434  else if (nltype == NLTYPE_ANYCRLF) Line 2283  else if (nltype == NLTYPE_ANYCRLF)
2283    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2284    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);
2285    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2286    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));
2287    }    }
2288  else  else
2289    {    {
2290    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2291    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));
2292    }    }
2293  }  }
2294    
2295  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2296  static void do_utf8readchar(compiler_common *common)  
2297    #ifdef COMPILE_PCRE8
2298    static void do_utfreadchar(compiler_common *common)
2299  {  {
2300  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2301  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. */
2302  DEFINE_COMPILER;  DEFINE_COMPILER;
2303  struct sljit_jump *jump;  struct sljit_jump *jump;
2304    
2305  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2306  /* Searching for the first zero. */  /* Searching for the first zero. */
2307  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);
2308  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2309  /* 2 byte sequence */  /* Two byte sequence. */
2310  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2311  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));
2312  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2313  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2314  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2315  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2316  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2317  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2318  JUMPHERE(jump);  JUMPHERE(jump);
2319    
2320  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);
2321  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2322  /* 3 byte sequence */  /* Three byte sequence. */
2323  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2324  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2325  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2326  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2327  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2328  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2329  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2330  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));
2331  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2332  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2333  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2334  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2335  JUMPHERE(jump);  JUMPHERE(jump);
2336    
2337  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2338  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);  
2339  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2340  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2341  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2342  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2343  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2344  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2345  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2346  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2347  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2348  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2349  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2350  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2351  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2352  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(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);  
 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), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 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, 4);  
2353  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2354  }  }
2355    
2356  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2357  {  {
2358  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2359  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2360  DEFINE_COMPILER;  DEFINE_COMPILER;
2361  struct sljit_jump *jump;  struct sljit_jump *jump;
2362  struct sljit_jump *compare;  struct sljit_jump *compare;
2363    
2364  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2365    
2366  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);
2367  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2368  /* 2 byte sequence */  /* Two byte sequence. */
2369  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2370  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));
2371  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2372  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2373  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1556  sljit_emit_fast_return(compiler, RETURN_ Line 2382  sljit_emit_fast_return(compiler, RETURN_
2382  JUMPHERE(jump);  JUMPHERE(jump);
2383    
2384  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2385  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);
2386  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2387  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2388  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2389  }  }
2390    
2391  #endif  #else /* COMPILE_PCRE8 */
2392    
2393    #ifdef COMPILE_PCRE16
2394    static void do_utfreadchar(compiler_common *common)
2395    {
2396    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2397    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2398    DEFINE_COMPILER;
2399    struct sljit_jump *jump;
2400    
2401    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2402    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2403    /* Do nothing, only return. */
2404    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2405    
2406    JUMPHERE(jump);
2407    /* Combine two 16 bit characters. */
2408    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2409    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2410    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2411    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2412    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2413    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2414    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2415    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2416    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2417    }
2418    #endif /* COMPILE_PCRE16 */
2419    
2420    #endif /* COMPILE_PCRE8 */
2421    
2422    #endif /* SUPPORT_UTF */
2423    
2424  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2425    
# Line 1578  DEFINE_COMPILER; Line 2435  DEFINE_COMPILER;
2435    
2436  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2437    
2438  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2439  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2440  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));
2441  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2442  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2443  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2444  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
2445  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2446  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));
2447  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2448  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2449  }  }
# Line 1600  struct sljit_label *newlinelabel = NULL; Line 2457  struct sljit_label *newlinelabel = NULL;
2457  struct sljit_jump *start;  struct sljit_jump *start;
2458  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2459  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2460  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2461  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
2462  #endif  #endif
2463  jump_list *newline = NULL;  jump_list *newline = NULL;
2464  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
2465  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
2466    
2467  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2468      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1614  if (!(hascrorlf || firstline) && (common Line 2471  if (!(hascrorlf || firstline) && (common
2471  if (firstline)  if (firstline)
2472    {    {
2473    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2474    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2475    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2476    
2477    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2478      {      {
2479      mainloop = LABEL();      mainloop = LABEL();
2480      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));
2481      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2482      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2483      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2484      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);
2485      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);
2486      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      JUMPHERE(end);
2487        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2488      }      }
2489    else    else
2490      {      {
2491      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2492      mainloop = LABEL();      mainloop = LABEL();
2493      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2494      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);
2495      read_char(common);      read_char(common);
2496      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2497      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2498      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2499        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2500      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2501      }      }
2502    
2503    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2504    }    }
2505    
2506  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1650  start = JUMP(SLJIT_JUMP); Line 2508  start = JUMP(SLJIT_JUMP);
2508  if (newlinecheck)  if (newlinecheck)
2509    {    {
2510    newlinelabel = LABEL();    newlinelabel = LABEL();
2511    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));
2512    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2513    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2514    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);
2515    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2516    #ifdef COMPILE_PCRE16
2517      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2518    #endif
2519    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2520    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2521    }    }
# Line 1662  if (newlinecheck) Line 2523  if (newlinecheck)
2523  mainloop = LABEL();  mainloop = LABEL();
2524    
2525  /* 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. */
2526  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2527  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2528  #endif  #endif
2529  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2530    
2531  if (readbyte)  if (readuchar)
2532    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2533    
2534  if (newlinecheck)  if (newlinecheck)
2535    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);
2536    
2537  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));
2538  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2539  if (common->utf8)  if (common->utf)
2540      {
2541      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2542      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2543      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2544      JUMPHERE(singlechar);
2545      }
2546    #endif
2547    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2548    if (common->utf)
2549    {    {
2550    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2551    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);
2552      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2553      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2554      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2555    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2556    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
2557    }    }
2558  #endif  #endif
2559  JUMPHERE(start);  JUMPHERE(start);
# Line 1694  if (newlinecheck) Line 2567  if (newlinecheck)
2567  return mainloop;  return mainloop;
2568  }  }
2569    
2570  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)
2571  {  {
2572  DEFINE_COMPILER;  DEFINE_COMPILER;
2573  struct sljit_label *start;  struct sljit_label *start;
2574  struct sljit_jump *leave;  struct sljit_jump *quit;
2575  struct sljit_jump *found;  struct sljit_jump *found;
2576  pcre_uint16 oc, bit;  pcre_int32 chars[4];
2577    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2578    int location = 0;
2579    pcre_int32 len, c, bit, caseless;
2580    BOOL must_end;
2581    
2582    #ifdef COMPILE_PCRE8
2583    union {
2584        sljit_uh ascombined;
2585        sljit_ub asuchars[2];
2586    } pair;
2587    #else
2588    union {
2589        sljit_ui ascombined;
2590        sljit_uh asuchars[2];
2591    } pair;
2592    #endif
2593    
2594    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2595      return FALSE;
2596    
2597    while (TRUE)
2598      {
2599      caseless = 0;
2600      must_end = TRUE;
2601      switch(*cc)
2602        {
2603        case OP_CHAR:
2604        must_end = FALSE;
2605        cc++;
2606        break;
2607    
2608        case OP_CHARI:
2609        caseless = 1;
2610        must_end = FALSE;
2611        cc++;
2612        break;
2613    
2614        case OP_SOD:
2615        case OP_SOM:
2616        case OP_SET_SOM:
2617        case OP_NOT_WORD_BOUNDARY:
2618        case OP_WORD_BOUNDARY:
2619        case OP_EODN:
2620        case OP_EOD:
2621        case OP_CIRC:
2622        case OP_CIRCM:
2623        case OP_DOLL:
2624        case OP_DOLLM:
2625        /* Zero width assertions. */
2626        cc++;
2627        continue;
2628    
2629        case OP_PLUS:
2630        case OP_MINPLUS:
2631        case OP_POSPLUS:
2632        cc++;
2633        break;
2634    
2635        case OP_EXACT:
2636        cc += 1 + IMM2_SIZE;
2637        break;
2638    
2639        case OP_PLUSI:
2640        case OP_MINPLUSI:
2641        case OP_POSPLUSI:
2642        caseless = 1;
2643        cc++;
2644        break;
2645    
2646        case OP_EXACTI:
2647        caseless = 1;
2648        cc += 1 + IMM2_SIZE;
2649        break;
2650    
2651        default:
2652        return FALSE;
2653        }
2654    
2655      len = 1;
2656    #ifdef SUPPORT_UTF
2657      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2658    #endif
2659    
2660      if (caseless && char_has_othercase(common, cc))
2661        {
2662        caseless = char_get_othercase_bit(common, cc);
2663        if (caseless == 0)
2664          return FALSE;
2665    #ifdef COMPILE_PCRE8
2666        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2667    #else
2668        if ((caseless & 0x100) != 0)
2669          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2670        else
2671          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2672    #endif
2673        }
2674      else
2675        caseless = 0;
2676    
2677      while (len > 0 && location < 2 * 2)
2678        {
2679        c = *cc;
2680        bit = 0;
2681        if (len == (caseless & 0xff))
2682          {
2683          bit = caseless >> 8;
2684          c |= bit;
2685          }
2686    
2687        chars[location] = c;
2688        chars[location + 1] = bit;
2689    
2690        len--;
2691        location += 2;
2692        cc++;
2693        }
2694    
2695      if (location == 2 * 2)
2696        break;
2697      else if (must_end)
2698        return FALSE;
2699      }
2700    
2701  if (firstline)  if (firstline)
2702    {    {
2703    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2704    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2705      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2706    }    }
2707    else
2708      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2709    
2710  start = LABEL();  start = LABEL();
2711  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2712  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2713    #ifdef COMPILE_PCRE8
2714    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2715    #else /* COMPILE_PCRE8 */
2716    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2717    #endif
2718    
2719    #else /* SLJIT_UNALIGNED */
2720    
2721    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2722    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2723    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2724    #else /* SLJIT_BIG_ENDIAN */
2725    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2726    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2727    #endif /* SLJIT_BIG_ENDIAN */
2728    
2729    #ifdef COMPILE_PCRE8
2730    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2731    #else /* COMPILE_PCRE8 */
2732    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2733    #endif
2734    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2735    
2736    #endif
2737    
2738    if (chars[1] != 0 || chars[3] != 0)
2739      {
2740      pair.asuchars[0] = chars[1];
2741      pair.asuchars[1] = chars[3];
2742      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2743      }
2744    
2745  if ((firstbyte & REQ_CASELESS) == 0)  pair.asuchars[0] = chars[0];
2746    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  pair.asuchars[1] = chars[2];
2747    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2748    
2749    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2750    JUMPTO(SLJIT_JUMP, start);
2751    JUMPHERE(found);
2752    JUMPHERE(quit);
2753    
2754    if (firstline)
2755      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2756  else  else
2757      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2758    return TRUE;
2759    }
2760    
2761    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2762    {
2763    DEFINE_COMPILER;
2764    struct sljit_label *start;
2765    struct sljit_jump *quit;
2766    struct sljit_jump *found;
2767    pcre_uchar oc, bit;
2768    
2769    if (firstline)
2770      {
2771      SLJIT_ASSERT(common->first_line_end != 0);
2772      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2773      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2774      }
2775    
2776    start = LABEL();
2777    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2778    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2779    
2780    oc = first_char;
2781    if (caseless)
2782    {    {
2783    firstbyte &= 0xff;    oc = TABLE_GET(first_char, common->fcc, first_char);
2784    oc = common->fcc[firstbyte];  #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2785    bit = firstbyte ^ oc;    if (first_char > 127 && common->utf)
2786        oc = UCD_OTHERCASE(first_char);
2787    #endif
2788      }
2789    if (first_char == oc)
2790      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2791    else
2792      {
2793      bit = first_char ^ oc;
2794    if (ispowerof2(bit))    if (ispowerof2(bit))
2795      {      {
2796      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2797      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2798      }      }
2799    else    else
2800      {      {
2801      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);
2802      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2803      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);
2804      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 1734  else Line 2806  else
2806      }      }
2807    }    }
2808    
2809  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  
2810  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2811  JUMPHERE(found);  JUMPHERE(found);
2812  JUMPHERE(leave);  JUMPHERE(quit);
2813    
2814  if (firstline)  if (firstline)
2815    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2816  }  }
2817    
2818  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 1757  DEFINE_COMPILER; Line 2821  DEFINE_COMPILER;
2821  struct sljit_label *loop;  struct sljit_label *loop;
2822  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2823  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2824  struct sljit_jump *leave;  struct sljit_jump *quit;
2825  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2826  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2827  jump_list *newline = NULL;  jump_list *newline = NULL;
2828    
2829  if (firstline)  if (firstline)
2830    {    {
2831    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2832    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2833      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2834    }    }
2835    
2836  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1776  if (common->nltype == NLTYPE_FIXED && co Line 2841  if (common->nltype == NLTYPE_FIXED && co
2841    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));
2842    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2843    
2844    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2845    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);
2846    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2847    #ifdef COMPILE_PCRE16
2848      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2849    #endif
2850    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2851    
2852    loop = LABEL();    loop = LABEL();
2853    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));
2854    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2855    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2856    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2857    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);
2858    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);
2859    
2860    JUMPHERE(leave);    JUMPHERE(quit);
2861    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2862    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2863    
# Line 1813  set_jumps(newline, loop); Line 2881  set_jumps(newline, loop);
2881    
2882  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2883    {    {
2884    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2885    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2886    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2887    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2888    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);
2889    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2890    #ifdef COMPILE_PCRE16
2891      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2892    #endif
2893    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2894    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2895    JUMPHERE(leave);    JUMPHERE(quit);
2896    }    }
2897  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2898  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2899    
2900  if (firstline)  if (firstline)
2901    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2902  }  }
2903    
2904  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)
2905  {  {
2906  DEFINE_COMPILER;  DEFINE_COMPILER;
2907  struct sljit_label *start;  struct sljit_label *start;
2908  struct sljit_jump *leave;  struct sljit_jump *quit;
2909  struct sljit_jump *found;  struct sljit_jump *found;
2910    #ifndef COMPILE_PCRE8
2911    struct sljit_jump *jump;
2912    #endif
2913    
2914  if (firstline)  if (firstline)
2915    {    {
2916    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2917    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2918      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2919    }    }
2920    
2921  start = LABEL();  start = LABEL();
2922  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2923  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2924  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2925  if (common->utf8)  if (common->utf)
2926    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2927  #endif  #endif
2928    #ifndef COMPILE_PCRE8
2929    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2930    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2931    JUMPHERE(jump);
2932    #endif
2933  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2934  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2935  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1857  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2937  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2937  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);
2938  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2939    
2940  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2941  if (common->utf8)  if (common->utf)
2942    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2943  #endif  #endif
2944  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));
2945  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2946  if (common->utf8)  if (common->utf)
2947    {    {
2948    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2949    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);
2950      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2951      }
2952    #endif
2953    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2954    if (common->utf)
2955      {
2956      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2957      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2958      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2959      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2960      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2961    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2962    }    }
2963  #endif  #endif
2964  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2965  JUMPHERE(found);  JUMPHERE(found);
2966  JUMPHERE(leave);  JUMPHERE(quit);
2967    
2968  if (firstline)  if (firstline)
2969    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2970  }  }
2971    
2972  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)
2973  {  {
2974  DEFINE_COMPILER;  DEFINE_COMPILER;
2975  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1887  struct sljit_jump *alreadyfound; Line 2978  struct sljit_jump *alreadyfound;
2978  struct sljit_jump *found;  struct sljit_jump *found;
2979  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2980  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2981  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2982    
2983  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2984    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2985  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);
2986  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2987  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2988    
2989  if (has_firstbyte)  if (has_firstchar)
2990    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2991  else  else
2992    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2993    
2994  loop = LABEL();  loop = LABEL();
2995  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2996    
2997  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2998  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2999    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
3000      {
3001      oc = TABLE_GET(req_char, common->fcc, req_char);
3002    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
3003      if (req_char > 127 && common->utf)
3004        oc = UCD_OTHERCASE(req_char);
3005    #endif
3006      }
3007    if (req_char == oc)
3008      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
3009  else  else
3010    {    {
3011    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
3012    if (ispowerof2(bit))    if (ispowerof2(bit))
3013      {      {
3014      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3015      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
3016      }      }
3017    else    else
3018      {      {
3019      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
3020      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
3021      }      }
3022    }    }
3023  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3024  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
3025    
3026  JUMPHERE(found);  JUMPHERE(found);
3027  if (foundoc)  if (foundoc)
3028    JUMPHERE(foundoc);    JUMPHERE(foundoc);
3029  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);
3030  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
3031  JUMPHERE(toolong);  JUMPHERE(toolong);
3032  return notfound;  return notfound;
# Line 1939  DEFINE_COMPILER; Line 3038  DEFINE_COMPILER;
3038  struct sljit_jump *jump;  struct sljit_jump *jump;
3039  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3040    
3041  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3042  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3043    GET_LOCAL_BASE(TMP3, 0, 0);
3044    
3045  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3046  mainloop = LABEL();  mainloop = LABEL();
3047  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3048  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);
3049  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3050  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));
3051  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));
3052  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 1966  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 3066  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
3066  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3067    
3068  JUMPHERE(jump);  JUMPHERE(jump);
3069    if (common->mark_ptr != 0)
3070      {
3071      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3072      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3073      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3074      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3075      JUMPTO(SLJIT_JUMP, mainloop);
3076    
3077      JUMPHERE(jump);
3078      }
3079    
3080  /* Unknown command. */  /* Unknown command. */
3081  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));
3082  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 1974  JUMPTO(SLJIT_JUMP, mainloop); Line 3085  JUMPTO(SLJIT_JUMP, mainloop);
3085  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3086  {  {
3087  DEFINE_COMPILER;  DEFINE_COMPILER;
3088  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3089  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3090  struct sljit_jump *jump;  struct sljit_jump *jump;
3091  #endif  #endif
3092    
3093  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3094    
3095  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);
3096  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3097  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3098  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));
3099  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3100  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3101  skip_char_back(common);  skip_char_back(common);
3102    check_start_used_ptr(common);
3103  read_char(common);  read_char(common);
3104    
3105  /* Testing char type. */  /* Testing char type. */
3106  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3107  if (common->useucp)  if (common->use_ucp)
3108    {    {
3109    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3110    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2009  if (common->useucp) Line 3121  if (common->useucp)
3121  else  else
3122  #endif  #endif
3123    {    {
3124  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3125    /* Here LOCALS1 has already been zeroed. */    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3126    jump = NULL;  #elif defined SUPPORT_UTF
3127    if (common->utf8)    /* Here LOCALS1 has already been zeroed. */
3128      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    jump = NULL;
3129  #endif    if (common->utf)
3130    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3131    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);  #endif /* COMPILE_PCRE8 */
3132    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3133    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3134  #ifdef SUPPORT_UTF8    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3135    if (jump != NULL)    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3136      JUMPHERE(jump);  #ifndef COMPILE_PCRE8
3137  #endif    JUMPHERE(jump);
3138    #elif defined SUPPORT_UTF
3139      if (jump != NULL)
3140        JUMPHERE(jump);
3141    #endif /* COMPILE_PCRE8 */
3142      }
3143    JUMPHERE(skipread);
3144    
3145    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3146    skipread = check_str_end(common);
3147    peek_char(common);
3148    
3149    /* Testing char type. This is a code duplication. */
3150    #ifdef SUPPORT_UCP
3151    if (common->use_ucp)
3152      {
3153      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3154      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3155      add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3156      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3157      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3158      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3159      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3160      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3161      COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);
3162      JUMPHERE(jump);
3163      }
3164    else
3165    #endif
3166      {
3167    #ifndef COMPILE_PCRE8
3168      /* TMP2 may be destroyed by peek_char. */
3169      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3170      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3171    #elif defined SUPPORT_UTF
3172      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3173      jump = NULL;
3174      if (common->utf)
3175        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3176    #endif
3177      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3178      OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3179      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3180    #ifndef COMPILE_PCRE8
3181      JUMPHERE(jump);
3182    #elif defined SUPPORT_UTF
3183      if (jump != NULL)
3184        JUMPHERE(jump);
3185    #endif /* COMPILE_PCRE8 */
3186      }
3187    JUMPHERE(skipread);
3188    
3189    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3190    sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3191    }
3192    
3193    /*
3194      range format:
3195    
3196      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3197      ranges[1] = first bit (0 or 1)
3198      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3199    */
3200    
3201    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3202    {
3203    DEFINE_COMPILER;
3204    struct sljit_jump *jump;
3205    
3206    if (ranges[0] < 0)
3207      return FALSE;
3208    
3209    switch(ranges[0])
3210      {
3211      case 1:
3212      if (readch)
3213        read_char(common);
3214      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3215      return TRUE;
3216    
3217      case 2:
3218      if (readch)
3219        read_char(common);
3220      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3221      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3222      return TRUE;
3223    
3224      case 4:
3225      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3226        {
3227        if (readch)
3228          read_char(common);
3229        if (ranges[1] != 0)
3230          {
3231          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3232          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3233          }
3234        else
3235          {
3236          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3237          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3238          JUMPHERE(jump);
3239          }
3240        return TRUE;
3241        }
3242      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3243        {
3244        if (readch)
3245          read_char(common);
3246        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3247        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3248        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3249        return TRUE;
3250        }
3251      return FALSE;
3252    
3253      default:
3254      return FALSE;
3255      }
3256    }
3257    
3258    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3259    {
3260    int i, bit, length;
3261    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3262    
3263    bit = ctypes[0] & flag;
3264    ranges[0] = -1;
3265    ranges[1] = bit != 0 ? 1 : 0;
3266    length = 0;
3267    
3268    for (i = 1; i < 256; i++)
3269      if ((ctypes[i] & flag) != bit)
3270        {
3271        if (length >= MAX_RANGE_SIZE)
3272          return;
3273        ranges[2 + length] = i;
3274        length++;
3275        bit ^= flag;
3276        }
3277    
3278    if (bit != 0)
3279      {
3280      if (length >= MAX_RANGE_SIZE)
3281        return;
3282      ranges[2 + length] = 256;
3283      length++;
3284    }    }
3285  JUMPHERE(beginend);  ranges[0] = length;
3286    }
3287    
3288  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3289  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  {
3290  peek_char(common);  int ranges[2 + MAX_RANGE_SIZE];
3291    pcre_uint8 bit, cbit, all;
3292    int i, byte, length = 0;
3293    
3294  /* Testing char type. This is a code duplication. */  bit = bits[0] & 0x1;
3295  #ifdef SUPPORT_UCP  ranges[1] = bit;
3296  if (common->useucp)  /* Can be 0 or 255. */
3297    all = -bit;
3298    
3299    for (i = 0; i < 256; )
3300    {    {
3301    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    byte = i >> 3;
3302    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    if ((i & 0x7) == 0 && bits[byte] == all)
3303    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));      i += 8;
3304    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    else
3305    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);      {
3306    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);      cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3307    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);      if (cbit != bit)
3308    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);        {
3309    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        if (length >= MAX_RANGE_SIZE)
3310    JUMPHERE(jump);          return FALSE;
3311          ranges[2 + length] = i;
3312          length++;
3313          bit = cbit;
3314          all = -cbit;
3315          }
3316        i++;
3317        }
3318    }    }
3319  else  
3320  #endif  if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3321    {    {
3322  #ifdef SUPPORT_UTF8    if (length >= MAX_RANGE_SIZE)
3323    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);      return FALSE;
3324    jump = NULL;    ranges[2 + length] = 256;
3325    if (common->utf8)    length++;
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);  
 #endif  
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);  
   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);  
   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  
 #ifdef SUPPORT_UTF8  
   if (jump != NULL)  
     JUMPHERE(jump);  
 #endif  
3326    }    }
3327  JUMPHERE(beginend);  ranges[0] = length;
3328    
3329  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  return check_ranges(common, ranges, backtracks, FALSE);
 sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
3330  }  }
3331    
3332  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 2073  static void check_anynewline(compiler_co Line 3334  static void check_anynewline(compiler_co
3334  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3335  DEFINE_COMPILER;  DEFINE_COMPILER;
3336    
3337  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3338    
3339  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3340  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);
3341  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3342  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);
3343  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3344  if (common->utf8)  #ifdef COMPILE_PCRE8
3345    if (common->utf)
3346    {    {
3347    #endif
3348    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3349    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3350    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);
3351    #ifdef COMPILE_PCRE8
3352    }    }
3353  #endif  #endif
3354    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3355  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3356  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3357  }  }
# Line 2096  static void check_hspace(compiler_common Line 3361  static void check_hspace(compiler_common
3361  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3362  DEFINE_COMPILER;  DEFINE_COMPILER;
3363    
3364  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3365    
3366  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);
3367  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3368  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);
3369  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3370  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);
3371  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3372  if (common->utf8)  #ifdef COMPILE_PCRE8
3373    if (common->utf)
3374    {    {
3375    #endif
3376    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3377    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);
3378    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2119  if (common->utf8) Line 3386  if (common->utf8)
3386    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);
3387    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3388    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);
3389    #ifdef COMPILE_PCRE8
3390    }    }
3391  #endif  #endif
3392    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3393  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3394    
3395  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2131  static void check_vspace(compiler_common Line 3400  static void check_vspace(compiler_common
3400  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3401  DEFINE_COMPILER;  DEFINE_COMPILER;
3402    
3403  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3404    
3405  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3406  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);
3407  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3408  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);
3409  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3410  if (common->utf8)  #ifdef COMPILE_PCRE8
3411    if (common->utf)
3412    {    {
3413    #endif
3414    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3415    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3416    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);
3417    #ifdef COMPILE_PCRE8
3418    }    }
3419  #endif  #endif
3420    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3421  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3422    
3423  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2159  DEFINE_COMPILER; Line 3432  DEFINE_COMPILER;
3432  struct sljit_jump *jump;  struct sljit_jump *jump;
3433  struct sljit_label *label;  struct sljit_label *label;
3434    
3435  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3436  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3437  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3438  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3439  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3440  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));
3441    
3442  label = LABEL();  label = LABEL();
3443  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3444  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3445  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3446  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));
3447  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3448    
3449  JUMPHERE(jump);  JUMPHERE(jump);
3450  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));
3451  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3452  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3453  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2188  DEFINE_COMPILER; Line 3461  DEFINE_COMPILER;
3461  struct sljit_jump *jump;  struct sljit_jump *jump;
3462  struct sljit_label *label;  struct sljit_label *label;
3463    
3464  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3465  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3466    
3467  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3468  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3469  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3470  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3471  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3472  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));
3473    
3474  label = LABEL();  label = LABEL();
3475  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3476  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3477    #ifndef COMPILE_PCRE8
3478    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3479    #endif
3480  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3481    #ifndef COMPILE_PCRE8
3482    JUMPHERE(jump);
3483    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3484    #endif
3485  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3486    #ifndef COMPILE_PCRE8
3487    JUMPHERE(jump);
3488    #endif
3489  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3490  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));
3491  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3492    
3493  JUMPHERE(jump);  JUMPHERE(jump);
3494  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));
3495  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3496  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3497  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2219  sljit_emit_fast_return(compiler, RETURN_ Line 3502  sljit_emit_fast_return(compiler, RETURN_
3502  #undef CHAR1  #undef CHAR1
3503  #undef CHAR2  #undef CHAR2
3504    
3505  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3506    
3507  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)
3508  {  {
3509  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3510  int c1, c2;  int c1, c2;
3511  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3512  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3513    
3514  while (src1 < end1)  while (src1 < end1)
3515    {    {
3516    if (src2 >= end2)    if (src2 >= end2)
3517      return 0;      return (pcre_uchar*)1;
3518    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3519    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3520    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
3521    }    }
3522  return src2;  return src2;
3523  }  }
3524    
3525  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3526    
3527  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,
3528      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3529  {  {
3530  DEFINE_COMPILER;  DEFINE_COMPILER;
3531  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3532  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3533  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3534  int utf8length;  int utflength;
3535  #endif  #endif
3536    
3537  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2258  if (caseless && char_has_othercase(commo Line 3539  if (caseless && char_has_othercase(commo
3539    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3540    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3541    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3542    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
3543      othercasechar = cc + (othercasebit >> 8);
3544    othercasebit &= 0xff;    othercasebit &= 0xff;
3545    #else
3546    #ifdef COMPILE_PCRE16
3547      othercasechar = cc + (othercasebit >> 9);
3548      if ((othercasebit & 0x100) != 0)
3549        othercasebit = (othercasebit & 0xff) << 8;
3550      else
3551        othercasebit &= 0xff;
3552    #endif
3553    #endif
3554    }    }
3555    
3556  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3557    {    {
3558    #ifdef COMPILE_PCRE8
3559  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3560    if (context->length >= 4)    if (context->length >= 4)
3561      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3562    else if (context->length >= 2)    else if (context->length >= 2)
3563      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3564    else    else
3565  #endif  #endif
3566      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3567    #else
3568    #ifdef COMPILE_PCRE16
3569    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3570      if (context->length >= 4)
3571        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3572      else
3573    #endif
3574        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3575    #endif
3576    #endif /* COMPILE_PCRE8 */
3577    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3578    }    }
3579    
3580  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3581  utf8length = 1;  utflength = 1;
3582  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3583    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3584    
3585  do  do
3586    {    {
3587  #endif  #endif
3588    
3589    context->length--;    context->length -= IN_UCHARS(1);
3590  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3591    
3592    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3593    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3594      {      {
3595      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3596      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3597      }      }
3598    else    else
3599      {      {
3600      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3601      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3602      }      }
3603    context->byteptr++;    context->ucharptr++;
3604    
3605    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
3606      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3607    #else
3608      if (context->ucharptr >= 2 || context->length == 0)
3609    #endif
3610      {      {
3611      if (context->length >= 4)      if (context->length >= 4)
3612        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);
3613    #ifdef COMPILE_PCRE8
3614      else if (context->length >= 2)      else if (context->length >= 2)
3615        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);
3616      else if (context->length >= 1)      else if (context->length >= 1)
3617        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);
3618    #else
3619        else if (context->length >= 2)
3620          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3621    #endif
3622      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3623    
3624      switch(context->byteptr)      switch(context->ucharptr)
3625        {        {
3626        case 4:        case 4 / sizeof(pcre_uchar):
3627        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3628          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);
3629        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));
3630        break;        break;
3631    
3632        case 2:        case 2 / sizeof(pcre_uchar):
3633        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3634          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);
3635        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));
3636        break;        break;
3637    
3638    #ifdef COMPILE_PCRE8
3639        case 1:        case 1:
3640        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3641          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);
3642        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));
3643        break;        break;
3644    #endif
3645    
3646        default:        default:
3647        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3648        break;        break;
3649        }        }
3650      context->byteptr = 0;      context->ucharptr = 0;
3651      }      }
3652    
3653  #else  #else
3654    
3655    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
3656    #ifdef COMPILE_PCRE8
3657    if (context->length > 0)    if (context->length > 0)
3658      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);
3659    #else
3660      if (context->length > 0)
3661        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3662    #endif
3663    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3664    
3665    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3666      {      {
3667      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3668      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));
3669      }      }
3670    else    else
3671      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));
3672    
3673  #endif  #endif
3674    
3675    cc++;    cc++;
3676  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3677    utf8length--;    utflength--;
3678    }    }
3679  while (utf8length > 0);  while (utflength > 0);
3680  #endif  #endif
3681    
3682  return cc;  return cc;
3683  }  }
3684    
3685  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3686    
3687  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
3688    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2386  return cc; Line 3704  return cc;
3704      } \      } \
3705    charoffset = (value);    charoffset = (value);
3706    
3707  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)
3708  {  {
3709  DEFINE_COMPILER;  DEFINE_COMPILER;
3710  jump_list *found = NULL;  jump_list *found = NULL;
3711  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3712  unsigned int c;  unsigned int c;
3713  int compares;  int compares;
3714  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3715  uschar *ccbegin;  pcre_uchar *ccbegin;
3716  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3717  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3718  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2404  unsigned int typeoffset; Line 3722  unsigned int typeoffset;
3722  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3723  unsigned int charoffset;  unsigned int charoffset;
3724    
3725  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF must be defined, we are
3726  check_input_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3727    detect_partial_match(common, backtracks);
3728  read_char(common);  read_char(common);
3729    
3730  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
3731    {    {
3732    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3733    if (common->utf8)  #ifndef COMPILE_PCRE8
3734      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3735    #elif defined SUPPORT_UTF
3736      if (common->utf)
3737      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3738    #endif
3739    
3740    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3741    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3742    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3743    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3744    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);
3745    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3746        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3747        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3748        }
3749    
3750    if (common->utf8)  #ifndef COMPILE_PCRE8
3751      JUMPHERE(jump);
3752    #elif defined SUPPORT_UTF
3753      if (common->utf)
3754      JUMPHERE(jump);      JUMPHERE(jump);
3755    #endif
3756    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3757  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3758    charsaved = TRUE;    charsaved = TRUE;
3759  #endif  #endif
3760    cc += 32;    cc += 32 / sizeof(pcre_uchar);
3761    }    }
3762    
3763  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2439  while (*cc != XCL_END) Line 3769  while (*cc != XCL_END)
3769    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3770      {      {
3771      cc += 2;      cc += 2;
3772  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3773      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]);
3774  #endif  #endif
3775  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3776      needschar = TRUE;      needschar = TRUE;
# Line 2449  while (*cc != XCL_END) Line 3779  while (*cc != XCL_END)
3779    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3780      {      {
3781      cc += 2;      cc += 2;
3782  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3783      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]);
3784  #endif  #endif
3785      cc++;      cc++;
3786  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3787      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]);
3788  #endif  #endif
3789  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3790      needschar = TRUE;      needschar = TRUE;
# Line 2524  if (needstype || needsscript) Line 3854  if (needstype || needsscript)
3854      {      {
3855      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3856        {        {
3857        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));
3858        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3859        }        }
3860      else      else
3861        {        {
3862        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3863        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));
3864        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3865        }        }
3866      }      }
# Line 2548  typeoffset = 0; Line 3878  typeoffset = 0;
3878  while (*cc != XCL_END)  while (*cc != XCL_END)
3879    {    {
3880    compares--;    compares--;
3881    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3882    jump = NULL;    jump = NULL;
3883    
3884    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3885      {      {
3886      cc ++;      cc ++;
3887  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3888      if (common->utf8)      if (common->utf)
3889        {        {
3890        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3891        }        }
# Line 2585  while (*cc != XCL_END) Line 3915  while (*cc != XCL_END)
3915    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3916      {      {
3917      cc ++;      cc ++;
3918  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3919      if (common->utf8)      if (common->utf)
3920        {        {
3921        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3922        }        }
# Line 2594  while (*cc != XCL_END) Line 3924  while (*cc != XCL_END)
3924  #endif  #endif
3925        c = *cc++;        c = *cc++;
3926      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3927  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3928      if (common->utf8)      if (common->utf)
3929        {        {
3930        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3931        }        }
# Line 2630  while (*cc != XCL_END) Line 3960  while (*cc != XCL_END)
3960      switch(*cc)      switch(*cc)
3961        {        {
3962        case PT_ANY:        case PT_ANY:
3963        if (list != fallbacks)        if (list != backtracks)
3964          {          {
3965          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))
3966            continue;            continue;
# Line 2651  while (*cc != XCL_END) Line 3981  while (*cc != XCL_END)
3981        break;        break;
3982    
3983        case PT_GC:        case PT_GC:
3984        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3985        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3986        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);
3987        break;        break;
3988    
3989        case PT_PC:        case PT_PC:
# Line 2703  while (*cc != XCL_END) Line 4033  while (*cc != XCL_END)
4033  #endif  #endif
4034    
4035    if (jump != NULL)    if (jump != NULL)
4036      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
4037    }    }
4038    
4039  if (found != NULL)  if (found != NULL)
# Line 2715  if (found != NULL) Line 4045  if (found != NULL)
4045    
4046  #endif  #endif
4047    
4048  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)
4049  {  {
4050  DEFINE_COMPILER;  DEFINE_COMPILER;
4051  int length;  int length;
4052  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4053  compare_context context;  compare_context context;
4054  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4055  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4056  struct sljit_label *label;  struct sljit_label *label;
4057  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4058  uschar propdata[5];  pcre_uchar propdata[5];
4059  #endif  #endif
4060  #endif  #endif
4061    
# Line 2734  switch(type) Line 4064  switch(type)
4064    case OP_SOD:    case OP_SOD:
4065    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4066    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));
4067    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));
4068    return cc;    return cc;
4069    
4070    case OP_SOM:    case OP_SOM:
4071    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4072    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));
4073    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));
4074    return cc;    return cc;
4075    
4076    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4077    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4078    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4079    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));
4080    return cc;    return cc;