/[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 696 by zherczeg, Sun Sep 18 15:09:49 2011 UTC revision 1209 by zherczeg, Wed Nov 7 07:25:07 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 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
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;    pcre_uint32 top_bracket;
174      sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
175    } executable_functions;
176    
177  typedef struct jump_list {  typedef struct jump_list {
178    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 176  typedef struct stub_list { Line 185  typedef struct stub_list {
185    enum stub_types type;    enum stub_types type;
186    int data;    int data;
187    struct sljit_jump *start;    struct sljit_jump *start;
188    struct sljit_label *leave;    struct sljit_label *quit;
189    struct stub_list *next;    struct stub_list *next;
190  } stub_list;  } stub_list;
191    
192  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
193    
194  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
195  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
196  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
197  of its descendants. */  of its descendants. */
198  typedef struct fallback_common {  typedef struct backtrack_common {
199    /* Concatenation stack. */    /* Concatenation stack. */
200    struct fallback_common *prev;    struct backtrack_common *prev;
201    jump_list *nextfallbacks;    jump_list *nextbacktracks;
202    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
203    struct fallback_common *top;    struct backtrack_common *top;
204    jump_list *topfallbacks;    jump_list *topbacktracks;
205    /* Opcode pointer. */    /* Opcode pointer. */
206    uschar *cc;    pcre_uchar *cc;
207  } fallback_common;  } backtrack_common;
208    
209  typedef struct assert_fallback {  typedef struct assert_backtrack {
210    fallback_common common;    backtrack_common common;
211    jump_list *condfailed;    jump_list *condfailed;
212    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
213    int framesize;    int framesize;
214    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
215    int localptr;    int private_data_ptr;
216    /* For iterators. */    /* For iterators. */
217    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
218  } assert_fallback;  } assert_backtrack;
219    
220  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
221    fallback_common common;    backtrack_common common;
222    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
223    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
224    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
225    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
226    /* For greedy ? operator. */    /* For greedy ? operator. */
227    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
228    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
229    union {    union {
230      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
231      jump_list *condfailed;      jump_list *condfailed;
232      assert_fallback *assert;      assert_backtrack *assert;
233      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
234      int framesize;      int framesize;
235    } u;    } u;
236    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
237    int localptr;    int private_data_ptr;
238  } bracket_fallback;  } bracket_backtrack;
239    
240  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
241    fallback_common common;    backtrack_common common;
242    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
243    int localptr;    int private_data_ptr;
244    /* Reverting stack is needed. */    /* Reverting stack is needed. */
245    int framesize;    int framesize;
246    /* Allocated stack size. */    /* Allocated stack size. */
247    int stacksize;    int stacksize;
248  } bracketpos_fallback;  } bracketpos_backtrack;
249    
250  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
251    fallback_common common;    backtrack_common common;
252    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
253  } braminzero_fallback;  } braminzero_backtrack;
254    
255  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
256    fallback_common common;    backtrack_common common;
257    /* Next iteration. */    /* Next iteration. */
258    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
259  } iterator_fallback;  } iterator_backtrack;
260    
261  typedef struct recurse_entry {  typedef struct recurse_entry {
262    struct recurse_entry *next;    struct recurse_entry *next;
# Line 259  typedef struct recurse_entry { Line 268  typedef struct recurse_entry {
268    int start;    int start;
269  } recurse_entry;  } recurse_entry;
270    
271  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
272    fallback_common common;    backtrack_common common;
273  } recurse_fallback;  } recurse_backtrack;
274    
275    #define MAX_RANGE_SIZE 6
276    
277  typedef struct compiler_common {  typedef struct compiler_common {
278    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
279    uschar *start;    pcre_uchar *start;
280    int localsize;  
281    int *localptrs;    /* Maps private data offset to each opcode. */
282    const uschar *fcc;    int *private_data_ptrs;
283    sljit_w lcc;    /* Tells whether the capturing bracket is optimized. */
284      pcre_uint8 *optimized_cbracket;
285      /* Starting offset of private data for capturing brackets. */
286    int cbraptr;    int cbraptr;
287      /* OVector starting point. Must be divisible by 2. */
288      int ovector_start;
289      /* Last known position of the requested byte. */
290      int req_char_ptr;
291      /* Head of the last recursion. */
292      int recursive_head;
293      /* First inspected character for partial matching. */
294      int start_used_ptr;
295      /* Starting pointer for partial soft matches. */
296      int hit_start;
297      /* End pointer of the first line. */
298      int first_line_end;
299      /* Points to the marked string. */
300      int mark_ptr;
301    
302      /* Flipped and lower case tables. */
303      const pcre_uint8 *fcc;
304      sljit_sw lcc;
305      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
306      int mode;
307      /* Newline control. */
308    int nltype;    int nltype;
309    int newline;    int newline;
310    int bsr_nltype;    int bsr_nltype;
311      /* Dollar endonly. */
312    int endonly;    int endonly;
313    sljit_w ctypes;    BOOL has_set_som;
314      /* Tables. */
315      sljit_sw ctypes;
316      int digits[2 + MAX_RANGE_SIZE];
317      /* Named capturing brackets. */
318      sljit_uw name_table;
319      sljit_sw name_count;
320      sljit_sw name_entry_size;
321    
322      /* Labels and jump lists. */
323      struct sljit_label *partialmatchlabel;
324      struct sljit_label *quitlabel;
325    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
326    stub_list *stubs;    stub_list *stubs;
327    recurse_entry *entries;    recurse_entry *entries;
328    recurse_entry *currententry;    recurse_entry *currententry;
329      jump_list *partialmatch;
330      jump_list *quit;
331    jump_list *accept;    jump_list *accept;
332    jump_list *calllimit;    jump_list *calllimit;
333    jump_list *stackalloc;    jump_list *stackalloc;
# Line 291  typedef struct compiler_common { Line 339  typedef struct compiler_common {
339    jump_list *casefulcmp;    jump_list *casefulcmp;
340    jump_list *caselesscmp;    jump_list *caselesscmp;
341    BOOL jscript_compat;    BOOL jscript_compat;
342  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
343    BOOL utf8;    BOOL utf;
344  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
345    BOOL useucp;    BOOL use_ucp;
346  #endif  #endif
347    jump_list *utf8readchar;  #ifndef COMPILE_PCRE32
348    jump_list *utf8readtype8;    jump_list *utfreadchar;
349  #endif  #endif
350    #ifdef COMPILE_PCRE8
351      jump_list *utfreadtype8;
352    #endif
353    #endif /* SUPPORT_UTF */
354  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
355    jump_list *getucd;    jump_list *getucd;
356  #endif  #endif
# Line 310  typedef struct compare_context { Line 362  typedef struct compare_context {
362    int length;    int length;
363    int sourcereg;    int sourcereg;
364  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
365    int byteptr;    int ucharptr;
366    union {    union {
367      int asint;      sljit_si asint;
368      short asshort;      sljit_uh asushort;
369    #if defined COMPILE_PCRE8
370      sljit_ub asbyte;      sljit_ub asbyte;
371      sljit_ub asbytes[4];      sljit_ub asuchars[4];
372    #elif defined COMPILE_PCRE16
373        sljit_uh asuchars[2];
374    #elif defined COMPILE_PCRE32
375        sljit_ui asuchars[1];
376    #endif
377    } c;    } c;
378    union {    union {
379      int asint;      sljit_si asint;
380      short asshort;      sljit_uh asushort;
381    #if defined COMPILE_PCRE8
382      sljit_ub asbyte;      sljit_ub asbyte;
383      sljit_ub asbytes[4];      sljit_ub asuchars[4];
384    #elif defined COMPILE_PCRE16
385        sljit_uh asuchars[2];
386    #elif defined COMPILE_PCRE32
387        sljit_ui asuchars[1];
388    #endif
389    } oc;    } oc;
390  #endif  #endif
391  } compare_context;  } compare_context;
392    
393  enum {  enum {
394    frame_end = 0,    frame_end = 0,
395    frame_setstrbegin = -1    frame_setstrbegin = -1,
396      frame_setmark = -2
397  };  };
398    
399    /* Undefine sljit macros. */
400    #undef CMP
401    
402  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
403  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
404    
405  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
406  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
407  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
408  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
409  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
410  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
411  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
412  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
413  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
414  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
415    
416  /* Locals layout. */  /* Local space layout. */
417  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
418  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
419  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
420  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
421  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
422  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
 /* Head of the saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  
423  /* Max limit of recursions. */  /* Max limit of recursions. */
424  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * sizeof(sljit_w))  
425  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
426  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
427  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
428  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
429  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
430  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
431  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))
432  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
433    
434    #if defined COMPILE_PCRE8
435    #define MOV_UCHAR  SLJIT_MOV_UB
436    #define MOVU_UCHAR SLJIT_MOVU_UB
437    #elif defined COMPILE_PCRE16
438    #define MOV_UCHAR  SLJIT_MOV_UH
439    #define MOVU_UCHAR SLJIT_MOVU_UH
440    #elif defined COMPILE_PCRE32
441    #define MOV_UCHAR  SLJIT_MOV_UI
442    #define MOVU_UCHAR SLJIT_MOVU_UI
443    #else
444    #error Unsupported compiling mode
445    #endif
446    
447  /* Shortcuts. */  /* Shortcuts. */
448  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 390  the start pointers when the end of the c Line 463  the start pointers when the end of the c
463    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
464  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
465    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))    sljit_set_label(sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w)), (label))
466  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
467    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
468    #define GET_LOCAL_BASE(dst, dstw, offset) \
469      sljit_get_local_base(compiler, (dst), (dstw), (offset))
470    
471  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
472  {  {
473  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));
474  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 404  return cc; Line 479  return cc;
479    
480  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
481   next_opcode   next_opcode
482   get_localspace   get_private_data_length
483   set_localptrs   set_private_data_ptrs
484   get_framesize   get_framesize
485   init_frame   init_frame
486   get_localsize   get_private_data_length_for_copy
487   copy_locals   copy_private_data
488   compile_hotpath   compile_matchingpath
489   compile_fallbackpath   compile_backtrackingpath
490  */  */
491    
492  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
493  {  {
494  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
495  switch(*cc)  switch(*cc)
# Line 463  switch(*cc) Line 538  switch(*cc)
538    case OP_BRAZERO:    case OP_BRAZERO:
539    case OP_BRAMINZERO:    case OP_BRAMINZERO:
540    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
541      case OP_COMMIT:
542    case OP_FAIL:    case OP_FAIL:
543    case OP_ACCEPT:    case OP_ACCEPT:
544    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
545    case OP_SKIPZERO:    case OP_SKIPZERO:
546    return cc + 1;    return cc + 1;
547    
548      case OP_ANYBYTE:
549    #ifdef SUPPORT_UTF
550      if (common->utf) return NULL;
551    #endif
552      return cc + 1;
553    
554    case OP_CHAR:    case OP_CHAR:
555    case OP_CHARI:    case OP_CHARI:
556    case OP_NOT:    case OP_NOT:
557    case OP_NOTI:    case OP_NOTI:
   
558    case OP_STAR:    case OP_STAR:
559    case OP_MINSTAR:    case OP_MINSTAR:
560    case OP_PLUS:    case OP_PLUS:
# Line 511  switch(*cc) Line 592  switch(*cc)
592    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
593    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
594    cc += 2;    cc += 2;
595  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
596    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]);
597  #endif  #endif
598    return cc;    return cc;
599    
# Line 532  switch(*cc) Line 613  switch(*cc)
613    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
614    case OP_NOTEXACTI:    case OP_NOTEXACTI:
615    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
616    cc += 4;    cc += 2 + IMM2_SIZE;
617  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
618    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]);
619  #endif  #endif
620    return cc;    return cc;
621    
622    case OP_NOTPROP:    case OP_NOTPROP:
623    case OP_PROP:    case OP_PROP:
624      return cc + 1 + 2;
625    
626    case OP_TYPEUPTO:    case OP_TYPEUPTO:
627    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
628    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 547  switch(*cc) Line 630  switch(*cc)
630    case OP_REF:    case OP_REF:
631    case OP_REFI:    case OP_REFI:
632    case OP_CREF:    case OP_CREF:
633      case OP_NCREF:
634      case OP_RREF:
635      case OP_NRREF:
636    case OP_CLOSE:    case OP_CLOSE:
637    cc += 3;    cc += 1 + IMM2_SIZE;
638    return cc;    return cc;
639    
640    case OP_CRRANGE:    case OP_CRRANGE:
641    case OP_CRMINRANGE:    case OP_CRMINRANGE:
642    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
643    
644    case OP_CLASS:    case OP_CLASS:
645    case OP_NCLASS:    case OP_NCLASS:
646    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
647    
648  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
649    case OP_XCLASS:    case OP_XCLASS:
650    return cc + GET(cc, 1);    return cc + GET(cc, 1);
651  #endif  #endif
# Line 571  switch(*cc) Line 657  switch(*cc)
657    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
658    case OP_REVERSE:    case OP_REVERSE:
659    case OP_ONCE:    case OP_ONCE:
660      case OP_ONCE_NC:
661    case OP_BRA:    case OP_BRA:
662    case OP_BRAPOS:    case OP_BRAPOS:
663    case OP_COND:    case OP_COND:
# Line 588  switch(*cc) Line 675  switch(*cc)
675    case OP_CBRAPOS:    case OP_CBRAPOS:
676    case OP_SCBRA:    case OP_SCBRA:
677    case OP_SCBRAPOS:    case OP_SCBRAPOS:
678    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
679    
680      case OP_MARK:
681      return cc + 1 + 2 + cc[1];
682    
683    default:    default:
684    return NULL;    return NULL;
685    }    }
686  }  }
687    
688  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
689        case OP_MINSTAR: \
690        case OP_MINPLUS: \
691        case OP_QUERY: \
692        case OP_MINQUERY: \
693        case OP_MINSTARI: \
694        case OP_MINPLUSI: \
695        case OP_QUERYI: \
696        case OP_MINQUERYI: \
697        case OP_NOTMINSTAR: \
698        case OP_NOTMINPLUS: \
699        case OP_NOTQUERY: \
700        case OP_NOTMINQUERY: \
701        case OP_NOTMINSTARI: \
702        case OP_NOTMINPLUSI: \
703        case OP_NOTQUERYI: \
704        case OP_NOTMINQUERYI:
705    
706    #define CASE_ITERATOR_PRIVATE_DATA_2A \
707        case OP_STAR: \
708        case OP_PLUS: \
709        case OP_STARI: \
710        case OP_PLUSI: \
711        case OP_NOTSTAR: \
712        case OP_NOTPLUS: \
713        case OP_NOTSTARI: \
714        case OP_NOTPLUSI:
715    
716    #define CASE_ITERATOR_PRIVATE_DATA_2B \
717        case OP_UPTO: \
718        case OP_MINUPTO: \
719        case OP_UPTOI: \
720        case OP_MINUPTOI: \
721        case OP_NOTUPTO: \
722        case OP_NOTMINUPTO: \
723        case OP_NOTUPTOI: \
724        case OP_NOTMINUPTOI:
725    
726    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
727        case OP_TYPEMINSTAR: \
728        case OP_TYPEMINPLUS: \
729        case OP_TYPEQUERY: \
730        case OP_TYPEMINQUERY:
731    
732    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
733        case OP_TYPESTAR: \
734        case OP_TYPEPLUS:
735    
736    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
737        case OP_TYPEUPTO: \
738        case OP_TYPEMINUPTO:
739    
740    static int get_class_iterator_size(pcre_uchar *cc)
741    {
742    switch(*cc)
743      {
744      case OP_CRSTAR:
745      case OP_CRPLUS:
746      return 2;
747    
748      case OP_CRMINSTAR:
749      case OP_CRMINPLUS:
750      case OP_CRQUERY:
751      case OP_CRMINQUERY:
752      return 1;
753    
754      case OP_CRRANGE:
755      case OP_CRMINRANGE:
756      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
757        return 0;
758      return 2;
759    
760      default:
761      return 0;
762      }
763    }
764    
765    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
766  {  {
767  int localspace = 0;  int private_data_length = 0;
768  uschar *alternative;  pcre_uchar *alternative;
769    pcre_uchar *name;
770    pcre_uchar *end = NULL;
771    int space, size, i;
772    pcre_uint32 bracketlen;
773    
774  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
775  while (cc < ccend)  while (cc < ccend)
776    {    {
777      space = 0;
778      size = 0;
779      bracketlen = 0;
780    switch(*cc)    switch(*cc)
781      {      {
782        case OP_SET_SOM:
783        common->has_set_som = TRUE;
784        cc += 1;
785        break;
786    
787        case OP_REF:
788        case OP_REFI:
789        common->optimized_cbracket[GET2(cc, 1)] = 0;
790        cc += 1 + IMM2_SIZE;
791        break;
792    
793      case OP_ASSERT:      case OP_ASSERT:
794      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
795      case OP_ASSERTBACK:      case OP_ASSERTBACK:
796      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
797      case OP_ONCE:      case OP_ONCE:
798        case OP_ONCE_NC:
799      case OP_BRAPOS:      case OP_BRAPOS:
800      case OP_SBRA:      case OP_SBRA:
801      case OP_SBRAPOS:      case OP_SBRAPOS:
802      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
803      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
804      break;      break;
805    
806      case OP_CBRAPOS:      case OP_CBRAPOS:
807      case OP_SCBRAPOS:      case OP_SCBRAPOS:
808      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
809      cc += 1 + LINK_SIZE + 2;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
810        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
811      break;      break;
812    
813      case OP_COND:      case OP_COND:
814      /* Might be a hidden SCOND. */      case OP_SCOND:
815      alternative = cc + GET(cc, 1);      bracketlen = cc[1 + LINK_SIZE];
816      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (bracketlen == OP_CREF)
817        localspace += sizeof(sljit_w);        {
818          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
819          common->optimized_cbracket[bracketlen] = 0;
820          }
821        else if (bracketlen == OP_NCREF)
822          {
823          bracketlen = GET2(cc, 1 + LINK_SIZE + 1);
824          name = (pcre_uchar *)common->name_table;
825          alternative = name;
826          for (i = 0; i < common->name_count; i++)
827            {
828            if (GET2(name, 0) == bracketlen) break;
829            name += common->name_entry_size;
830            }
831          SLJIT_ASSERT(i != common->name_count);
832    
833          for (i = 0; i < common->name_count; i++)
834            {
835            if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
836              common->optimized_cbracket[GET2(alternative, 0)] = 0;
837            alternative += common->name_entry_size;
838            }
839          }
840    
841        if (*cc == OP_COND)
842          {
843          /* Might be a hidden SCOND. */
844          alternative = cc + GET(cc, 1);
845          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
846            private_data_length += sizeof(sljit_sw);
847          }
848        else
849          private_data_length += sizeof(sljit_sw);
850        bracketlen = 1 + LINK_SIZE;
851        break;
852    
853        case OP_BRA:
854        bracketlen = 1 + LINK_SIZE;
855        break;
856    
857        case OP_CBRA:
858        case OP_SCBRA:
859        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
860        break;
861    
862        CASE_ITERATOR_PRIVATE_DATA_1
863        space = 1;
864        size = -2;
865        break;
866    
867        CASE_ITERATOR_PRIVATE_DATA_2A
868        space = 2;
869        size = -2;
870        break;
871    
872        CASE_ITERATOR_PRIVATE_DATA_2B
873        space = 2;
874        size = -(2 + IMM2_SIZE);
875        break;
876    
877        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
878        space = 1;
879        size = 1;
880        break;
881    
882        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
883        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
884          space = 2;
885        size = 1;
886        break;
887    
888        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
889        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
890          space = 2;
891        size = 1 + IMM2_SIZE;
892        break;
893    
894        case OP_CLASS:
895        case OP_NCLASS:
896        size += 1 + 32 / sizeof(pcre_uchar);
897        space = get_class_iterator_size(cc + size);
898        break;
899    
900    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
901        case OP_XCLASS:
902        size = GET(cc, 1);
903        space = get_class_iterator_size(cc + size);
904        break;
905    #endif
906    
907        case OP_RECURSE:
908        /* Set its value only once. */
909        if (common->recursive_head == 0)
910          {
911          common->recursive_head = common->ovector_start;
912          common->ovector_start += sizeof(sljit_sw);
913          }
914      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
915      break;      break;
916    
917        case OP_MARK:
918        if (common->mark_ptr == 0)
919          {
920          common->mark_ptr = common->ovector_start;
921          common->ovector_start += sizeof(sljit_sw);
922          }
923        cc += 1 + 2 + cc[1];
924        break;
925    
926      default:      default:
927      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
928      if (cc == NULL)      if (cc == NULL)
929        return -1;        return -1;
930      break;      break;
931      }      }
932    
933      if (space > 0 && cc >= end)
934        private_data_length += sizeof(sljit_sw) * space;
935    
936      if (size != 0)
937        {
938        if (size < 0)
939          {
940          cc += -size;
941    #ifdef SUPPORT_UTF
942          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
943    #endif
944          }
945        else
946          cc += size;
947        }
948    
949      if (bracketlen != 0)
950        {
951        if (cc >= end)
952          {
953          end = bracketend(cc);
954          if (end[-1 - LINK_SIZE] == OP_KET)
955            end = NULL;
956          }
957        cc += bracketlen;
958        }
959    }    }
960  return localspace;  return private_data_length;
961  }  }
962    
963  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
964  {  {
965  uschar *cc = common->start;  pcre_uchar *cc = common->start;
966  uschar *alternative;  pcre_uchar *alternative;
967    pcre_uchar *end = NULL;
968    int space, size, bracketlen;
969    
970  while (cc < ccend)  while (cc < ccend)
971    {    {
972      space = 0;
973      size = 0;
974      bracketlen = 0;
975    switch(*cc)    switch(*cc)
976      {      {
977      case OP_ASSERT:      case OP_ASSERT:
# Line 654  while (cc < ccend) Line 979  while (cc < ccend)
979      case OP_ASSERTBACK:      case OP_ASSERTBACK:
980      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
981      case OP_ONCE:      case OP_ONCE:
982        case OP_ONCE_NC:
983      case OP_BRAPOS:      case OP_BRAPOS:
984      case OP_SBRA:      case OP_SBRA:
985      case OP_SBRAPOS:      case OP_SBRAPOS:
986      case OP_SCOND:      case OP_SCOND:
987      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
988      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
989      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
990      break;      break;
991    
992      case OP_CBRAPOS:      case OP_CBRAPOS:
993      case OP_SCBRAPOS:      case OP_SCBRAPOS:
994      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
995      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
996      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
997      break;      break;
998    
999      case OP_COND:      case OP_COND:
# Line 675  while (cc < ccend) Line 1001  while (cc < ccend)
1001      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1002      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1003        {        {
1004        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1005        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1006        }        }
1007      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1008        break;
1009    
1010        case OP_BRA:
1011        bracketlen = 1 + LINK_SIZE;
1012        break;
1013    
1014        case OP_CBRA:
1015        case OP_SCBRA:
1016        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1017        break;
1018    
1019        CASE_ITERATOR_PRIVATE_DATA_1
1020        space = 1;
1021        size = -2;
1022        break;
1023    
1024        CASE_ITERATOR_PRIVATE_DATA_2A
1025        space = 2;
1026        size = -2;
1027        break;
1028    
1029        CASE_ITERATOR_PRIVATE_DATA_2B
1030        space = 2;
1031        size = -(2 + IMM2_SIZE);
1032        break;
1033    
1034        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1035        space = 1;
1036        size = 1;
1037        break;
1038    
1039        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1040        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1041          space = 2;
1042        size = 1;
1043        break;
1044    
1045        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1046        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1047          space = 2;
1048        size = 1 + IMM2_SIZE;
1049        break;
1050    
1051        case OP_CLASS:
1052        case OP_NCLASS:
1053        size += 1 + 32 / sizeof(pcre_uchar);
1054        space = get_class_iterator_size(cc + size);
1055        break;
1056    
1057    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1058        case OP_XCLASS:
1059        size = GET(cc, 1);
1060        space = get_class_iterator_size(cc + size);
1061      break;      break;
1062    #endif
1063    
1064      default:      default:
1065      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1066      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1067      break;      break;
1068      }      }
1069    
1070      if (space > 0 && cc >= end)
1071        {
1072        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1073        private_data_ptr += sizeof(sljit_sw) * space;
1074        }
1075    
1076      if (size != 0)
1077        {
1078        if (size < 0)
1079          {
1080          cc += -size;
1081    #ifdef SUPPORT_UTF
1082          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1083    #endif
1084          }
1085        else
1086          cc += size;
1087        }
1088    
1089      if (bracketlen > 0)
1090        {
1091        if (cc >= end)
1092          {
1093          end = bracketend(cc);
1094          if (end[-1 - LINK_SIZE] == OP_KET)
1095            end = NULL;
1096          }
1097        cc += bracketlen;
1098        }
1099    }    }
1100  }  }
1101    
1102  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
1103  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1104  {  {
1105  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
1106  int length = 0;  int length = 0;
1107  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1108  BOOL needs_frame = FALSE;  BOOL setsom_found = recursive;
1109  BOOL setsom_found = FALSE;  BOOL setmark_found = recursive;
1110    
1111  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1112    {    {
# Line 711  while (cc < ccend) Line 1120  while (cc < ccend)
1120    switch(*cc)    switch(*cc)
1121      {      {
1122      case OP_SET_SOM:      case OP_SET_SOM:
1123      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1124      if (!setsom_found)      if (!setsom_found)
1125        {        {
1126        length += 2;        length += 2;
1127        setsom_found = TRUE;        setsom_found = TRUE;
1128        }        }
1129      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1130      break;      break;
1131    
1132      case OP_ASSERT:      case OP_MARK:
1133      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
1134      case OP_ASSERTBACK:      if (!setmark_found)
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
1135        {        {
1136        cc = bracketend(cc);        length += 2;
1137        break;        setmark_found = TRUE;
1138        }        }
1139      /* Check whether a frame must be created. */      cc += 1 + 2 + cc[1];
1140      end = bracketend(cc);      break;
1141      while (cc < end)  
1142        {      case OP_RECURSE:
1143        if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS      if (common->has_set_som && !setsom_found)
1144            || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)        {
1145          needs_frame = TRUE;        length += 2;
1146        cc = next_opcode(common, cc);        setsom_found = TRUE;
1147        SLJIT_ASSERT(cc != NULL);        }
1148        if (common->mark_ptr != 0 && !setmark_found)
1149          {
1150          length += 2;
1151          setmark_found = TRUE;
1152        }        }
1153        cc += 1 + LINK_SIZE;
1154      break;      break;
1155    
1156      case OP_CBRA:      case OP_CBRA:
# Line 747  while (cc < ccend) Line 1158  while (cc < ccend)
1158      case OP_SCBRA:      case OP_SCBRA:
1159      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1160      length += 3;      length += 3;
1161      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1162      break;      break;
1163    
1164      default:      default:
# Line 757  while (cc < ccend) Line 1168  while (cc < ccend)
1168      }      }
1169    
1170  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1171  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
1172    return -1;    return -1;
1173    
1174  if (length > 0)  if (length > 0)
1175    return length + 2;    return length + 1;
1176  return needs_frame ? 0 : -1;  return -1;
1177  }  }
1178    
1179  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)
1180  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
1181  DEFINE_COMPILER;  DEFINE_COMPILER;
1182  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1183  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1184    BOOL setmark_found = recursive;
1185  int offset;  int offset;
1186    
1187  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
1188    {  SLJIT_UNUSED_ARG(stacktop);
1189    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
1190    
1191  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacktop), TMP1, 0);  
   
1192  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1193    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
1194  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 791  while (cc < ccend) Line 1196  while (cc < ccend)
1196    switch(*cc)    switch(*cc)
1197      {      {
1198      case OP_SET_SOM:      case OP_SET_SOM:
1199      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1200      if (!setsom_found)      if (!setsom_found)
1201        {        {
1202        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1203        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1204        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1205        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1206        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1207        setsom_found = TRUE;        setsom_found = TRUE;
1208        }        }
1209      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1210      break;      break;
1211    
1212      case OP_ASSERT:      case OP_MARK:
1213      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
1214      case OP_ASSERTBACK:      if (!setmark_found)
1215      case OP_ASSERTBACK_NOT:        {
1216      case OP_ONCE:        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1217      cc = bracketend(cc);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1218          stackpos += (int)sizeof(sljit_sw);
1219          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1220          stackpos += (int)sizeof(sljit_sw);
1221          setmark_found = TRUE;
1222          }
1223        cc += 1 + 2 + cc[1];
1224        break;
1225    
1226        case OP_RECURSE:
1227        if (common->has_set_som && !setsom_found)
1228          {
1229          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1230          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1231          stackpos += (int)sizeof(sljit_sw);
1232          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1233          stackpos += (int)sizeof(sljit_sw);
1234          setsom_found = TRUE;
1235          }
1236        if (common->mark_ptr != 0 && !setmark_found)
1237          {
1238          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1239          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1240          stackpos += (int)sizeof(sljit_sw);
1241          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1242          stackpos += (int)sizeof(sljit_sw);
1243          setmark_found = TRUE;
1244          }
1245        cc += 1 + LINK_SIZE;
1246      break;      break;
1247    
1248      case OP_CBRA:      case OP_CBRA:
# Line 818  while (cc < ccend) Line 1251  while (cc < ccend)
1251      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1252      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1253      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1254      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1255      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1256      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
1257      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1258      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1259      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1260      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1261    
1262      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1263      break;      break;
1264    
1265      default:      default:
# Line 836  while (cc < ccend) Line 1269  while (cc < ccend)
1269      }      }
1270    
1271  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
1272  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1273  }  }
1274    
1275  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)
1276  {  {
1277  int localsize = 2;  int private_data_length = 2;
1278  uschar *alternative;  int size;
1279  /* Calculate the sum of the local variables. */  pcre_uchar *alternative;
1280    /* Calculate the sum of the private machine words. */
1281  while (cc < ccend)  while (cc < ccend)
1282    {    {
1283      size = 0;
1284    switch(*cc)    switch(*cc)
1285      {      {
1286      case OP_ASSERT:      case OP_ASSERT:
# Line 853  while (cc < ccend) Line 1288  while (cc < ccend)
1288      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1289      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1290      case OP_ONCE:      case OP_ONCE:
1291        case OP_ONCE_NC:
1292      case OP_BRAPOS:      case OP_BRAPOS:
1293      case OP_SBRA:      case OP_SBRA:
1294      case OP_SBRAPOS:      case OP_SBRAPOS:
1295      case OP_SCOND:      case OP_SCOND:
1296      localsize++;      private_data_length++;
1297      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1298      break;      break;
1299    
1300      case OP_CBRA:      case OP_CBRA:
1301      case OP_SCBRA:      case OP_SCBRA:
1302      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1303      cc += 1 + LINK_SIZE + 2;        private_data_length++;
1304        cc += 1 + LINK_SIZE + IMM2_SIZE;
1305      break;      break;
1306    
1307      case OP_CBRAPOS:      case OP_CBRAPOS:
1308      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1309      localsize += 2;      private_data_length += 2;
1310      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1311      break;      break;
1312    
1313      case OP_COND:      case OP_COND:
1314      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1315      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1316      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1317        localsize++;        private_data_length++;
1318      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1319      break;      break;
1320    
1321        CASE_ITERATOR_PRIVATE_DATA_1
1322        if (PRIVATE_DATA(cc))
1323          private_data_length++;
1324        cc += 2;
1325    #ifdef SUPPORT_UTF
1326        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1327    #endif
1328        break;
1329    
1330        CASE_ITERATOR_PRIVATE_DATA_2A
1331        if (PRIVATE_DATA(cc))
1332          private_data_length += 2;
1333        cc += 2;
1334    #ifdef SUPPORT_UTF
1335        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1336    #endif
1337        break;
1338    
1339        CASE_ITERATOR_PRIVATE_DATA_2B
1340        if (PRIVATE_DATA(cc))
1341          private_data_length += 2;
1342        cc += 2 + IMM2_SIZE;
1343    #ifdef SUPPORT_UTF
1344        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1345    #endif
1346        break;
1347    
1348        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1349        if (PRIVATE_DATA(cc))
1350          private_data_length++;
1351        cc += 1;
1352        break;
1353    
1354        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1355        if (PRIVATE_DATA(cc))
1356          private_data_length += 2;
1357        cc += 1;
1358        break;
1359    
1360        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1361        if (PRIVATE_DATA(cc))
1362          private_data_length += 2;
1363        cc += 1 + IMM2_SIZE;
1364        break;
1365    
1366        case OP_CLASS:
1367        case OP_NCLASS:
1368    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1369        case OP_XCLASS:
1370        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1371    #else
1372        size = 1 + 32 / (int)sizeof(pcre_uchar);
1373    #endif
1374        if (PRIVATE_DATA(cc))
1375          private_data_length += get_class_iterator_size(cc + size);
1376        cc += size;
1377        break;
1378    
1379      default:      default:
1380      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1381      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 888  while (cc < ccend) Line 1383  while (cc < ccend)
1383      }      }
1384    }    }
1385  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1386  return localsize;  return private_data_length;
1387  }  }
1388    
1389  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1390    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1391  {  {
1392  DEFINE_COMPILER;  DEFINE_COMPILER;
1393  int srcw[2];  int srcw[2];
1394  int count;  int count, size;
1395  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1396  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1397  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1398  uschar *alternative;  pcre_uchar *alternative;
1399  enum {  enum {
1400    start,    start,
1401    loop,    loop,
# Line 913  stacktop = STACK(stacktop - 1); Line 1408  stacktop = STACK(stacktop - 1);
1408    
1409  if (!save)  if (!save)
1410    {    {
1411    stackptr += sizeof(sljit_w);    stackptr += sizeof(sljit_sw);
1412    if (stackptr < stacktop)    if (stackptr < stacktop)
1413      {      {
1414      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1415      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1416      tmp1empty = FALSE;      tmp1empty = FALSE;
1417      }      }
1418    if (stackptr < stacktop)    if (stackptr < stacktop)
1419      {      {
1420      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1421      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1422      tmp2empty = FALSE;      tmp2empty = FALSE;
1423      }      }
1424    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
# Line 935  while (status != end) Line 1430  while (status != end)
1430    switch(status)    switch(status)
1431      {      {
1432      case start:      case start:
1433      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1434      count = 1;      count = 1;
1435      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1436      status = loop;      status = loop;
1437      break;      break;
1438    
# Line 955  while (status != end) Line 1450  while (status != end)
1450        case OP_ASSERTBACK:        case OP_ASSERTBACK:
1451        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
1452        case OP_ONCE:        case OP_ONCE:
1453          case OP_ONCE_NC:
1454        case OP_BRAPOS:        case OP_BRAPOS:
1455        case OP_SBRA:        case OP_SBRA:
1456        case OP_SBRAPOS:        case OP_SBRAPOS:
1457        case OP_SCOND:        case OP_SCOND:
1458        count = 1;        count = 1;
1459        srcw[0] = PRIV(cc);        srcw[0] = PRIVATE_DATA(cc);
1460        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1461        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1462        break;        break;
1463    
1464        case OP_CBRA:        case OP_CBRA:
1465        case OP_SCBRA:        case OP_SCBRA:
1466        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1467        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1468        cc += 1 + LINK_SIZE + 2;          count = 1;
1469            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1470            }
1471          cc += 1 + LINK_SIZE + IMM2_SIZE;
1472        break;        break;
1473    
1474        case OP_CBRAPOS:        case OP_CBRAPOS:
1475        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1476        count = 2;        count = 2;
1477          srcw[0] = PRIVATE_DATA(cc);
1478        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1479        srcw[0] = PRIV(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1480        SLJIT_ASSERT(srcw[0] != 0);        cc += 1 + LINK_SIZE + IMM2_SIZE;
       cc += 1 + LINK_SIZE + 2;  
1481        break;        break;
1482    
1483        case OP_COND:        case OP_COND:
# Line 987  while (status != end) Line 1486  while (status != end)
1486        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1487          {          {
1488          count = 1;          count = 1;
1489          srcw[0] = PRIV(cc);          srcw[0] = PRIVATE_DATA(cc);
1490          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1491          }          }
1492        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1493        break;        break;
1494    
1495        default:        CASE_ITERATOR_PRIVATE_DATA_1
1496        cc = next_opcode(common, cc);        if (PRIVATE_DATA(cc))
1497        SLJIT_ASSERT(cc != NULL);          {
1498        break;          count = 1;
1499        }          srcw[0] = PRIVATE_DATA(cc);
1500            }
1501          cc += 2;
1502    #ifdef SUPPORT_UTF
1503          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1504    #endif
1505          break;
1506    
1507          CASE_ITERATOR_PRIVATE_DATA_2A
1508          if (PRIVATE_DATA(cc))
1509            {
1510            count = 2;
1511            srcw[0] = PRIVATE_DATA(cc);
1512            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1513            }
1514          cc += 2;
1515    #ifdef SUPPORT_UTF
1516          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1517    #endif
1518          break;
1519    
1520          CASE_ITERATOR_PRIVATE_DATA_2B
1521          if (PRIVATE_DATA(cc))
1522            {
1523            count = 2;
1524            srcw[0] = PRIVATE_DATA(cc);
1525            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1526            }
1527          cc += 2 + IMM2_SIZE;
1528    #ifdef SUPPORT_UTF
1529          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1530    #endif
1531          break;
1532    
1533          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1534          if (PRIVATE_DATA(cc))
1535            {
1536            count = 1;
1537            srcw[0] = PRIVATE_DATA(cc);
1538            }
1539          cc += 1;
1540          break;
1541    
1542          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1543          if (PRIVATE_DATA(cc))
1544            {
1545            count = 2;
1546            srcw[0] = PRIVATE_DATA(cc);
1547            srcw[1] = srcw[0] + sizeof(sljit_sw);
1548            }
1549          cc += 1;
1550          break;
1551    
1552          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1553          if (PRIVATE_DATA(cc))
1554            {
1555            count = 2;
1556            srcw[0] = PRIVATE_DATA(cc);
1557            srcw[1] = srcw[0] + sizeof(sljit_sw);
1558            }
1559          cc += 1 + IMM2_SIZE;
1560          break;
1561    
1562          case OP_CLASS:
1563          case OP_NCLASS:
1564    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1565          case OP_XCLASS:
1566          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1567    #else
1568          size = 1 + 32 / (int)sizeof(pcre_uchar);
1569    #endif
1570          if (PRIVATE_DATA(cc))
1571            switch(get_class_iterator_size(cc + size))
1572              {
1573              case 1:
1574              count = 1;
1575              srcw[0] = PRIVATE_DATA(cc);
1576              break;
1577    
1578              case 2:
1579              count = 2;
1580              srcw[0] = PRIVATE_DATA(cc);
1581              srcw[1] = srcw[0] + sizeof(sljit_sw);
1582              break;
1583    
1584              default:
1585              SLJIT_ASSERT_STOP();
1586              break;
1587              }
1588          cc += size;
1589          break;
1590    
1591          default:
1592          cc = next_opcode(common, cc);
1593          SLJIT_ASSERT(cc != NULL);
1594          break;
1595          }
1596      break;      break;
1597    
1598      case end:      case end:
# Line 1015  while (status != end) Line 1610  while (status != end)
1610          if (!tmp1empty)          if (!tmp1empty)
1611            {            {
1612            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1613            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1614            }            }
1615          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1616          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1026  while (status != end) Line 1621  while (status != end)
1621          if (!tmp2empty)          if (!tmp2empty)
1622            {            {
1623            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1624            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1625            }            }
1626          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1627          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1043  while (status != end) Line 1638  while (status != end)
1638          if (!tmp1empty)          if (!tmp1empty)
1639            {            {
1640            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1641            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1642            }            }
1643          tmp1next = FALSE;          tmp1next = FALSE;
1644          }          }
# Line 1055  while (status != end) Line 1650  while (status != end)
1650          if (!tmp2empty)          if (!tmp2empty)
1651            {            {
1652            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1653            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1654            }            }
1655          tmp1next = TRUE;          tmp1next = TRUE;
1656          }          }
# Line 1070  if (save) Line 1665  if (save)
1665      if (!tmp1empty)      if (!tmp1empty)
1666        {        {
1667        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1668        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1669        }        }
1670      if (!tmp2empty)      if (!tmp2empty)
1671        {        {
1672        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1673        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1674        }        }
1675      }      }
1676    else    else
# Line 1083  if (save) Line 1678  if (save)
1678      if (!tmp2empty)      if (!tmp2empty)
1679        {        {
1680        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1681        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1682        }        }
1683      if (!tmp1empty)      if (!tmp1empty)
1684        {        {
1685        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1686        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1687        }        }
1688      }      }
1689    }    }
1690  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1691  }  }
1692    
1693  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1694    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1695    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1696    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1697    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1698    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1699    
1700    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1701  {  {
1702  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1703  }  }
# Line 1105  static SLJIT_INLINE void set_jumps(jump_ Line 1707  static SLJIT_INLINE void set_jumps(jump_
1707  while (list)  while (list)
1708    {    {
1709    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1710    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1711    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1712    list = list->next;    list = list->next;
1713    }    }
# Line 1132  if (list_item) Line 1734  if (list_item)
1734    list_item->type = type;    list_item->type = type;
1735    list_item->data = data;    list_item->data = data;
1736    list_item->start = start;    list_item->start = start;
1737    list_item->leave = LABEL();    list_item->quit = LABEL();
1738    list_item->next = common->stubs;    list_item->next = common->stubs;
1739    common->stubs = list_item;    common->stubs = list_item;
1740    }    }
# Line 1152  while (list_item) Line 1754  while (list_item)
1754      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1755      break;      break;
1756      }      }
1757    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1758    list_item = list_item->next;    list_item = list_item->next;
1759    }    }
1760  common->stubs = NULL;  common->stubs = NULL;
# Line 1171  static SLJIT_INLINE void allocate_stack( Line 1773  static SLJIT_INLINE void allocate_stack(
1773  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
1774  DEFINE_COMPILER;  DEFINE_COMPILER;
1775    
1776  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1777  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
1778  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1779  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1185  add_stub(common, stack_alloc, 0, CMP(SLJ Line 1787  add_stub(common, stack_alloc, 0, CMP(SLJ
1787  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1788  {  {
1789  DEFINE_COMPILER;  DEFINE_COMPILER;
1790  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1791  }  }
1792    
1793  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1195  struct sljit_label *loop; Line 1797  struct sljit_label *loop;
1797  int i;  int i;
1798  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1799  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1800  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_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));
1801  if (length < 8)  if (length < 8)
1802    {    {
1803    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1203  if (length < 8) Line 1805  if (length < 8)
1805    }    }
1806  else  else
1807    {    {
1808    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_sw));
1809    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1810    loop = LABEL();    loop = LABEL();
1811    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_sw), SLJIT_TEMPORARY_REG1, 0);
1812    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1813    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1814    }    }
# Line 1219  struct sljit_label *loop; Line 1821  struct sljit_label *loop;
1821  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1822    
1823  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1824  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));
1825  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1826    
1827  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1828    if (common->mark_ptr != 0)
1829      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1830  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1831    if (common->mark_ptr != 0)
1832      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1833  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1834  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1835  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1836  /* Unlikely, but possible */  /* Unlikely, but possible */
1837  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1838  loop = LABEL();  loop = LABEL();
1839  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);
1840  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_sw));
1841  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1842  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1843    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1844    #endif
1845    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1846  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1847  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1848  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1241  JUMPHERE(earlyexit); Line 1850  JUMPHERE(earlyexit);
1850  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1851  if (topbracket > 1)  if (topbracket > 1)
1852    {    {
1853    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_sw));
1854    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1855    
1856    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1857    loop = LABEL();    loop = LABEL();
1858    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
1859    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1860    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);
1861    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1862    }    }
1863  else  else
1864    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1865  }  }
1866    
1867  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1868    {
1869    DEFINE_COMPILER;
1870    
1871    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1872    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1873    
1874    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1875    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1876    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1877    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1878    
1879    /* Store match begin and end. */
1880    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1881    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1882    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1883    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1884    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1885    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1886    #endif
1887    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1888    
1889    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1890    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1891    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1892    #endif
1893    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1894    
1895    JUMPTO(SLJIT_JUMP, quit);
1896    }
1897    
1898    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1899    {
1900    /* May destroy TMP1. */
1901    DEFINE_COMPILER;
1902    struct sljit_jump *jump;
1903    
1904    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1905      {
1906      /* The value of -1 must be kept for start_used_ptr! */
1907      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1908      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1909      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1910      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1911      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1912      JUMPHERE(jump);
1913      }
1914    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1915      {
1916      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1917      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1918      JUMPHERE(jump);
1919      }
1920    }
1921    
1922    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1923  {  {
1924  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1925  unsigned int c;  unsigned int c;
1926    
1927  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1928  if (common->utf8)  if (common->utf)
1929    {    {
1930    GETCHAR(c, cc);    GETCHAR(c, cc);
1931    if (c > 127)    if (c > 127)
# Line 1272  if (common->utf8) Line 1936  if (common->utf8)
1936      return FALSE;      return FALSE;
1937  #endif  #endif
1938      }      }
1939    #ifndef COMPILE_PCRE8
1940      return common->fcc[c] != c;
1941    #endif
1942    }    }
1943  else  else
1944  #endif  #endif
1945    c = *cc;    c = *cc;
1946  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1947  }  }
1948    
1949  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)
1950  {  {
1951  /* Returns with the othercase. */  /* Returns with the othercase. */
1952  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1953  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1954    {    {
1955  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1956    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1292  if (common->utf8 && c > 127) Line 1959  if (common->utf8 && c > 127)
1959  #endif  #endif
1960    }    }
1961  #endif  #endif
1962  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1963  }  }
1964    
1965  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)
1966  {  {
1967  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1968  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1969  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1970  int n;  int n;
1971  #endif  #endif
1972    
1973  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1974  if (common->utf8)  if (common->utf)
1975    {    {
1976    GETCHAR(c, cc);    GETCHAR(c, cc);
1977    if (c <= 127)    if (c <= 127)
# Line 1321  if (common->utf8) Line 1988  if (common->utf8)
1988  else  else
1989    {    {
1990    c = *cc;    c = *cc;
1991    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1992    }    }
1993  #else  #else
1994  c = *cc;  c = *cc;
1995  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1996  #endif  #endif
1997    
1998  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1336  if (c <= 127 && bit == 0x20) Line 2003  if (c <= 127 && bit == 0x20)
2003    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2004    
2005  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2006  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2007    return 0;    return 0;
2008    
2009  #ifdef SUPPORT_UTF8  #if defined COMPILE_PCRE8
2010  if (common->utf8 && c > 127)  
2011    #ifdef SUPPORT_UTF
2012    if (common->utf && c > 127)
2013    {    {
2014    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
2015    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
2016      {      {
2017      n--;      n--;
# Line 1350  if (common->utf8 && c > 127) Line 2019  if (common->utf8 && c > 127)
2019      }      }
2020    return (n << 8) | bit;    return (n << 8) | bit;
2021    }    }
2022  #endif  #endif /* SUPPORT_UTF */
2023  return (0 << 8) | bit;  return (0 << 8) | bit;
2024    
2025    #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2026    
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    
2038    #endif /* COMPILE_PCRE[8|16|32] */
2039  }  }
2040    
2041  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
2042  {  {
2043    /* Checks whether a partial matching is occured. Does not modify registers. */
2044  DEFINE_COMPILER;  DEFINE_COMPILER;
2045  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump = NULL;
2046    
2047    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2048    
2049    if (common->mode == JIT_COMPILE)
2050      return;
2051    
2052    if (!force)
2053      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2054    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2055      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2056    
2057    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2058      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2059    else
2060      {
2061      if (common->partialmatchlabel != NULL)
2062        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2063      else
2064        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2065      }
2066    
2067    if (jump != NULL)
2068      JUMPHERE(jump);
2069    }
2070    
2071    static struct sljit_jump *check_str_end(compiler_common *common)
2072    {
2073    /* Does not affect registers. Usually used in a tight spot. */
2074    DEFINE_COMPILER;
2075    struct sljit_jump *jump;
2076    struct sljit_jump *nohit;
2077    struct sljit_jump *return_value;
2078    
2079    if (common->mode == JIT_COMPILE)
2080      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2081    
2082    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2083    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2084      {
2085      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2086      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2087      JUMPHERE(nohit);
2088      return_value = JUMP(SLJIT_JUMP);
2089      }
2090    else
2091      {
2092      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2093      if (common->partialmatchlabel != NULL)
2094        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2095      else
2096        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2097      }
2098    JUMPHERE(jump);
2099    return return_value;
2100    }
2101    
2102    static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2103    {
2104    DEFINE_COMPILER;
2105    struct sljit_jump *jump;
2106    
2107    if (common->mode == JIT_COMPILE)
2108      {
2109      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2110      return;
2111      }
2112    
2113    /* Partial matching mode. */
2114    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2115    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2116    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2117      {
2118      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2119      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2120      }
2121    else
2122      {
2123      if (common->partialmatchlabel != NULL)
2124        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2125      else
2126        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2127      }
2128    JUMPHERE(jump);
2129  }  }
2130    
2131  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1365  static void read_char(compiler_common *c Line 2133  static void read_char(compiler_common *c
2133  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2134  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2135  DEFINE_COMPILER;  DEFINE_COMPILER;
2136  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2137  struct sljit_jump *jump;  struct sljit_jump *jump;
2138  #endif  #endif
2139    
2140  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2141  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2142  if (common->utf8)  if (common->utf)
2143    {    {
2144    /* Should not found a value between 128 and 192 here. */  #if defined COMPILE_PCRE8
2145    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2146    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #elif defined COMPILE_PCRE16
2147      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2148    #endif /* COMPILE_PCRE[8|16] */
2149      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2150    JUMPHERE(jump);    JUMPHERE(jump);
2151    }    }
2152  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2153  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2154  }  }
2155    
2156  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1387  static void peek_char(compiler_common *c Line 2158  static void peek_char(compiler_common *c
2158  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2159  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2160  DEFINE_COMPILER;  DEFINE_COMPILER;
2161  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2162  struct sljit_jump *jump;  struct sljit_jump *jump;
2163  #endif  #endif
2164    
2165  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2166  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2167  if (common->utf8)  if (common->utf)
2168    {    {
2169    /* Should not found a value between 128 and 192 here. */  #if defined COMPILE_PCRE8
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2171    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #elif defined COMPILE_PCRE16
2172      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2173    #endif /* COMPILE_PCRE[8|16] */
2174      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2175    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2176    JUMPHERE(jump);    JUMPHERE(jump);
2177    }    }
2178  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2179  }  }
2180    
2181  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2182  {  {
2183  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */  /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */
2184  DEFINE_COMPILER;  DEFINE_COMPILER;
2185  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2186  struct sljit_jump *jump;  struct sljit_jump *jump;
2187  #endif  #endif
2188    
2189  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2190  if (common->utf8)  if (common->utf)
2191    {    {
2192    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2193    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2194    #if defined COMPILE_PCRE8
2195    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2196    it is a clever early read in most cases. */    it is needed in most cases. */
2197    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2198    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2199    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  
2200    JUMPHERE(jump);    JUMPHERE(jump);
2201    #elif defined COMPILE_PCRE16
2202      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2203      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2204      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2205      JUMPHERE(jump);
2206      /* Skip low surrogate if necessary. */
2207      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2208      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2209      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2210      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2211      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2212    #elif defined COMPILE_PCRE32
2213      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2214      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2215      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2216      JUMPHERE(jump);
2217    #endif /* COMPILE_PCRE[8|16|32] */
2218    return;    return;
2219    }    }
2220    #endif /* SUPPORT_UTF */
2221    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2222    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2223    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2224    /* The ctypes array contains only 256 values. */
2225    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2226    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2227    #endif
2228    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2229    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2230    JUMPHERE(jump);
2231  #endif  #endif
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  
2232  }  }
2233    
2234  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2235  {  {
2236  /* 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. */
2237  DEFINE_COMPILER;  DEFINE_COMPILER;
2238  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2239    #if defined COMPILE_PCRE8
2240  struct sljit_label *label;  struct sljit_label *label;
2241    
2242  if (common->utf8)  if (common->utf)
2243    {    {
2244    label = LABEL();    label = LABEL();
2245    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2246    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));
2247    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2248    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2249    return;    return;
2250    }    }
2251  #endif  #elif defined COMPILE_PCRE16
2252  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2253      {
2254      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2255      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2256      /* Skip low surrogate if necessary. */
2257      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2258      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2259      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2260      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2261      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2262      return;
2263      }
2264    #endif /* COMPILE_PCRE[8|16] */
2265    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2266    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2267  }  }
2268    
2269  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **backtracks, BOOL jumpiftrue)
2270  {  {
2271  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */  /* Character comes in TMP1. Checks if it is a newline. TMP2 may be destroyed. */
2272  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1460  DEFINE_COMPILER; Line 2274  DEFINE_COMPILER;
2274  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2275    {    {
2276    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2277    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2278    }    }
2279  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2280    {    {
2281    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
2282    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2283    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2284    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2285    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2286    }    }
2287  else  else
2288    {    {
2289    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2290    add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, backtracks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
2291    }    }
2292  }  }
2293    
2294  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2295  static void do_utf8readchar(compiler_common *common)  
2296    #if defined COMPILE_PCRE8
2297    static void do_utfreadchar(compiler_common *common)
2298  {  {
2299  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2300  of the character (>= 192). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
2301  DEFINE_COMPILER;  DEFINE_COMPILER;
2302  struct sljit_jump *jump;  struct sljit_jump *jump;
2303    
2304  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2305  /* Searching for the first zero. */  /* Searching for the first zero. */
2306  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);
2307  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2308  /* 2 byte sequence */  /* Two byte sequence. */
2309  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2310  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));
2311  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2312  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2313  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2314  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2315  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2316  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2317  JUMPHERE(jump);  JUMPHERE(jump);
2318    
2319  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);
2320  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2321  /* 3 byte sequence */  /* Three byte sequence. */
2322  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2323  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2324  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2325  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2326  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2327  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2328  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2329  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));
2330  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2331  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2332  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2333  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2334  JUMPHERE(jump);  JUMPHERE(jump);
2335    
2336  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2337  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);  
2338  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2339  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2340  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2341  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2342  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2343  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
2344  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2345  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2346  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2347  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2348  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2349  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2350  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2351  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
2352  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2353  }  }
2354    
2355  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2356  {  {
2357  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2358  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2359  DEFINE_COMPILER;  DEFINE_COMPILER;
2360  struct sljit_jump *jump;  struct sljit_jump *jump;
2361  struct sljit_jump *compare;  struct sljit_jump *compare;
2362    
2363  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2364    
2365  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);
2366  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2367  /* 2 byte sequence */  /* Two byte sequence. */
2368  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2369  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));
2370  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2371  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2372  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1590  sljit_emit_fast_return(compiler, RETURN_ Line 2381  sljit_emit_fast_return(compiler, RETURN_
2381  JUMPHERE(jump);  JUMPHERE(jump);
2382    
2383  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2384  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
2385  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2386  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2387  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2388  }  }
2389    
2390  #endif  #elif defined COMPILE_PCRE16
2391    
2392    static void do_utfreadchar(compiler_common *common)
2393    {
2394    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2395    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2396    DEFINE_COMPILER;
2397    struct sljit_jump *jump;
2398    
2399    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2400    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2401    /* Do nothing, only return. */
2402    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2403    
2404    JUMPHERE(jump);
2405    /* Combine two 16 bit characters. */
2406    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2407    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2408    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2409    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2410    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2411    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2412    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2413    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2414    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2415    }
2416    
2417    #endif /* COMPILE_PCRE[8|16] */
2418    
2419    #endif /* SUPPORT_UTF */
2420    
2421  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2422    
# Line 1613  DEFINE_COMPILER; Line 2432  DEFINE_COMPILER;
2432    
2433  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2434    
2435  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2436  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2437  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_ucd_stage1);  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
2438  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2439  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2440  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2441  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2442  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2443  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
2444  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2445  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2446  }  }
2447  #endif  #endif
2448    
2449    static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)
2450    {
2451    DEFINE_COMPILER;
2452    struct sljit_label *mainloop;
2453    struct sljit_label *newlinelabel = NULL;
2454    struct sljit_jump *start;
2455    struct sljit_jump *end = NULL;
2456    struct sljit_jump *nl = NULL;
2457    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2458    struct sljit_jump *singlechar;
2459    #endif
2460    jump_list *newline = NULL;
2461    BOOL newlinecheck = FALSE;
2462    BOOL readuchar = FALSE;
2463    
2464    if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2465        common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
2466      newlinecheck = TRUE;
2467    
2468    if (firstline)
2469      {
2470      /* Search for the end of the first line. */
2471      SLJIT_ASSERT(common->first_line_end != 0);
2472      OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2473    
2474      if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2475        {
2476        mainloop = LABEL();
2477        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2478        end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2479        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2480        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2481        CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2482        CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2483        JUMPHERE(end);
2484        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2485        }
2486      else
2487        {
2488        end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2489        mainloop = LABEL();
2490        /* Continual stores does not cause data dependency. */
2491        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2492        read_char(common);
2493        check_newlinechar(common, common->nltype, &newline, TRUE);
2494        CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2495        JUMPHERE(end);
2496        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2497        set_jumps(newline, LABEL());
2498        }
2499    
2500      OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
2501      }
2502    
2503    start = JUMP(SLJIT_JUMP);
2504    
2505    if (newlinecheck)
2506      {
2507      newlinelabel = LABEL();
2508      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2509      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2510      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2511      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2512      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2513    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2514      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2515    #endif
2516      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2517      nl = JUMP(SLJIT_JUMP);
2518      }
2519    
2520    mainloop = LABEL();
2521    
2522    /* Increasing the STR_PTR here requires one less jump in the most common case. */
2523    #ifdef SUPPORT_UTF
2524    if (common->utf) readuchar = TRUE;
2525    #endif
2526    if (newlinecheck) readuchar = TRUE;
2527    
2528    if (readuchar)
2529      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2530    
2531    if (newlinecheck)
2532      CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2533    
2534    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2535    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2536    #if defined COMPILE_PCRE8
2537    if (common->utf)
2538      {
2539      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2540      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2541      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2542      JUMPHERE(singlechar);
2543      }
2544    #elif defined COMPILE_PCRE16
2545    if (common->utf)
2546      {
2547      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2548      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2549      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2550      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2551      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2552      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2553      JUMPHERE(singlechar);
2554      }
2555    #endif /* COMPILE_PCRE[8|16] */
2556    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2557    JUMPHERE(start);
2558    
2559    if (newlinecheck)
2560      {
2561      JUMPHERE(end);
2562      JUMPHERE(nl);
2563      }
2564    
2565    return mainloop;
2566    }
2567    
2568    #define MAX_N_CHARS 3
2569    
2570    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2571    {
2572    DEFINE_COMPILER;
2573    struct sljit_label *start;
2574    struct sljit_jump *quit;
2575    pcre_uint32 chars[MAX_N_CHARS * 2];
2576    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2577    int location = 0;
2578    pcre_int32 len, c, bit, caseless;
2579    int must_stop;
2580    
2581    /* We do not support alternatives now. */
2582    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2583      return FALSE;
2584    
2585    while (TRUE)
2586      {
2587      caseless = 0;
2588      must_stop = 1;
2589      switch(*cc)
2590        {
2591        case OP_CHAR:
2592        must_stop = 0;
2593        cc++;
2594        break;
2595    
2596        case OP_CHARI:
2597        caseless = 1;
2598        must_stop = 0;
2599        cc++;
2600        break;
2601    
2602        case OP_SOD:
2603        case OP_SOM:
2604        case OP_SET_SOM:
2605        case OP_NOT_WORD_BOUNDARY:
2606        case OP_WORD_BOUNDARY:
2607        case OP_EODN:
2608        case OP_EOD:
2609        case OP_CIRC:
2610        case OP_CIRCM:
2611        case OP_DOLL:
2612        case OP_DOLLM:
2613        /* Zero width assertions. */
2614        cc++;
2615        continue;
2616    
2617        case OP_PLUS:
2618        case OP_MINPLUS:
2619        case OP_POSPLUS:
2620        cc++;
2621        break;
2622    
2623        case OP_EXACT:
2624        cc += 1 + IMM2_SIZE;
2625        break;
2626    
2627        case OP_PLUSI:
2628        case OP_MINPLUSI:
2629        case OP_POSPLUSI:
2630        caseless = 1;
2631        cc++;
2632        break;
2633    
2634        case OP_EXACTI:
2635        caseless = 1;
2636        cc += 1 + IMM2_SIZE;
2637        break;
2638    
2639  static SLJIT_INLINE struct sljit_label *mainloop_entry(compiler_common *common, BOOL hascrorlf, BOOL firstline)      default:
2640  {      must_stop = 2;
2641  DEFINE_COMPILER;      break;
2642  struct sljit_label *mainloop;      }
 struct sljit_label *newlinelabel = NULL;  
 struct sljit_jump *start;  
 struct sljit_jump *end = NULL;  
 struct sljit_jump *nl = NULL;  
 jump_list *newline = NULL;  
 BOOL newlinecheck = FALSE;  
 BOOL readbyte = FALSE;  
2643    
2644  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||    if (must_stop == 2)
2645      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))        break;
   newlinecheck = TRUE;  
2646    
2647  if (firstline)    len = 1;
2648    {  #ifdef SUPPORT_UTF
2649    /* Search for the end of the first line. */    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2650    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);  #endif
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);  
2651    
2652    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (caseless && char_has_othercase(common, cc))
2653      {      {
2654      mainloop = LABEL();      caseless = char_get_othercase_bit(common, cc);
2655      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      if (caseless == 0)
2656      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);        return FALSE;
2657      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);  #ifdef COMPILE_PCRE8
2658      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2659      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);  #else
2660      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      if ((caseless & 0x100) != 0)
2661      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);        caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2662        else
2663          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2664    #endif
2665      }      }
2666    else    else
2667        caseless = 0;
2668    
2669      while (len > 0 && location < MAX_N_CHARS * 2)
2670      {      {
2671      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      c = *cc;
2672      mainloop = LABEL();      bit = 0;
2673      /* Continual stores does not cause data dependency. */      if (len == (caseless & 0xff))
2674      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);        {
2675      read_char(common);        bit = caseless >> 8;
2676      check_newlinechar(common, common->nltype, &newline, TRUE);        c |= bit;
2677      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);        }
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);  
     set_jumps(newline, LABEL());  
     }  
2678    
2679    JUMPHERE(end);      chars[location] = c;
2680    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);      chars[location + 1] = bit;
   }  
2681    
2682  start = JUMP(SLJIT_JUMP);      len--;
2683        location += 2;
2684        cc++;
2685        }
2686    
2687  if (newlinecheck)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2688    {      break;
   newlinelabel = LABEL();  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
   end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   nl = JUMP(SLJIT_JUMP);  
2689    }    }
2690    
2691  mainloop = LABEL();  /* At least two characters are required. */
2692    if (location < 2 * 2)
2693  /* Increasing the STR_PTR here requires one less jump in the most common case. */      return FALSE;
 #ifdef SUPPORT_UTF8  
 if (common->utf8) readbyte = TRUE;  
 #endif  
 if (newlinecheck) readbyte = TRUE;  
   
 if (readbyte)  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
   
 if (newlinecheck)  
   CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);  
2694    
2695  #ifdef SUPPORT_UTF8  if (firstline)
 if (common->utf8)  
2696    {    {
2697    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    SLJIT_ASSERT(common->first_line_end != 0);
2698    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2699      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, (location >> 1) - 1);
2700    }    }
2701  else  else
2702    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #endif  
 JUMPHERE(start);  
2703    
2704  if (newlinecheck)  start = LABEL();
2705    {  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2706    JUMPHERE(end);  
2707    JUMPHERE(nl);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2708    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2709    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2710    if (chars[1] != 0)
2711      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2712    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2713    if (location > 2 * 2)
2714      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2715    if (chars[3] != 0)
2716      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2717    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2718    if (location > 2 * 2)
2719      {
2720      if (chars[5] != 0)
2721        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2722      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2723    }    }
2724    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2725    
2726  return mainloop;  JUMPHERE(quit);
2727    
2728    if (firstline)
2729      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2730    else
2731      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, (location >> 1) - 1);
2732    return TRUE;
2733  }  }
2734    
2735  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  #undef MAX_N_CHARS
2736    
2737    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2738  {  {
2739  DEFINE_COMPILER;  DEFINE_COMPILER;
2740  struct sljit_label *start;  struct sljit_label *start;
2741  struct sljit_jump *leave;  struct sljit_jump *quit;
2742  struct sljit_jump *found;  struct sljit_jump *found;
2743  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2744    
2745  if (firstline)  if (firstline)
2746    {    {
2747    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2748    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2749      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2750    }    }
2751    
2752  start = LABEL();  start = LABEL();
2753  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2754  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2755    
2756  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2757    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2758      {
2759      oc = TABLE_GET(first_char, common->fcc, first_char);
2760    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2761      if (first_char > 127 && common->utf)
2762        oc = UCD_OTHERCASE(first_char);
2763    #endif
2764      }
2765    if (first_char == oc)
2766      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2767  else  else
2768    {    {
2769    firstbyte &= 0xff;    bit = first_char ^ oc;
2770    oc = common->fcc[firstbyte];    if (is_powerof2(bit))
   bit = firstbyte ^ oc;  
   if (ispowerof2(bit))  
2771      {      {
2772      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2773      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2774      }      }
2775    else    else
2776      {      {
2777      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);
2778      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2779      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc);
2780      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2781      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
2782      }      }
2783    }    }
2784    
2785  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 if (common->utf8)  
   {  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #endif  
2786  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2787  JUMPHERE(found);  JUMPHERE(found);
2788  JUMPHERE(leave);  JUMPHERE(quit);
2789    
2790  if (firstline)  if (firstline)
2791    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2792  }  }
2793    
2794  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 1792  DEFINE_COMPILER; Line 2797  DEFINE_COMPILER;
2797  struct sljit_label *loop;  struct sljit_label *loop;
2798  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2799  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2800  struct sljit_jump *leave;  struct sljit_jump *quit;
2801  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2802  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2803  jump_list *newline = NULL;  jump_list *newline = NULL;
2804    
2805  if (firstline)  if (firstline)
2806    {    {
2807    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2808    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2809      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2810    }    }
2811    
2812  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1811  if (common->nltype == NLTYPE_FIXED && co Line 2817  if (common->nltype == NLTYPE_FIXED && co
2817    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));
2818    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2819    
2820    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2821    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, TMP1, 0);
2822    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
2823    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2824      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2825    #endif
2826    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2827    
2828    loop = LABEL();    loop = LABEL();
2829    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2830    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2831    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2832    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2833    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2834    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2835    
2836    JUMPHERE(leave);    JUMPHERE(quit);
2837    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2838    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2839    
# Line 1848  set_jumps(newline, loop); Line 2857  set_jumps(newline, loop);
2857    
2858  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2859    {    {
2860    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2861    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2862    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2863    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2864    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_NL);
2865    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2866    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2867      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2868    #endif
2869    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2870    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2871    JUMPHERE(leave);    JUMPHERE(quit);
2872    }    }
2873  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2874  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2875    
2876  if (firstline)  if (firstline)
2877    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2878  }  }
2879    
2880  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2881  {  {
2882  DEFINE_COMPILER;  DEFINE_COMPILER;
2883  struct sljit_label *start;  struct sljit_label *start;
2884  struct sljit_jump *leave;  struct sljit_jump *quit;
2885  struct sljit_jump *found;  struct sljit_jump *found;
2886    #ifndef COMPILE_PCRE8
2887    struct sljit_jump *jump;
2888    #endif
2889    
2890  if (firstline)  if (firstline)
2891    {    {
2892    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2893    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2894      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2895    }    }
2896    
2897  start = LABEL();  start = LABEL();
2898  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2899  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2900  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2901  if (common->utf8)  if (common->utf)
2902    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2903    #endif
2904    #ifndef COMPILE_PCRE8
2905    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2906    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2907    JUMPHERE(jump);
2908  #endif  #endif
2909  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2910  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1892  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2913  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2913  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);
2914  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2915    
2916  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2917  if (common->utf8)  if (common->utf)
2918    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
2919  #endif  #endif
2920    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2921    #ifdef SUPPORT_UTF
2922    #if defined COMPILE_PCRE8
2923    if (common->utf)
2924      {
2925      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2926      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2927      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2928      }
2929    #elif defined COMPILE_PCRE16
2930    if (common->utf)
2931      {
2932      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2933      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2934      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2935      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2936      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2937      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2938      }
2939    #endif /* COMPILE_PCRE[8|16] */
2940    #endif /* SUPPORT_UTF */
2941  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2942  JUMPHERE(found);  JUMPHERE(found);
2943  JUMPHERE(leave);  JUMPHERE(quit);
2944    
2945  if (firstline)  if (firstline)
2946    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2947  }  }
2948    
2949  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_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)
2950  {  {
2951  DEFINE_COMPILER;  DEFINE_COMPILER;
2952  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1917  struct sljit_jump *alreadyfound; Line 2955  struct sljit_jump *alreadyfound;
2955  struct sljit_jump *found;  struct sljit_jump *found;
2956  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2957  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2958  pcre_uint16 oc, bit;  pcre_uint32 oc, bit;
2959    
2960  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2961    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2962  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);
2963  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2964  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2965    
2966  if (has_firstbyte)  if (has_firstchar)
2967    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2968  else  else
2969    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2970    
2971  loop = LABEL();  loop = LABEL();
2972  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2973    
2974  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2975  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2976    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2977      {
2978      oc = TABLE_GET(req_char, common->fcc, req_char);
2979    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2980      if (req_char > 127 && common->utf)
2981        oc = UCD_OTHERCASE(req_char);
2982    #endif
2983      }
2984    if (req_char == oc)
2985      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2986  else  else
2987    {    {
2988    reqbyte &= 0xff;    bit = req_char ^ oc;
2989    oc = common->fcc[reqbyte];    if (is_powerof2(bit))
   bit = reqbyte ^ oc;  
   if (ispowerof2(bit))  
2990      {      {
2991      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2992      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2993      }      }
2994    else    else
2995      {      {
2996      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2997      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2998      }      }
2999    }    }
3000  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3001  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
3002    
3003  JUMPHERE(found);  JUMPHERE(found);
3004  if (foundoc)  if (foundoc)
3005    JUMPHERE(foundoc);    JUMPHERE(foundoc);
3006  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);
3007  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
3008  JUMPHERE(toolong);  JUMPHERE(toolong);
3009  return notfound;  return notfound;
# Line 1966  return notfound; Line 3012  return notfound;
3012  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
3013  {  {
3014  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
3015  struct sljit_jump *jump;  struct sljit_jump *jump;
3016  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3017    
3018  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3019  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3020    GET_LOCAL_BASE(TMP3, 0, 0);
3021    
3022  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
3023  mainloop = LABEL();  mainloop = LABEL();
3024  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3025  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
3026  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3027  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3028  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3029  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
3030  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3031    
3032  JUMPHERE(jump);  JUMPHERE(jump);
3033  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
3034  /* End of dropping frames. */  /* End of dropping frames. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
 CMPTO(SLJIT_C_GREATER_EQUAL, TMP1, 0, STACK_TOP, 0, mainloop);  
 JUMPHERE(earlyexit);  
3035  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3036    
3037  JUMPHERE(jump);  JUMPHERE(jump);
3038  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
3039  /* Set string begin. */  /* Set string begin. */
3040  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3041  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3042  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
3043  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3044    
3045  JUMPHERE(jump);  JUMPHERE(jump);
3046    if (common->mark_ptr != 0)
3047      {
3048      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3049      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3050      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3051      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3052      JUMPTO(SLJIT_JUMP, mainloop);
3053    
3054      JUMPHERE(jump);
3055      }
3056    
3057  /* Unknown command. */  /* Unknown command. */
3058  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3059  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3060  }  }
3061    
3062  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3063  {  {
3064  DEFINE_COMPILER;  DEFINE_COMPILER;
3065  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3066  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3067  struct sljit_jump *jump;  struct sljit_jump *jump;
3068  #endif  #endif
3069    
3070  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3071    
3072  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);
3073  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3074  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3075  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));
3076  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3077  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3078  skip_char_back(common);  skip_char_back(common);
3079    check_start_used_ptr(common);
3080  read_char(common);  read_char(common);
3081    
3082  /* Testing char type. */  /* Testing char type. */
3083  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3084  if (common->useucp)  if (common->use_ucp)
3085    {    {
3086    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3087    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3088    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3089    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3090    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3091    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3092    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3093    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3094    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3095    JUMPHERE(jump);    JUMPHERE(jump);
3096    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3097    }    }
3098  else  else
3099  #endif  #endif
3100    {    {
3101  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3102      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3103    #elif defined SUPPORT_UTF
3104    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3105    jump = NULL;    jump = NULL;
3106    if (common->utf8)    if (common->utf)
3107      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3108  #endif  #endif /* COMPILE_PCRE8 */
3109    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3110    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3111    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3112    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3113  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3114      JUMPHERE(jump);
3115    #elif defined SUPPORT_UTF
3116    if (jump != NULL)    if (jump != NULL)
3117      JUMPHERE(jump);      JUMPHERE(jump);
3118  #endif  #endif /* COMPILE_PCRE8 */
3119    }    }
3120  JUMPHERE(beginend);  JUMPHERE(skipread);
3121    
3122  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3123  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3124  peek_char(common);  peek_char(common);
3125    
3126  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3127  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3128  if (common->useucp)  if (common->use_ucp)
3129    {    {
3130    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3131    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3132    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3133    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3134    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3135    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3136    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3137    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3138    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3139    JUMPHERE(jump);    JUMPHERE(jump);
3140    }    }
3141  else  else
3142  #endif  #endif
3143    {    {
3144  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3145      /* TMP2 may be destroyed by peek_char. */
3146      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3147      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3148    #elif defined SUPPORT_UTF
3149    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3150    jump = NULL;    jump = NULL;
3151    if (common->utf8)    if (common->utf)
3152      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3153  #endif  #endif
3154    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3155    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3156    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3157  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3158      JUMPHERE(jump);
3159    #elif defined SUPPORT_UTF
3160    if (jump != NULL)    if (jump != NULL)
3161      JUMPHERE(jump);      JUMPHERE(jump);
3162  #endif  #endif /* COMPILE_PCRE8 */
3163    }    }
3164  JUMPHERE(beginend);  JUMPHERE(skipread);
3165    
3166  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3167  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3168  }  }
3169    
3170    /*
3171      range format:
3172    
3173      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3174      ranges[1] = first bit (0 or 1)
3175      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3176    */
3177    
3178    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3179    {
3180    DEFINE_COMPILER;
3181    struct sljit_jump *jump;
3182    
3183    if (ranges[0] < 0)
3184      return FALSE;
3185    
3186    switch(ranges[0])
3187      {
3188      case 1:
3189      if (readch)
3190        read_char(common);
3191      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3192      return TRUE;
3193    
3194      case 2:
3195      if (readch)
3196        read_char(common);
3197      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3198      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3199      return TRUE;
3200    
3201      case 4:
3202      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3203        {
3204        if (readch)
3205          read_char(common);
3206        if (ranges[1] != 0)
3207          {
3208          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3209          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3210          }
3211        else
3212          {
3213          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3214          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3215          JUMPHERE(jump);
3216          }
3217        return TRUE;
3218        }
3219      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3220        {
3221        if (readch)
3222          read_char(common);
3223        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3224        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3225        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3226        return TRUE;
3227        }
3228      return FALSE;
3229    
3230      default:
3231      return FALSE;
3232      }
3233    }
3234    
3235    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3236    {
3237    int i, bit, length;
3238    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3239    
3240    bit = ctypes[0] & flag;
3241    ranges[0] = -1;
3242    ranges[1] = bit != 0 ? 1 : 0;
3243    length = 0;
3244    
3245    for (i = 1; i < 256; i++)
3246      if ((ctypes[i] & flag) != bit)
3247        {
3248        if (length >= MAX_RANGE_SIZE)
3249          return;
3250        ranges[2 + length] = i;
3251        length++;
3252        bit ^= flag;
3253        }
3254    
3255    if (bit != 0)
3256      {
3257      if (length >= MAX_RANGE_SIZE)
3258        return;
3259      ranges[2 + length] = 256;
3260      length++;
3261      }
3262    ranges[0] = length;
3263    }
3264    
3265    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3266    {
3267    int ranges[2 + MAX_RANGE_SIZE];
3268    pcre_uint8 bit, cbit, all;
3269    int i, byte, length = 0;
3270    
3271    bit = bits[0] & 0x1;
3272    ranges[1] = bit;
3273    /* Can be 0 or 255. */
3274    all = -bit;
3275    
3276    for (i = 0; i < 256; )
3277      {
3278      byte = i >> 3;
3279      if ((i & 0x7) == 0 && bits[byte] == all)
3280        i += 8;
3281      else
3282        {
3283        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3284        if (cbit != bit)
3285          {
3286          if (length >= MAX_RANGE_SIZE)
3287            return FALSE;
3288          ranges[2 + length] = i;
3289          length++;
3290          bit = cbit;
3291          all = -cbit;
3292          }
3293        i++;
3294        }
3295      }
3296    
3297    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3298      {
3299      if (length >= MAX_RANGE_SIZE)
3300        return FALSE;
3301      ranges[2 + length] = 256;
3302      length++;
3303      }
3304    ranges[0] = length;
3305    
3306    return check_ranges(common, ranges, backtracks, FALSE);
3307    }
3308    
3309  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3310  {  {
3311  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3312  DEFINE_COMPILER;  DEFINE_COMPILER;
3313    
3314  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3315    
3316  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3317  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3318  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3319  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3320  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3321  if (common->utf8)  #ifdef COMPILE_PCRE8
3322    if (common->utf)
3323    {    {
3324    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  #endif
3325      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3326    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3327    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3328    #ifdef COMPILE_PCRE8
3329    }    }
3330  #endif  #endif
3331  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3332    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3333  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3334  }  }
3335    
# Line 2132  static void check_hspace(compiler_common Line 3338  static void check_hspace(compiler_common
3338  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3339  DEFINE_COMPILER;  DEFINE_COMPILER;
3340    
3341  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3342    
3343  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3344  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3345  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3346  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3347  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3348  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3349  if (common->utf8)  #ifdef COMPILE_PCRE8
3350    if (common->utf)
3351    {    {
3352    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  #endif
3353      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3354    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
3355    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3356    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
3357    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3358    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3359    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
3360    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3361    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
3362    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3363    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
3364    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3365    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
3366    #ifdef COMPILE_PCRE8
3367    }    }
3368  #endif  #endif
3369  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3370    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3371    
3372  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3373  }  }
# Line 2167  static void check_vspace(compiler_common Line 3377  static void check_vspace(compiler_common
3377  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3378  DEFINE_COMPILER;  DEFINE_COMPILER;
3379    
3380  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3381    
3382  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3383  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3384  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3385  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3386  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3387  if (common->utf8)  #ifdef COMPILE_PCRE8
3388    if (common->utf)
3389    {    {
3390    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif
3391      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3392    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3393    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3394    #ifdef COMPILE_PCRE8
3395    }    }
3396  #endif  #endif
3397  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3398    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3399    
3400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3401  }  }
# Line 2195  DEFINE_COMPILER; Line 3409  DEFINE_COMPILER;
3409  struct sljit_jump *jump;  struct sljit_jump *jump;
3410  struct sljit_label *label;  struct sljit_label *label;
3411    
3412  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3413  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3414  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3415  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3416  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3417  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));
3418    
3419  label = LABEL();  label = LABEL();
3420  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3421  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3422  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3423  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));
3424  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3425    
3426  JUMPHERE(jump);  JUMPHERE(jump);
3427  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));
3428  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3429  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3430  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2224  DEFINE_COMPILER; Line 3438  DEFINE_COMPILER;
3438  struct sljit_jump *jump;  struct sljit_jump *jump;
3439  struct sljit_label *label;  struct sljit_label *label;
3440    
3441  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3442  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3443    
3444  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3445  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3446  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3447  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3448  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3449  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));
3450    
3451  label = LABEL();  label = LABEL();
3452  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3453  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3454    #ifndef COMPILE_PCRE8
3455    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3456    #endif
3457  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3458    #ifndef COMPILE_PCRE8
3459    JUMPHERE(jump);
3460    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3461    #endif
3462  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3463    #ifndef COMPILE_PCRE8
3464    JUMPHERE(jump);
3465    #endif
3466  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3467  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));
3468  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3469    
3470  JUMPHERE(jump);  JUMPHERE(jump);
3471  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));
3472  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3473  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3474  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2255  sljit_emit_fast_return(compiler, RETURN_ Line 3479  sljit_emit_fast_return(compiler, RETURN_
3479  #undef CHAR1  #undef CHAR1
3480  #undef CHAR2  #undef CHAR2
3481    
3482  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3483    
3484  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)
3485  {  {
3486  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3487  int c1, c2;  pcre_uint32 c1, c2;
3488  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3489  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3490    const ucd_record *ur;
3491    const pcre_uint32 *pp;
3492    
3493  while (src1 < end1)  while (src1 < end1)
3494    {    {
3495    if (src2 >= end2)    if (src2 >= end2)
3496      return 0;      return (pcre_uchar*)1;
3497    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3498    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3499    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    ur = GET_UCD(c2);
3500      if (c1 != c2 && c1 != c2 + ur->other_case)
3501        {
3502        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3503        for (;;)
3504          {
3505          if (c1 < *pp) return NULL;
3506          if (c1 == *pp++) break;
3507          }
3508        }
3509    }    }
3510  return src2;  return src2;
3511  }  }
3512    
3513  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3514    
3515  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,
3516      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3517  {  {
3518  DEFINE_COMPILER;  DEFINE_COMPILER;
3519  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3520  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3521  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3522  int utf8length;  int utflength;
3523  #endif  #endif
3524    
3525  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2294  if (caseless && char_has_othercase(commo Line 3527  if (caseless && char_has_othercase(commo
3527    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3528    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3529    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3530    othercasebyte = cc + (othercasebit >> 8);  #if defined COMPILE_PCRE8
3531      othercasechar = cc + (othercasebit >> 8);
3532    othercasebit &= 0xff;    othercasebit &= 0xff;
3533    #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3534      /* Note that this code only handles characters in the BMP. If there
3535      ever are characters outside the BMP whose othercase differs in only one
3536      bit from itself (there currently are none), this code will need to be
3537      revised for COMPILE_PCRE32. */
3538      othercasechar = cc + (othercasebit >> 9);
3539      if ((othercasebit & 0x100) != 0)
3540        othercasebit = (othercasebit & 0xff) << 8;
3541      else
3542        othercasebit &= 0xff;
3543    #endif /* COMPILE_PCRE[8|16|32] */
3544    }    }
3545    
3546  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3547    {    {
3548    #if defined COMPILE_PCRE8
3549  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3550    if (context->length >= 4)    if (context->length >= 4)
3551      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3552    else if (context->length >= 2)    else if (context->length >= 2)
3553      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3554    else    else
3555  #endif  #endif
3556      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3557    #elif defined COMPILE_PCRE16
3558    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3559      if (context->length >= 4)
3560        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3561      else
3562    #endif
3563        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3564    #elif defined COMPILE_PCRE32
3565      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3566    #endif /* COMPILE_PCRE[8|16|32] */
3567    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3568    }    }
3569    
3570  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3571  utf8length = 1;  utflength = 1;
3572  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3573    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3574    
3575  do  do
3576    {    {
3577  #endif  #endif
3578    
3579    context->length--;    context->length -= IN_UCHARS(1);
3580  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3581    
3582    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3583    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3584      {      {
3585      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3586      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3587      }      }
3588    else    else
3589      {      {
3590      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3591      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3592      }      }
3593    context->byteptr++;    context->ucharptr++;
3594    
3595    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #if defined COMPILE_PCRE8
3596      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3597    #elif defined COMPILE_PCRE16
3598      if (context->ucharptr >= 2 || context->length == 0)
3599    #elif defined COMPILE_PCRE32
3600      if (1 /* context->ucharptr >= 1 || context->length == 0 */)
3601    #endif
3602      {      {
3603    #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
3604      if (context->length >= 4)      if (context->length >= 4)
3605        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);
3606    #if defined COMPILE_PCRE8
3607      else if (context->length >= 2)      else if (context->length >= 2)
3608        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);
3609      else if (context->length >= 1)      else if (context->length >= 1)
3610        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);
3611    #elif defined COMPILE_PCRE16
3612        else if (context->length >= 2)
3613          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3614    #endif /* COMPILE_PCRE[8|16] */
3615    #elif defined COMPILE_PCRE32
3616        OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3617    #endif /* COMPILE_PCRE[8|16|32] */
3618      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3619    
3620      switch(context->byteptr)