/[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 741 by zherczeg, Mon Oct 31 09:31:46 2011 UTC revision 1247 by zherczeg, Mon Feb 11 21:37:46 2013 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  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 60  system files. */ Line 62  system files. */
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Defines for debugging purposes. */
 #define LOCAL_SPACE_SIZE 32768  
69    
70    /* 1 - Use unoptimized capturing brackets.
71       2 - Enable capture_last_ptr (includes option 1). */
72    /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* Allocate memory for the regex stack on the real machine stack.
75    Fast, but limited size. */
76    #define MACHINE_STACK_SIZE 32768
77    
78    /* Growth rate for stack allocated by the OS. Should be the multiply
79    of page size. */
80  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
81    
82  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 80  The code generator follows the recursive Line 91  The code generator follows the recursive
91  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
92  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
93  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
94  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
95    
96    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
97    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
98    
99  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
100  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.
101  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
102  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
103  branches on the hot path.  branches on the matching path.
104    
105   Greedy star operator (*) :   Greedy star operator (*) :
106     Hot path: match happens.     Matching path: match happens.
107     Fallback path: match failed.     Backtrack path: match failed.
108   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
109     Hot path: no need to perform a match.     Matching path: no need to perform a match.
110     Fallback path: match is required.     Backtrack path: match is required.
111    
112  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
113  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 106  we have the following regular expression Line 117  we have the following regular expression
117    
118  The generated code will be the following:  The generated code will be the following:
119    
120   A hot path   A matching path
121   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
122   B hot path   B matching path
123   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
124   D hot path   D matching path
125   return with successful match   return with successful match
126    
127   D fallback path   D backtrack path
128   ')' 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")
129   B fallback path   B backtrack path
130   C expected path   C expected path
131   jump to D hot path   jump to D matching path
132   C fallback path   C backtrack path
133   A fallback path   A backtrack path
134    
135   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
136   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
137   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
138   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
139   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
140   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
141  */  */
142    
143  /*  /*
144  Saved stack frames:  Saved stack frames:
145    
146  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
147  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
148  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
149  mechanism.  mechanism.
150    
151  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:
152  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
153    
154  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.
155  */  */
156    
157  typedef struct jit_arguments {  typedef struct jit_arguments {
158    /* Pointers first. */    /* Pointers first. */
159    struct sljit_stack *stack;    struct sljit_stack *stack;
160    PCRE_SPTR str;    const pcre_uchar *str;
161    PCRE_SPTR begin;    const pcre_uchar *begin;
162    PCRE_SPTR end;    const pcre_uchar *end;
163    int *offsets;    int *offsets;
164    uschar *ptr;    pcre_uchar *uchar_ptr;
165      pcre_uchar *mark_ptr;
166      void *callout_data;
167    /* Everything else after. */    /* Everything else after. */
168    int offsetcount;    int offset_count;
169    int calllimit;    int call_limit;
170    uschar notbol;    pcre_uint8 notbol;
171    uschar noteol;    pcre_uint8 noteol;
172    uschar notempty;    pcre_uint8 notempty;
173    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
174  } jit_arguments;  } jit_arguments;
175    
176  typedef struct executable_function {  typedef struct executable_functions {
177    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
178    pcre_jit_callback callback;    PUBL(jit_callback) callback;
179    void *userdata;    void *userdata;
180  } executable_function;    pcre_uint32 top_bracket;
181      sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
182    } executable_functions;
183    
184  typedef struct jump_list {  typedef struct jump_list {
185    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 177  typedef struct stub_list { Line 192  typedef struct stub_list {
192    enum stub_types type;    enum stub_types type;
193    int data;    int data;
194    struct sljit_jump *start;    struct sljit_jump *start;
195    struct sljit_label *leave;    struct sljit_label *quit;
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
200    
201  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
202  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
203  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
204  of its descendants. */  of its descendants. */
205  typedef struct fallback_common {  typedef struct backtrack_common {
206    /* Concatenation stack. */    /* Concatenation stack. */
207    struct fallback_common *prev;    struct backtrack_common *prev;
208    jump_list *nextfallbacks;    jump_list *nextbacktracks;
209    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
210    struct fallback_common *top;    struct backtrack_common *top;
211    jump_list *topfallbacks;    jump_list *topbacktracks;
212    /* Opcode pointer. */    /* Opcode pointer. */
213    uschar *cc;    pcre_uchar *cc;
214  } fallback_common;  } backtrack_common;
215    
216  typedef struct assert_fallback {  typedef struct assert_backtrack {
217    fallback_common common;    backtrack_common common;
218    jump_list *condfailed;    jump_list *condfailed;
219    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
220    int framesize;    int framesize;
221    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
222    int localptr;    int private_data_ptr;
223    /* For iterators. */    /* For iterators. */
224    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
225  } assert_fallback;  } assert_backtrack;
226    
227  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
228    fallback_common common;    backtrack_common common;
229    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
230    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
231    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
232    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
233    /* For greedy ? operator. */    /* For greedy ? operator. */
234    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
235    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
236    union {    union {
237      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
238      jump_list *condfailed;      jump_list *condfailed;
239      assert_fallback *assert;      assert_backtrack *assert;
240      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
241      int framesize;      int framesize;
242    } u;    } u;
243    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
244    int localptr;    int private_data_ptr;
245  } bracket_fallback;  } bracket_backtrack;
246    
247  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
248    fallback_common common;    backtrack_common common;
249    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
250    int localptr;    int private_data_ptr;
251    /* Reverting stack is needed. */    /* Reverting stack is needed. */
252    int framesize;    int framesize;
253    /* Allocated stack size. */    /* Allocated stack size. */
254    int stacksize;    int stacksize;
255  } bracketpos_fallback;  } bracketpos_backtrack;
256    
257  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
258    fallback_common common;    backtrack_common common;
259    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
260  } braminzero_fallback;  } braminzero_backtrack;
261    
262  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
263    fallback_common common;    backtrack_common common;
264    /* Next iteration. */    /* Next iteration. */
265    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
266  } iterator_fallback;  } iterator_backtrack;
267    
268  typedef struct recurse_entry {  typedef struct recurse_entry {
269    struct recurse_entry *next;    struct recurse_entry *next;
# Line 260  typedef struct recurse_entry { Line 275  typedef struct recurse_entry {
275    int start;    int start;
276  } recurse_entry;  } recurse_entry;
277    
278  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
279    fallback_common common;    backtrack_common common;
280  } recurse_fallback;  } recurse_backtrack;
281    
282    #define MAX_RANGE_SIZE 6
283    
284  typedef struct compiler_common {  typedef struct compiler_common {
285    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
286    uschar *start;    pcre_uchar *start;
287    int localsize;  
288    int *localptrs;    /* Maps private data offset to each opcode. */
289    const uschar *fcc;    int *private_data_ptrs;
290    sljit_w lcc;    /* Tells whether the capturing bracket is optimized. */
291      pcre_uint8 *optimized_cbracket;
292      /* Starting offset of private data for capturing brackets. */
293    int cbraptr;    int cbraptr;
294      /* OVector starting point. Must be divisible by 2. */
295      int ovector_start;
296      /* Last known position of the requested byte. */
297      int req_char_ptr;
298      /* Head of the last recursion. */
299      int recursive_head_ptr;
300      /* First inspected character for partial matching. */
301      int start_used_ptr;
302      /* Starting pointer for partial soft matches. */
303      int hit_start;
304      /* End pointer of the first line. */
305      int first_line_end;
306      /* Points to the marked string. */
307      int mark_ptr;
308      /* Points to the last matched capture block index. */
309      int capture_last_ptr;
310    
311      /* Flipped and lower case tables. */
312      const pcre_uint8 *fcc;
313      sljit_sw lcc;
314      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
315      int mode;
316      /* Newline control. */
317    int nltype;    int nltype;
318    int newline;    int newline;
319    int bsr_nltype;    int bsr_nltype;
320      /* Dollar endonly. */
321    int endonly;    int endonly;
322    sljit_w ctypes;    BOOL has_set_som;
323      /* Tables. */
324      sljit_sw ctypes;
325      int digits[2 + MAX_RANGE_SIZE];
326      /* Named capturing brackets. */
327    sljit_uw name_table;    sljit_uw name_table;
328    sljit_w name_count;    sljit_sw name_count;
329    sljit_w name_entry_size;    sljit_sw name_entry_size;
330    struct sljit_label *acceptlabel;  
331      /* Labels and jump lists. */
332      struct sljit_label *partialmatchlabel;
333      struct sljit_label *quit_label;
334      struct sljit_label *forced_quit_label;
335      struct sljit_label *accept_label;
336    stub_list *stubs;    stub_list *stubs;
337    recurse_entry *entries;    recurse_entry *entries;
338    recurse_entry *currententry;    recurse_entry *currententry;
339      jump_list *partialmatch;
340      jump_list *quit;
341      jump_list *forced_quit;
342    jump_list *accept;    jump_list *accept;
343    jump_list *calllimit;    jump_list *calllimit;
344    jump_list *stackalloc;    jump_list *stackalloc;
# Line 295  typedef struct compiler_common { Line 350  typedef struct compiler_common {
350    jump_list *casefulcmp;    jump_list *casefulcmp;
351    jump_list *caselesscmp;    jump_list *caselesscmp;
352    BOOL jscript_compat;    BOOL jscript_compat;
353  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
354    BOOL utf8;    BOOL utf;
355  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
356    BOOL useucp;    BOOL use_ucp;
357    #endif
358    #ifndef COMPILE_PCRE32
359      jump_list *utfreadchar;
360  #endif  #endif
361    jump_list *utf8readchar;  #ifdef COMPILE_PCRE8
362    jump_list *utf8readtype8;    jump_list *utfreadtype8;
363  #endif  #endif
364    #endif /* SUPPORT_UTF */
365  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
366    jump_list *getucd;    jump_list *getucd;
367  #endif  #endif
# Line 314  typedef struct compare_context { Line 373  typedef struct compare_context {
373    int length;    int length;
374    int sourcereg;    int sourcereg;
375  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
376    int byteptr;    int ucharptr;
377    union {    union {
378      int asint;      sljit_si asint;
379      short asshort;      sljit_uh asushort;
380    #if defined COMPILE_PCRE8
381      sljit_ub asbyte;      sljit_ub asbyte;
382      sljit_ub asbytes[4];      sljit_ub asuchars[4];
383    #elif defined COMPILE_PCRE16
384        sljit_uh asuchars[2];
385    #elif defined COMPILE_PCRE32
386        sljit_ui asuchars[1];
387    #endif
388    } c;    } c;
389    union {    union {
390      int asint;      sljit_si asint;
391      short asshort;      sljit_uh asushort;
392    #if defined COMPILE_PCRE8
393      sljit_ub asbyte;      sljit_ub asbyte;
394      sljit_ub asbytes[4];      sljit_ub asuchars[4];
395    #elif defined COMPILE_PCRE16
396        sljit_uh asuchars[2];
397    #elif defined COMPILE_PCRE32
398        sljit_ui asuchars[1];
399    #endif
400    } oc;    } oc;
401  #endif  #endif
402  } compare_context;  } compare_context;
403    
404  enum {  /* Undefine sljit macros. */
405    frame_end = 0,  #undef CMP
   frame_setstrbegin = -1  
 };  
406    
407  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
408  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
409    
410  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
411  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
412  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
413  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
414  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
415  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
416  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
417  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
418  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
419  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
420    
421  /* Locals layout. */  /* Local space layout. */
422  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
423  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
424  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
425  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
426  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
427  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
428  /* Max limit of recursions. */  /* Max limit of recursions. */
429  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
430  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
431  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
432  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
433  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. */
434  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
435  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
436  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))
437  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
438    
439    #if defined COMPILE_PCRE8
440    #define MOV_UCHAR  SLJIT_MOV_UB
441    #define MOVU_UCHAR SLJIT_MOVU_UB
442    #elif defined COMPILE_PCRE16
443    #define MOV_UCHAR  SLJIT_MOV_UH
444    #define MOVU_UCHAR SLJIT_MOVU_UH
445    #elif defined COMPILE_PCRE32
446    #define MOV_UCHAR  SLJIT_MOV_UI
447    #define MOVU_UCHAR SLJIT_MOVU_UI
448    #else
449    #error Unsupported compiling mode
450    #endif
451    
452  /* Shortcuts. */  /* Shortcuts. */
453  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 388  the start pointers when the end of the c Line 464  the start pointers when the end of the c
464    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
465  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
466    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
467    #define SET_LABEL(jump, label) \
468      sljit_set_label((jump), (label))
469  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
470    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
471  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
472    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))
473  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
474    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
475    #define GET_LOCAL_BASE(dst, dstw, offset) \
476      sljit_get_local_base(compiler, (dst), (dstw), (offset))
477    
478  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
479  {  {
480  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));
481  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 406  return cc; Line 486  return cc;
486    
487  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
488   next_opcode   next_opcode
489   get_localspace   get_private_data_length
490   set_localptrs   set_private_data_ptrs
491   get_framesize   get_framesize
492   init_frame   init_frame
493   get_localsize   get_private_data_length_for_copy
494   copy_locals   copy_private_data
495   compile_hotpath   compile_matchingpath
496   compile_fallbackpath   compile_backtrackingpath
497  */  */
498    
499  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
500  {  {
501  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
502  switch(*cc)  switch(*cc)
# Line 465  switch(*cc) Line 545  switch(*cc)
545    case OP_BRAZERO:    case OP_BRAZERO:
546    case OP_BRAMINZERO:    case OP_BRAMINZERO:
547    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
548      case OP_COMMIT:
549    case OP_FAIL:    case OP_FAIL:
550    case OP_ACCEPT:    case OP_ACCEPT:
551    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 472  switch(*cc) Line 553  switch(*cc)
553    return cc + 1;    return cc + 1;
554    
555    case OP_ANYBYTE:    case OP_ANYBYTE:
556  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
557    if (common->utf8) return NULL;    if (common->utf) return NULL;
558  #endif  #endif
559    return cc + 1;    return cc + 1;
560    
# Line 481  switch(*cc) Line 562  switch(*cc)
562    case OP_CHARI:    case OP_CHARI:
563    case OP_NOT:    case OP_NOT:
564    case OP_NOTI:    case OP_NOTI:
   
565    case OP_STAR:    case OP_STAR:
566    case OP_MINSTAR:    case OP_MINSTAR:
567    case OP_PLUS:    case OP_PLUS:
# Line 519  switch(*cc) Line 599  switch(*cc)
599    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
600    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
601    cc += 2;    cc += 2;
602  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
603    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]);
604  #endif  #endif
605    return cc;    return cc;
606    
# Line 540  switch(*cc) Line 620  switch(*cc)
620    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
621    case OP_NOTEXACTI:    case OP_NOTEXACTI:
622    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
623    cc += 4;    cc += 2 + IMM2_SIZE;
624  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
625    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]);
626  #endif  #endif
627    return cc;    return cc;
628    
629    case OP_NOTPROP:    case OP_NOTPROP:
630    case OP_PROP:    case OP_PROP:
631      return cc + 1 + 2;
632    
633    case OP_TYPEUPTO:    case OP_TYPEUPTO:
634    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
635    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 559  switch(*cc) Line 641  switch(*cc)
641    case OP_RREF:    case OP_RREF:
642    case OP_NRREF:    case OP_NRREF:
643    case OP_CLOSE:    case OP_CLOSE:
644    cc += 3;    cc += 1 + IMM2_SIZE;
645    return cc;    return cc;
646    
647    case OP_CRRANGE:    case OP_CRRANGE:
648    case OP_CRMINRANGE:    case OP_CRMINRANGE:
649    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
650    
651    case OP_CLASS:    case OP_CLASS:
652    case OP_NCLASS:    case OP_NCLASS:
653    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
654    
655  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
656    case OP_XCLASS:    case OP_XCLASS:
657    return cc + GET(cc, 1);    return cc + GET(cc, 1);
658  #endif  #endif
# Line 600  switch(*cc) Line 682  switch(*cc)
682    case OP_CBRAPOS:    case OP_CBRAPOS:
683    case OP_SCBRA:    case OP_SCBRA:
684    case OP_SCBRAPOS:    case OP_SCBRAPOS:
685    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
686    
687      case OP_MARK:
688      return cc + 1 + 2 + cc[1];
689    
690      case OP_CALLOUT:
691      return cc + 2 + 2 * LINK_SIZE;
692    
693    default:    default:
694    return NULL;    return NULL;
695    }    }
696  }  }
697    
698  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
699        case OP_MINSTAR: \
700        case OP_MINPLUS: \
701        case OP_QUERY: \
702        case OP_MINQUERY: \
703        case OP_MINSTARI: \
704        case OP_MINPLUSI: \
705        case OP_QUERYI: \
706        case OP_MINQUERYI: \
707        case OP_NOTMINSTAR: \
708        case OP_NOTMINPLUS: \
709        case OP_NOTQUERY: \
710        case OP_NOTMINQUERY: \
711        case OP_NOTMINSTARI: \
712        case OP_NOTMINPLUSI: \
713        case OP_NOTQUERYI: \
714        case OP_NOTMINQUERYI:
715    
716    #define CASE_ITERATOR_PRIVATE_DATA_2A \
717        case OP_STAR: \
718        case OP_PLUS: \
719        case OP_STARI: \
720        case OP_PLUSI: \
721        case OP_NOTSTAR: \
722        case OP_NOTPLUS: \
723        case OP_NOTSTARI: \
724        case OP_NOTPLUSI:
725    
726    #define CASE_ITERATOR_PRIVATE_DATA_2B \
727        case OP_UPTO: \
728        case OP_MINUPTO: \
729        case OP_UPTOI: \
730        case OP_MINUPTOI: \
731        case OP_NOTUPTO: \
732        case OP_NOTMINUPTO: \
733        case OP_NOTUPTOI: \
734        case OP_NOTMINUPTOI:
735    
736    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
737        case OP_TYPEMINSTAR: \
738        case OP_TYPEMINPLUS: \
739        case OP_TYPEQUERY: \
740        case OP_TYPEMINQUERY:
741    
742    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
743        case OP_TYPESTAR: \
744        case OP_TYPEPLUS:
745    
746    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
747        case OP_TYPEUPTO: \
748        case OP_TYPEMINUPTO:
749    
750    static int get_class_iterator_size(pcre_uchar *cc)
751    {
752    switch(*cc)
753      {
754      case OP_CRSTAR:
755      case OP_CRPLUS:
756      return 2;
757    
758      case OP_CRMINSTAR:
759      case OP_CRMINPLUS:
760      case OP_CRQUERY:
761      case OP_CRMINQUERY:
762      return 1;
763    
764      case OP_CRRANGE:
765      case OP_CRMINRANGE:
766      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
767        return 0;
768      return 2;
769    
770      default:
771      return 0;
772      }
773    }
774    
775    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
776  {  {
777  int localspace = 0;  int private_data_length = 0;
778  uschar *alternative;  pcre_uchar *alternative;
779    pcre_uchar *name;
780    pcre_uchar *end = NULL;
781    int space, size, i;
782    pcre_uint32 bracketlen;
783    
784  /* 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. */
785  while (cc < ccend)  while (cc < ccend)
786    {    {
787      space = 0;
788      size = 0;
789      bracketlen = 0;
790    switch(*cc)    switch(*cc)
791      {      {
792        case OP_SET_SOM:
793        common->has_set_som = TRUE;
794        cc += 1;
795        break;
796    
797        case OP_REF:
798        case OP_REFI:
799        common->optimized_cbracket[GET2(cc, 1)] = 0;
800        cc += 1 + IMM2_SIZE;
801        break;
802    
803      case OP_ASSERT:      case OP_ASSERT:
804      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
805      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 625  while (cc < ccend) Line 809  while (cc < ccend)
809      case OP_BRAPOS:      case OP_BRAPOS:
810      case OP_SBRA:      case OP_SBRA:
811      case OP_SBRAPOS:      case OP_SBRAPOS:
812      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
813      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
814      break;      break;
815    
816      case OP_CBRAPOS:      case OP_CBRAPOS:
817      case OP_SCBRAPOS:      case OP_SCBRAPOS:
818      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
819      cc += 1 + LINK_SIZE + 2;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
820        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
821      break;      break;
822    
823      case OP_COND:      case OP_COND:
824      /* Might be a hidden SCOND. */      case OP_SCOND:
825      alternative = cc + GET(cc, 1);      /* Only AUTO_CALLOUT can insert this opcode. We do
826      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)         not intend to support this case. */
827        localspace += sizeof(sljit_w);      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
828          return -1;
829    
830        if (*cc == OP_COND)
831          {
832          /* Might be a hidden SCOND. */
833          alternative = cc + GET(cc, 1);
834          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
835            private_data_length += sizeof(sljit_sw);
836          }
837        else
838          private_data_length += sizeof(sljit_sw);
839        bracketlen = 1 + LINK_SIZE;
840        break;
841    
842        case OP_CREF:
843        i = GET2(cc, 1);
844        common->optimized_cbracket[i] = 0;
845        cc += 1 + IMM2_SIZE;
846        break;
847    
848        case OP_NCREF:
849        bracketlen = GET2(cc, 1);
850        name = (pcre_uchar *)common->name_table;
851        alternative = name;
852        for (i = 0; i < common->name_count; i++)
853          {
854          if (GET2(name, 0) == bracketlen) break;
855          name += common->name_entry_size;
856          }
857        SLJIT_ASSERT(i != common->name_count);
858    
859        for (i = 0; i < common->name_count; i++)
860          {
861          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
862            common->optimized_cbracket[GET2(alternative, 0)] = 0;
863          alternative += common->name_entry_size;
864          }
865        bracketlen = 0;
866        cc += 1 + IMM2_SIZE;
867        break;
868    
869        case OP_BRA:
870        bracketlen = 1 + LINK_SIZE;
871        break;
872    
873        case OP_CBRA:
874        case OP_SCBRA:
875        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
876        break;
877    
878        CASE_ITERATOR_PRIVATE_DATA_1
879        space = 1;
880        size = -2;
881        break;
882    
883        CASE_ITERATOR_PRIVATE_DATA_2A
884        space = 2;
885        size = -2;
886        break;
887    
888        CASE_ITERATOR_PRIVATE_DATA_2B
889        space = 2;
890        size = -(2 + IMM2_SIZE);
891        break;
892    
893        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
894        space = 1;
895        size = 1;
896        break;
897    
898        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
899        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
900          space = 2;
901        size = 1;
902        break;
903    
904        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
905        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
906          space = 2;
907        size = 1 + IMM2_SIZE;
908        break;
909    
910        case OP_CLASS:
911        case OP_NCLASS:
912        size += 1 + 32 / sizeof(pcre_uchar);
913        space = get_class_iterator_size(cc + size);
914        break;
915    
916    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
917        case OP_XCLASS:
918        size = GET(cc, 1);
919        space = get_class_iterator_size(cc + size);
920        break;
921    #endif
922    
923        case OP_RECURSE:
924        /* Set its value only once. */
925        if (common->recursive_head_ptr == 0)
926          {
927          common->recursive_head_ptr = common->ovector_start;
928          common->ovector_start += sizeof(sljit_sw);
929          }
930      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
931      break;      break;
932    
933        case OP_CALLOUT:
934        if (common->capture_last_ptr == 0)
935          {
936          common->capture_last_ptr = common->ovector_start;
937          common->ovector_start += sizeof(sljit_sw);
938          }
939        cc += 2 + 2 * LINK_SIZE;
940        break;
941    
942        case OP_MARK:
943        if (common->mark_ptr == 0)
944          {
945          common->mark_ptr = common->ovector_start;
946          common->ovector_start += sizeof(sljit_sw);
947          }
948        cc += 1 + 2 + cc[1];
949        break;
950    
951      default:      default:
952      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
953      if (cc == NULL)      if (cc == NULL)
954        return -1;        return -1;
955      break;      break;
956      }      }
957    
958      if (space > 0 && cc >= end)
959        private_data_length += sizeof(sljit_sw) * space;
960    
961      if (size != 0)
962        {
963        if (size < 0)
964          {
965          cc += -size;
966    #ifdef SUPPORT_UTF
967          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
968    #endif
969          }
970        else
971          cc += size;
972        }
973    
974      if (bracketlen != 0)
975        {
976        if (cc >= end)
977          {
978          end = bracketend(cc);
979          if (end[-1 - LINK_SIZE] == OP_KET)
980            end = NULL;
981          }
982        cc += bracketlen;
983        }
984    }    }
985  return localspace;  return private_data_length;
986  }  }
987    
988  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)
989  {  {
990  uschar *cc = common->start;  pcre_uchar *cc = common->start;
991  uschar *alternative;  pcre_uchar *alternative;
992    pcre_uchar *end = NULL;
993    int space, size, bracketlen;
994    
995  while (cc < ccend)  while (cc < ccend)
996    {    {
997      space = 0;
998      size = 0;
999      bracketlen = 0;
1000    switch(*cc)    switch(*cc)
1001      {      {
1002      case OP_ASSERT:      case OP_ASSERT:
# Line 672  while (cc < ccend) Line 1009  while (cc < ccend)
1009      case OP_SBRA:      case OP_SBRA:
1010      case OP_SBRAPOS:      case OP_SBRAPOS:
1011      case OP_SCOND:      case OP_SCOND:
1012      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1013      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1014      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1015      break;      break;
1016    
1017      case OP_CBRAPOS:      case OP_CBRAPOS:
1018      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1019      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1020      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1021      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1022      break;      break;
1023    
1024      case OP_COND:      case OP_COND:
# Line 689  while (cc < ccend) Line 1026  while (cc < ccend)
1026      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1027      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1028        {        {
1029        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1030        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1031        }        }
1032      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1033        break;
1034    
1035        case OP_BRA:
1036        bracketlen = 1 + LINK_SIZE;
1037        break;
1038    
1039        case OP_CBRA:
1040        case OP_SCBRA:
1041        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1042        break;
1043    
1044        CASE_ITERATOR_PRIVATE_DATA_1
1045        space = 1;
1046        size = -2;
1047        break;
1048    
1049        CASE_ITERATOR_PRIVATE_DATA_2A
1050        space = 2;
1051        size = -2;
1052        break;
1053    
1054        CASE_ITERATOR_PRIVATE_DATA_2B
1055        space = 2;
1056        size = -(2 + IMM2_SIZE);
1057        break;
1058    
1059        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1060        space = 1;
1061        size = 1;
1062        break;
1063    
1064        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1065        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1066          space = 2;
1067        size = 1;
1068        break;
1069    
1070        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1071        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1072          space = 2;
1073        size = 1 + IMM2_SIZE;
1074        break;
1075    
1076        case OP_CLASS:
1077        case OP_NCLASS:
1078        size += 1 + 32 / sizeof(pcre_uchar);
1079        space = get_class_iterator_size(cc + size);
1080        break;
1081    
1082    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1083        case OP_XCLASS:
1084        size = GET(cc, 1);
1085        space = get_class_iterator_size(cc + size);
1086      break;      break;
1087    #endif
1088    
1089      default:      default:
1090      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1091      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1092      break;      break;
1093      }      }
1094    
1095      if (space > 0 && cc >= end)
1096        {
1097        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1098        private_data_ptr += sizeof(sljit_sw) * space;
1099        }
1100    
1101      if (size != 0)
1102        {
1103        if (size < 0)
1104          {
1105          cc += -size;
1106    #ifdef SUPPORT_UTF
1107          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1108    #endif
1109          }
1110        else
1111          cc += size;
1112        }
1113    
1114      if (bracketlen > 0)
1115        {
1116        if (cc >= end)
1117          {
1118          end = bracketend(cc);
1119          if (end[-1 - LINK_SIZE] == OP_KET)
1120            end = NULL;
1121          }
1122        cc += bracketlen;
1123        }
1124    }    }
1125  }  }
1126    
1127  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
1128  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1129  {  {
1130  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1131  int length = 0;  int length = 0;
1132  BOOL possessive = FALSE;  int possessive = 0;
1133  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1134    BOOL setmark_found = recursive;
1135    /* The last capture is a local variable even for recursions. */
1136    BOOL capture_last_found = FALSE;
1137    
1138  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1139    {    {
1140    length = 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1141    possessive = TRUE;    /* This is correct regardless of common->capture_last_ptr. */
1142      capture_last_found = TRUE;
1143    }    }
1144    
1145  cc = next_opcode(common, cc);  cc = next_opcode(common, cc);
# Line 723  while (cc < ccend) Line 1148  while (cc < ccend)
1148    switch(*cc)    switch(*cc)
1149      {      {
1150      case OP_SET_SOM:      case OP_SET_SOM:
1151      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1152      if (!setsom_found)      if (!setsom_found)
1153        {        {
1154        length += 2;        length += 2;
1155        setsom_found = TRUE;        setsom_found = TRUE;
1156        }        }
1157      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1158        break;
1159    
1160        case OP_MARK:
1161        SLJIT_ASSERT(common->mark_ptr != 0);
1162        if (!setmark_found)
1163          {
1164          length += 2;
1165          setmark_found = TRUE;
1166          }
1167        cc += 1 + 2 + cc[1];
1168        break;
1169    
1170        case OP_RECURSE:
1171        if (common->has_set_som && !setsom_found)
1172          {
1173          length += 2;
1174          setsom_found = TRUE;
1175          }
1176        if (common->mark_ptr != 0 && !setmark_found)
1177          {
1178          length += 2;
1179          setmark_found = TRUE;
1180          }
1181        if (common->capture_last_ptr != 0 && !capture_last_found)
1182          {
1183          length += 2;
1184          capture_last_found = TRUE;
1185          }
1186        cc += 1 + LINK_SIZE;
1187      break;      break;
1188    
1189      case OP_CBRA:      case OP_CBRA:
1190      case OP_CBRAPOS:      case OP_CBRAPOS:
1191      case OP_SCBRA:      case OP_SCBRA:
1192      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1193        if (common->capture_last_ptr != 0 && !capture_last_found)
1194          {
1195          length += 2;
1196          capture_last_found = TRUE;
1197          }
1198      length += 3;      length += 3;
1199      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1200      break;      break;
1201    
1202      default:      default:
# Line 747  while (cc < ccend) Line 1206  while (cc < ccend)
1206      }      }
1207    
1208  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1209  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1210    return -1;    return -1;
1211    
1212  if (length > 0)  if (length > 0)
# Line 755  if (length > 0) Line 1214  if (length > 0)
1214  return -1;  return -1;
1215  }  }
1216    
1217  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)
1218  {  {
1219  DEFINE_COMPILER;  DEFINE_COMPILER;
1220  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1221  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1222    BOOL setmark_found = recursive;
1223    /* The last capture is a local variable even for recursions. */
1224    BOOL capture_last_found = FALSE;
1225  int offset;  int offset;
1226    
1227  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1228    SLJIT_UNUSED_ARG(stacktop);
1229  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1230    
1231  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 773  while (cc < ccend) Line 1236  while (cc < ccend)
1236    switch(*cc)    switch(*cc)
1237      {      {
1238      case OP_SET_SOM:      case OP_SET_SOM:
1239      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1240      if (!setsom_found)      if (!setsom_found)
1241        {        {
1242        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1243        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1244        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1245          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1246          stackpos += (int)sizeof(sljit_sw);
1247          setsom_found = TRUE;
1248          }
1249        cc += 1;
1250        break;
1251    
1252        case OP_MARK:
1253        SLJIT_ASSERT(common->mark_ptr != 0);
1254        if (!setmark_found)
1255          {
1256          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1257          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1258          stackpos += (int)sizeof(sljit_sw);
1259          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1260          stackpos += (int)sizeof(sljit_sw);
1261          setmark_found = TRUE;
1262          }
1263        cc += 1 + 2 + cc[1];
1264        break;
1265    
1266        case OP_RECURSE:
1267        if (common->has_set_som && !setsom_found)
1268          {
1269          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1270          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1271          stackpos += (int)sizeof(sljit_sw);
1272        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1273        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1274        setsom_found = TRUE;        setsom_found = TRUE;
1275        }        }
1276      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      if (common->mark_ptr != 0 && !setmark_found)
1277          {
1278          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1279          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1280          stackpos += (int)sizeof(sljit_sw);
1281          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1282          stackpos += (int)sizeof(sljit_sw);
1283          setmark_found = TRUE;
1284          }
1285        if (common->capture_last_ptr != 0 && !capture_last_found)
1286          {
1287          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1288          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1289          stackpos += (int)sizeof(sljit_sw);
1290          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1291          stackpos += (int)sizeof(sljit_sw);
1292          capture_last_found = TRUE;
1293          }
1294        cc += 1 + LINK_SIZE;
1295      break;      break;
1296    
1297      case OP_CBRA:      case OP_CBRA:
1298      case OP_CBRAPOS:      case OP_CBRAPOS:
1299      case OP_SCBRA:      case OP_SCBRA:
1300      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1301        if (common->capture_last_ptr != 0 && !capture_last_found)
1302          {
1303          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1304          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1305          stackpos += (int)sizeof(sljit_sw);
1306          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1307          stackpos += (int)sizeof(sljit_sw);
1308          capture_last_found = TRUE;
1309          }
1310      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1311      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1312      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1313      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1314      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));
1315      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1316      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1317      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1318      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1319    
1320      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1321      break;      break;
1322    
1323      default:      default:
# Line 809  while (cc < ccend) Line 1326  while (cc < ccend)
1326      break;      break;
1327      }      }
1328    
1329  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1330  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1331  }  }
1332    
1333  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)
1334  {  {
1335  int localsize = 2;  int private_data_length = 2;
1336  uschar *alternative;  int size;
1337  /* Calculate the sum of the local variables. */  pcre_uchar *alternative;
1338    /* Calculate the sum of the private machine words. */
1339  while (cc < ccend)  while (cc < ccend)
1340    {    {
1341      size = 0;
1342    switch(*cc)    switch(*cc)
1343      {      {
1344      case OP_ASSERT:      case OP_ASSERT:
# Line 832  while (cc < ccend) Line 1351  while (cc < ccend)
1351      case OP_SBRA:      case OP_SBRA:
1352      case OP_SBRAPOS:      case OP_SBRAPOS:
1353      case OP_SCOND:      case OP_SCOND:
1354      localsize++;      private_data_length++;
1355      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1356      break;      break;
1357    
1358      case OP_CBRA:      case OP_CBRA:
1359      case OP_SCBRA:      case OP_SCBRA:
1360      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1361      cc += 1 + LINK_SIZE + 2;        private_data_length++;
1362        cc += 1 + LINK_SIZE + IMM2_SIZE;
1363      break;      break;
1364    
1365      case OP_CBRAPOS:      case OP_CBRAPOS:
1366      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1367      localsize += 2;      private_data_length += 2;
1368      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1369      break;      break;
1370    
1371      case OP_COND:      case OP_COND:
1372      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1373      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1374      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1375        localsize++;        private_data_length++;
1376      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1377      break;      break;
1378    
1379        CASE_ITERATOR_PRIVATE_DATA_1
1380        if (PRIVATE_DATA(cc))
1381          private_data_length++;
1382        cc += 2;
1383    #ifdef SUPPORT_UTF
1384        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1385    #endif
1386        break;
1387    
1388        CASE_ITERATOR_PRIVATE_DATA_2A
1389        if (PRIVATE_DATA(cc))
1390          private_data_length += 2;
1391        cc += 2;
1392    #ifdef SUPPORT_UTF
1393        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1394    #endif
1395        break;
1396    
1397        CASE_ITERATOR_PRIVATE_DATA_2B
1398        if (PRIVATE_DATA(cc))
1399          private_data_length += 2;
1400        cc += 2 + IMM2_SIZE;
1401    #ifdef SUPPORT_UTF
1402        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1403    #endif
1404        break;
1405    
1406        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1407        if (PRIVATE_DATA(cc))
1408          private_data_length++;
1409        cc += 1;
1410        break;
1411    
1412        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1413        if (PRIVATE_DATA(cc))
1414          private_data_length += 2;
1415        cc += 1;
1416        break;
1417    
1418        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1419        if (PRIVATE_DATA(cc))
1420          private_data_length += 2;
1421        cc += 1 + IMM2_SIZE;
1422        break;
1423    
1424        case OP_CLASS:
1425        case OP_NCLASS:
1426    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1427        case OP_XCLASS:
1428        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1429    #else
1430        size = 1 + 32 / (int)sizeof(pcre_uchar);
1431    #endif
1432        if (PRIVATE_DATA(cc))
1433          private_data_length += get_class_iterator_size(cc + size);
1434        cc += size;
1435        break;
1436    
1437      default:      default:
1438      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1439      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 863  while (cc < ccend) Line 1441  while (cc < ccend)
1441      }      }
1442    }    }
1443  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1444  return localsize;  return private_data_length;
1445  }  }
1446    
1447  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,
1448    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1449  {  {
1450  DEFINE_COMPILER;  DEFINE_COMPILER;
1451  int srcw[2];  int srcw[2];
1452  int count;  int count, size;
1453  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1454  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1455  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1456  uschar *alternative;  pcre_uchar *alternative;
1457  enum {  enum {
1458    start,    start,
1459    loop,    loop,
# Line 888  stacktop = STACK(stacktop - 1); Line 1466  stacktop = STACK(stacktop - 1);
1466    
1467  if (!save)  if (!save)
1468    {    {
1469    stackptr += sizeof(sljit_w);    stackptr += sizeof(sljit_sw);
1470    if (stackptr < stacktop)    if (stackptr < stacktop)
1471      {      {
1472      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1473      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1474      tmp1empty = FALSE;      tmp1empty = FALSE;
1475      }      }
1476    if (stackptr < stacktop)    if (stackptr < stacktop)
1477      {      {
1478      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1479      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1480      tmp2empty = FALSE;      tmp2empty = FALSE;
1481      }      }
1482    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
# Line 910  while (status != end) Line 1488  while (status != end)
1488    switch(status)    switch(status)
1489      {      {
1490      case start:      case start:
1491      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1492      count = 1;      count = 1;
1493      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head_ptr;
1494      status = loop;      status = loop;
1495      break;      break;
1496    
# Line 936  while (status != end) Line 1514  while (status != end)
1514        case OP_SBRAPOS:        case OP_SBRAPOS:
1515        case OP_SCOND:        case OP_SCOND:
1516        count = 1;        count = 1;
1517        srcw[0] = PRIV(cc);        srcw[0] = PRIVATE_DATA(cc);
1518        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1519        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1520        break;        break;
1521    
1522        case OP_CBRA:        case OP_CBRA:
1523        case OP_SCBRA:        case OP_SCBRA:
1524        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1525        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1526        cc += 1 + LINK_SIZE + 2;          count = 1;
1527        break;          srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1528            }
1529          cc += 1 + LINK_SIZE + IMM2_SIZE;
1530          break;
1531    
1532        case OP_CBRAPOS:        case OP_CBRAPOS:
1533        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1534        count = 2;        count = 2;
1535          srcw[0] = PRIVATE_DATA(cc);
1536        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1537        srcw[0] = PRIV(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1538        SLJIT_ASSERT(srcw[0] != 0);        cc += 1 + LINK_SIZE + IMM2_SIZE;
       cc += 1 + LINK_SIZE + 2;  
1539        break;        break;
1540    
1541        case OP_COND:        case OP_COND:
# Line 963  while (status != end) Line 1544  while (status != end)
1544        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1545          {          {
1546          count = 1;          count = 1;
1547          srcw[0] = PRIV(cc);          srcw[0] = PRIVATE_DATA(cc);
1548          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1549          }          }
1550        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1551        break;        break;
1552    
1553          CASE_ITERATOR_PRIVATE_DATA_1
1554          if (PRIVATE_DATA(cc))
1555            {
1556            count = 1;
1557            srcw[0] = PRIVATE_DATA(cc);
1558            }
1559          cc += 2;
1560    #ifdef SUPPORT_UTF
1561          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1562    #endif
1563          break;
1564    
1565          CASE_ITERATOR_PRIVATE_DATA_2A
1566          if (PRIVATE_DATA(cc))
1567            {
1568            count = 2;
1569            srcw[0] = PRIVATE_DATA(cc);
1570            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1571            }
1572          cc += 2;
1573    #ifdef SUPPORT_UTF
1574          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1575    #endif
1576          break;
1577    
1578          CASE_ITERATOR_PRIVATE_DATA_2B
1579          if (PRIVATE_DATA(cc))
1580            {
1581            count = 2;
1582            srcw[0] = PRIVATE_DATA(cc);
1583            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1584            }
1585          cc += 2 + IMM2_SIZE;
1586    #ifdef SUPPORT_UTF
1587          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1588    #endif
1589          break;
1590    
1591          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1592          if (PRIVATE_DATA(cc))
1593            {
1594            count = 1;
1595            srcw[0] = PRIVATE_DATA(cc);
1596            }
1597          cc += 1;
1598          break;
1599    
1600          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1601          if (PRIVATE_DATA(cc))
1602            {
1603            count = 2;
1604            srcw[0] = PRIVATE_DATA(cc);
1605            srcw[1] = srcw[0] + sizeof(sljit_sw);
1606            }
1607          cc += 1;
1608          break;
1609    
1610          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1611          if (PRIVATE_DATA(cc))
1612            {
1613            count = 2;
1614            srcw[0] = PRIVATE_DATA(cc);
1615            srcw[1] = srcw[0] + sizeof(sljit_sw);
1616            }
1617          cc += 1 + IMM2_SIZE;
1618          break;
1619    
1620          case OP_CLASS:
1621          case OP_NCLASS:
1622    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1623          case OP_XCLASS:
1624          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1625    #else
1626          size = 1 + 32 / (int)sizeof(pcre_uchar);
1627    #endif
1628          if (PRIVATE_DATA(cc))
1629            switch(get_class_iterator_size(cc + size))
1630              {
1631              case 1:
1632              count = 1;
1633              srcw[0] = PRIVATE_DATA(cc);
1634              break;
1635    
1636              case 2:
1637              count = 2;
1638              srcw[0] = PRIVATE_DATA(cc);
1639              srcw[1] = srcw[0] + sizeof(sljit_sw);
1640              break;
1641    
1642              default:
1643              SLJIT_ASSERT_STOP();
1644              break;
1645              }
1646          cc += size;
1647          break;
1648    
1649        default:        default:
1650        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1651        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 991  while (status != end) Line 1668  while (status != end)
1668          if (!tmp1empty)          if (!tmp1empty)
1669            {            {
1670            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1671            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1672            }            }
1673          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1674          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1002  while (status != end) Line 1679  while (status != end)
1679          if (!tmp2empty)          if (!tmp2empty)
1680            {            {
1681            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1682            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1683            }            }
1684          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1685          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1019  while (status != end) Line 1696  while (status != end)
1696          if (!tmp1empty)          if (!tmp1empty)
1697            {            {
1698            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1699            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1700            }            }
1701          tmp1next = FALSE;          tmp1next = FALSE;
1702          }          }
# Line 1031  while (status != end) Line 1708  while (status != end)
1708          if (!tmp2empty)          if (!tmp2empty)
1709            {            {
1710            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1711            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1712            }            }
1713          tmp1next = TRUE;          tmp1next = TRUE;
1714          }          }
# Line 1046  if (save) Line 1723  if (save)
1723      if (!tmp1empty)      if (!tmp1empty)
1724        {        {
1725        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1726        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1727        }        }
1728      if (!tmp2empty)      if (!tmp2empty)
1729        {        {
1730        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1731        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1732        }        }
1733      }      }
1734    else    else
# Line 1059  if (save) Line 1736  if (save)
1736      if (!tmp2empty)      if (!tmp2empty)
1737        {        {
1738        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1739        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1740        }        }
1741      if (!tmp1empty)      if (!tmp1empty)
1742        {        {
1743        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1744        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1745        }        }
1746      }      }
1747    }    }
1748  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1749  }  }
1750    
1751  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1752    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1753    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1754    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1755    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1756    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1757    
1758    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1759  {  {
1760  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1761  }  }
# Line 1081  static SLJIT_INLINE void set_jumps(jump_ Line 1765  static SLJIT_INLINE void set_jumps(jump_
1765  while (list)  while (list)
1766    {    {
1767    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1768    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1769    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1770    list = list->next;    list = list->next;
1771    }    }
1772  }  }
# Line 1108  if (list_item) Line 1792  if (list_item)
1792    list_item->type = type;    list_item->type = type;
1793    list_item->data = data;    list_item->data = data;
1794    list_item->start = start;    list_item->start = start;
1795    list_item->leave = LABEL();    list_item->quit = LABEL();
1796    list_item->next = common->stubs;    list_item->next = common->stubs;
1797    common->stubs = list_item;    common->stubs = list_item;
1798    }    }
# Line 1128  while (list_item) Line 1812  while (list_item)
1812      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1813      break;      break;
1814      }      }
1815    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1816    list_item = list_item->next;    list_item = list_item->next;
1817    }    }
1818  common->stubs = NULL;  common->stubs = NULL;
# Line 1147  static SLJIT_INLINE void allocate_stack( Line 1831  static SLJIT_INLINE void allocate_stack(
1831  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
1832  DEFINE_COMPILER;  DEFINE_COMPILER;
1833    
1834  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));
1835  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
1836  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1837  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1161  add_stub(common, stack_alloc, 0, CMP(SLJ Line 1845  add_stub(common, stack_alloc, 0, CMP(SLJ
1845  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1846  {  {
1847  DEFINE_COMPILER;  DEFINE_COMPILER;
1848  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));
1849  }  }
1850    
1851  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1171  struct sljit_label *loop; Line 1855  struct sljit_label *loop;
1855  int i;  int i;
1856  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1857  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1858  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1859  if (length < 8)  if (length < 8)
1860    {    {
1861    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
1862      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1863    }    }
1864  else  else
1865    {    {
1866    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));
1867    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);
1868    loop = LABEL();    loop = LABEL();
1869    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1870    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
1871    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1872    }    }
1873  }  }
# Line 1192  static SLJIT_INLINE void copy_ovector(co Line 1876  static SLJIT_INLINE void copy_ovector(co
1876  {  {
1877  DEFINE_COMPILER;  DEFINE_COMPILER;
1878  struct sljit_label *loop;  struct sljit_label *loop;
1879  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
1880    
1881  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1882  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));
1883  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);
1884    
1885  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1886  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  if (common->mark_ptr != 0)
1887  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1888  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
1889  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  if (common->mark_ptr != 0)
1890      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
1891    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1892    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1893    GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1894  /* Unlikely, but possible */  /* Unlikely, but possible */
1895  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
1896  loop = LABEL();  loop = LABEL();
1897  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_SCRATCH_REG1, 0);
1898  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));
1899  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1900  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1901  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1902    #endif
1903    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1904    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1905  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1906  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
1907    
1908  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1909  if (topbracket > 1)  if (topbracket > 1)
1910    {    {
1911    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
1912    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
1913    
1914    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1915    loop = LABEL();    loop = LABEL();
1916    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
1917    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1918    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1919    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
1920    }    }
1921  else  else
1922    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1923  }  }
1924    
1925  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)
1926    {
1927    DEFINE_COMPILER;
1928    
1929    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1930    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1931    
1932    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
1933    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1934    OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offset_count));
1935    CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
1936    
1937    /* Store match begin and end. */
1938    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1939    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1940    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1941    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1942    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1943    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1944    #endif
1945    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1946    
1947    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
1948    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1949    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1950    #endif
1951    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
1952    
1953    JUMPTO(SLJIT_JUMP, quit);
1954    }
1955    
1956    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1957    {
1958    /* May destroy TMP1. */
1959    DEFINE_COMPILER;
1960    struct sljit_jump *jump;
1961    
1962    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1963      {
1964      /* The value of -1 must be kept for start_used_ptr! */
1965      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1966      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1967      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1968      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1969      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1970      JUMPHERE(jump);
1971      }
1972    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1973      {
1974      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1975      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1976      JUMPHERE(jump);
1977      }
1978    }
1979    
1980    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1981  {  {
1982  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1983  unsigned int c;  unsigned int c;
1984    
1985  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1986  if (common->utf8)  if (common->utf)
1987    {    {
1988    GETCHAR(c, cc);    GETCHAR(c, cc);
1989    if (c > 127)    if (c > 127)
# Line 1248  if (common->utf8) Line 1994  if (common->utf8)
1994      return FALSE;      return FALSE;
1995  #endif  #endif
1996      }      }
1997    #ifndef COMPILE_PCRE8
1998      return common->fcc[c] != c;
1999    #endif
2000    }    }
2001  else  else
2002  #endif  #endif
2003    c = *cc;    c = *cc;
2004  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
2005  }  }
2006    
2007  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)
2008  {  {
2009  /* Returns with the othercase. */  /* Returns with the othercase. */
2010  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2011  if (common->utf8 && c > 127)  if (common->utf && c > 127)
2012    {    {
2013  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2014    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1268  if (common->utf8 && c > 127) Line 2017  if (common->utf8 && c > 127)
2017  #endif  #endif
2018    }    }
2019  #endif  #endif
2020  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
2021  }  }
2022    
2023  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)
2024  {  {
2025  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
2026  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2027  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2028  int n;  int n;
2029  #endif  #endif
2030    
2031  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2032  if (common->utf8)  if (common->utf)
2033    {    {
2034    GETCHAR(c, cc);    GETCHAR(c, cc);
2035    if (c <= 127)    if (c <= 127)
# Line 1297  if (common->utf8) Line 2046  if (common->utf8)
2046  else  else
2047    {    {
2048    c = *cc;    c = *cc;
2049    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
2050    }    }
2051  #else  #else
2052  c = *cc;  c = *cc;
2053  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
2054  #endif  #endif
2055    
2056  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1312  if (c <= 127 && bit == 0x20) Line 2061  if (c <= 127 && bit == 0x20)
2061    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2062    
2063  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2064  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2065    return 0;    return 0;
2066    
2067  #ifdef SUPPORT_UTF8  #if defined COMPILE_PCRE8
2068  if (common->utf8 && c > 127)  
2069    #ifdef SUPPORT_UTF
2070    if (common->utf && c > 127)
2071    {    {
2072    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
2073    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
2074      {      {
2075      n--;      n--;
# Line 1326  if (common->utf8 && c > 127) Line 2077  if (common->utf8 && c > 127)
2077      }      }
2078    return (n << 8) | bit;    return (n << 8) | bit;
2079    }    }
2080  #endif  #endif /* SUPPORT_UTF */
2081  return (0 << 8) | bit;  return (0 << 8) | bit;
2082    
2083    #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2084    
2085    #ifdef SUPPORT_UTF
2086    if (common->utf && c > 65535)
2087      {
2088      if (bit >= (1 << 10))
2089        bit >>= 10;
2090      else
2091        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
2092      }
2093    #endif /* SUPPORT_UTF */
2094    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
2095    
2096    #endif /* COMPILE_PCRE[8|16|32] */
2097    }
2098    
2099    static void check_partial(compiler_common *common, BOOL force)
2100    {
2101    /* Checks whether a partial matching is occured. Does not modify registers. */
2102    DEFINE_COMPILER;
2103    struct sljit_jump *jump = NULL;
2104    
2105    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2106    
2107    if (common->mode == JIT_COMPILE)
2108      return;
2109    
2110    if (!force)
2111      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2112    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2113      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2114    
2115    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2116      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2117    else
2118      {
2119      if (common->partialmatchlabel != NULL)
2120        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2121      else
2122        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2123      }
2124    
2125    if (jump != NULL)
2126      JUMPHERE(jump);
2127    }
2128    
2129    static struct sljit_jump *check_str_end(compiler_common *common)
2130    {
2131    /* Does not affect registers. Usually used in a tight spot. */
2132    DEFINE_COMPILER;
2133    struct sljit_jump *jump;
2134    struct sljit_jump *nohit;
2135    struct sljit_jump *return_value;
2136    
2137    if (common->mode == JIT_COMPILE)
2138      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2139    
2140    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2141    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2142      {
2143      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2144      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2145      JUMPHERE(nohit);
2146      return_value = JUMP(SLJIT_JUMP);
2147      }
2148    else
2149      {
2150      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2151      if (common->partialmatchlabel != NULL)
2152        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2153      else
2154        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2155      }
2156    JUMPHERE(jump);
2157    return return_value;
2158  }  }
2159    
2160  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2161  {  {
2162  DEFINE_COMPILER;  DEFINE_COMPILER;
2163  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
2164    
2165    if (common->mode == JIT_COMPILE)
2166      {
2167      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2168      return;
2169      }
2170    
2171    /* Partial matching mode. */
2172    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2173    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2174    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2175      {
2176      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2177      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2178      }
2179    else
2180      {
2181      if (common->partialmatchlabel != NULL)
2182        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2183      else
2184        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2185      }
2186    JUMPHERE(jump);
2187  }  }
2188    
2189  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1341  static void read_char(compiler_common *c Line 2191  static void read_char(compiler_common *c
2191  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2192  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2193  DEFINE_COMPILER;  DEFINE_COMPILER;
2194  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2195  struct sljit_jump *jump;  struct sljit_jump *jump;
2196  #endif  #endif
2197    
2198  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2199  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2200  if (common->utf8)  if (common->utf)
2201    {    {
2202    #if defined COMPILE_PCRE8
2203    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2204    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #elif defined COMPILE_PCRE16
2205      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2206    #endif /* COMPILE_PCRE[8|16] */
2207      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2208    JUMPHERE(jump);    JUMPHERE(jump);
2209    }    }
2210  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2211  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));
2212  }  }
2213    
2214  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1362  static void peek_char(compiler_common *c Line 2216  static void peek_char(compiler_common *c
2216  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2217  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2218  DEFINE_COMPILER;  DEFINE_COMPILER;
2219  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2220  struct sljit_jump *jump;  struct sljit_jump *jump;
2221  #endif  #endif
2222    
2223  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2224  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2225  if (common->utf8)  if (common->utf)
2226    {    {
2227    #if defined COMPILE_PCRE8
2228    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2229    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #elif defined COMPILE_PCRE16
2230      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2231    #endif /* COMPILE_PCRE[8|16] */
2232      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2233    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2234    JUMPHERE(jump);    JUMPHERE(jump);
2235    }    }
2236  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2237  }  }
2238    
2239  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2240  {  {
2241  /* 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. */
2242  DEFINE_COMPILER;  DEFINE_COMPILER;
2243  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2244  struct sljit_jump *jump;  struct sljit_jump *jump;
2245  #endif  #endif
2246    
2247  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2248  if (common->utf8)  if (common->utf)
2249    {    {
2250    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2251    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));
2252    #if defined COMPILE_PCRE8
2253    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2254    it is a clever early read in most cases. */    it is needed in most cases. */
2255    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2256    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2257    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2258      JUMPHERE(jump);
2259    #elif defined COMPILE_PCRE16
2260      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2261      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2262      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2263    JUMPHERE(jump);    JUMPHERE(jump);
2264      /* Skip low surrogate if necessary. */
2265      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2266      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2267      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2268      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2269      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2270    #elif defined COMPILE_PCRE32
2271      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2272      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2273      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2274      JUMPHERE(jump);
2275    #endif /* COMPILE_PCRE[8|16|32] */
2276    return;    return;
2277    }    }
2278    #endif /* SUPPORT_UTF */
2279    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2280    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2281    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2282    /* The ctypes array contains only 256 values. */
2283    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2284    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2285    #endif
2286    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2287    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2288    JUMPHERE(jump);
2289  #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);  
2290  }  }
2291    
2292  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2293  {  {
2294  /* 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. */
2295  DEFINE_COMPILER;  DEFINE_COMPILER;
2296  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2297    #if defined COMPILE_PCRE8
2298  struct sljit_label *label;  struct sljit_label *label;
2299    
2300  if (common->utf8)  if (common->utf)
2301    {    {
2302    label = LABEL();    label = LABEL();
2303    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2304    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));
2305    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2306    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2307    return;    return;
2308    }    }
2309  #endif  #elif defined COMPILE_PCRE16
2310  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2311      {
2312      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2313      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2314      /* Skip low surrogate if necessary. */
2315      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2316      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2317      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2318      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2319      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2320      return;
2321      }
2322    #endif /* COMPILE_PCRE[8|16] */
2323    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2324    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2325  }  }
2326    
2327  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)
2328  {  {
2329  /* 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. */
2330  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1433  DEFINE_COMPILER; Line 2332  DEFINE_COMPILER;
2332  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2333    {    {
2334    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2335    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));
2336    }    }
2337  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2338    {    {
2339    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);
2340    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2341    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);
2342    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);
2343    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));
2344    }    }
2345  else  else
2346    {    {
2347    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2348    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));
2349    }    }
2350  }  }
2351    
2352  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2353  static void do_utf8readchar(compiler_common *common)  
2354    #if defined COMPILE_PCRE8
2355    static void do_utfreadchar(compiler_common *common)
2356  {  {
2357  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2358  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
2359  DEFINE_COMPILER;  DEFINE_COMPILER;
2360  struct sljit_jump *jump;  struct sljit_jump *jump;
2361    
2362  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2363  /* Searching for the first zero. */  /* Searching for the first zero. */
2364  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);
2365  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2366  /* 2 byte sequence */  /* Two byte sequence. */
2367  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2368  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));
2369  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2370  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2371  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2372  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2373  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2374  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2375  JUMPHERE(jump);  JUMPHERE(jump);
2376    
2377  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);
2378  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2379  /* 3 byte sequence */  /* Three byte sequence. */
2380  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2381  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2382  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2383  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2384  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2385  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2386  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2387  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));
2388  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2389  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2390  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2391  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2392  JUMPHERE(jump);  JUMPHERE(jump);
2393    
2394  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2395  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);  
2396  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2397  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2398  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2399  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2400  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2401  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2402  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2403  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2404  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2405  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2406  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2407  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2408  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2409  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  
2410  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2411  }  }
2412    
2413  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2414  {  {
2415  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2416  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2417  DEFINE_COMPILER;  DEFINE_COMPILER;
2418  struct sljit_jump *jump;  struct sljit_jump *jump;
2419  struct sljit_jump *compare;  struct sljit_jump *compare;
2420    
2421  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2422    
2423  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);
2424  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2425  /* 2 byte sequence */  /* Two byte sequence. */
2426  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2427  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));
2428  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2429  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2430  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1563  sljit_emit_fast_return(compiler, RETURN_ Line 2439  sljit_emit_fast_return(compiler, RETURN_
2439  JUMPHERE(jump);  JUMPHERE(jump);
2440    
2441  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2442  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2443  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2444  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2445  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2446  }  }
2447    
2448  #endif  #elif defined COMPILE_PCRE16
2449    
2450    static void do_utfreadchar(compiler_common *common)
2451    {
2452    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2453    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2454    DEFINE_COMPILER;
2455    struct sljit_jump *jump;
2456    
2457    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2458    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2459    /* Do nothing, only return. */
2460    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2461    
2462    JUMPHERE(jump);
2463    /* Combine two 16 bit characters. */
2464    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2465    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2466    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2467    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2468    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2469    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2470    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2471    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2472    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2473    }
2474    
2475    #endif /* COMPILE_PCRE[8|16] */
2476    
2477    #endif /* SUPPORT_UTF */
2478    
2479  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2480    
# Line 1585  DEFINE_COMPILER; Line 2490  DEFINE_COMPILER;
2490    
2491  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2492    
2493  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2494  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2495  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));
2496  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2497  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2498  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2499  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2500  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2501  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));
2502  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2503  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2504  }  }
# Line 1607  struct sljit_label *newlinelabel = NULL; Line 2512  struct sljit_label *newlinelabel = NULL;
2512  struct sljit_jump *start;  struct sljit_jump *start;
2513  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2514  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2515  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2516  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
2517  #endif  #endif
2518  jump_list *newline = NULL;  jump_list *newline = NULL;
2519  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
2520  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
2521    
2522  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2523      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1621  if (!(hascrorlf || firstline) && (common Line 2526  if (!(hascrorlf || firstline) && (common
2526  if (firstline)  if (firstline)
2527    {    {
2528    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2529    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2530    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2531    
2532    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2533      {      {
2534      mainloop = LABEL();      mainloop = LABEL();
2535      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));
2536      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2537      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2538      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2539      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
2540      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
2541      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      JUMPHERE(end);
2542        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2543      }      }
2544    else    else
2545      {      {
2546      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2547      mainloop = LABEL();      mainloop = LABEL();
2548      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2549      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2550      read_char(common);      read_char(common);
2551      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2552      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2553      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2554        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2555      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2556      }      }
2557    
2558    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2559    }    }
2560    
2561  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1657  start = JUMP(SLJIT_JUMP); Line 2563  start = JUMP(SLJIT_JUMP);
2563  if (newlinecheck)  if (newlinecheck)
2564    {    {
2565    newlinelabel = LABEL();    newlinelabel = LABEL();
2566    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));
2567    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2568    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2569    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, common->newline & 0xff);
2570    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2571    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2572      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2573    #endif
2574    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2575    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2576    }    }
# Line 1669  if (newlinecheck) Line 2578  if (newlinecheck)
2578  mainloop = LABEL();  mainloop = LABEL();
2579    
2580  /* Increasing the STR_PTR here requires one less jump in the most common case. */  /* Increasing the STR_PTR here requires one less jump in the most common case. */
2581  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2582  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2583  #endif  #endif
2584  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2585    
2586  if (readbyte)  if (readuchar)
2587    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2588    
2589  if (newlinecheck)  if (newlinecheck)
2590    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, newlinelabel);
2591    
2592  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));
2593  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2594  if (common->utf8)  #if defined COMPILE_PCRE8
2595    if (common->utf)
2596    {    {
2597    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2598    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2599    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2600    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
2601    }    }
2602  #endif  #elif defined COMPILE_PCRE16
2603    if (common->utf)
2604      {
2605      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2606      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2607      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2608      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2609      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2610      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2611      JUMPHERE(singlechar);
2612      }
2613    #endif /* COMPILE_PCRE[8|16] */
2614    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2615  JUMPHERE(start);  JUMPHERE(start);
2616    
2617  if (newlinecheck)  if (newlinecheck)
# Line 1701  if (newlinecheck) Line 2623  if (newlinecheck)
2623  return mainloop;  return mainloop;
2624  }  }
2625    
2626  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  #define MAX_N_CHARS 3
2627    
2628    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2629    {
2630    DEFINE_COMPILER;
2631    struct sljit_label *start;
2632    struct sljit_jump *quit;
2633    pcre_uint32 chars[MAX_N_CHARS * 2];
2634    pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2635    int location = 0;
2636    pcre_int32 len, c, bit, caseless;
2637    int must_stop;
2638    
2639    /* We do not support alternatives now. */
2640    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2641      return FALSE;
2642    
2643    while (TRUE)
2644      {
2645      caseless = 0;
2646      must_stop = 1;
2647      switch(*cc)
2648        {
2649        case OP_CHAR:
2650        must_stop = 0;
2651        cc++;
2652        break;
2653    
2654        case OP_CHARI:
2655        caseless = 1;
2656        must_stop = 0;
2657        cc++;
2658        break;
2659    
2660        case OP_SOD:
2661        case OP_SOM:
2662        case OP_SET_SOM:
2663        case OP_NOT_WORD_BOUNDARY:
2664        case OP_WORD_BOUNDARY:
2665        case OP_EODN:
2666        case OP_EOD:
2667        case OP_CIRC:
2668        case OP_CIRCM:
2669        case OP_DOLL:
2670        case OP_DOLLM:
2671        /* Zero width assertions. */
2672        cc++;
2673        continue;
2674    
2675        case OP_PLUS:
2676        case OP_MINPLUS:
2677        case OP_POSPLUS:
2678        cc++;
2679        break;
2680    
2681        case OP_EXACT:
2682        cc += 1 + IMM2_SIZE;
2683        break;
2684    
2685        case OP_PLUSI:
2686        case OP_MINPLUSI:
2687        case OP_POSPLUSI:
2688        caseless = 1;
2689        cc++;
2690        break;
2691    
2692        case OP_EXACTI:
2693        caseless = 1;
2694        cc += 1 + IMM2_SIZE;
2695        break;
2696    
2697        default:
2698        must_stop = 2;
2699        break;
2700        }
2701    
2702      if (must_stop == 2)
2703          break;
2704    
2705      len = 1;
2706    #ifdef SUPPORT_UTF
2707      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2708    #endif
2709    
2710      if (caseless && char_has_othercase(common, cc))
2711        {
2712        caseless = char_get_othercase_bit(common, cc);
2713        if (caseless == 0)
2714          return FALSE;
2715    #ifdef COMPILE_PCRE8
2716        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2717    #else
2718        if ((caseless & 0x100) != 0)
2719          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2720        else
2721          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2722    #endif
2723        }
2724      else
2725        caseless = 0;
2726    
2727      while (len > 0 && location < MAX_N_CHARS * 2)
2728        {
2729        c = *cc;
2730        bit = 0;
2731        if (len == (caseless & 0xff))
2732          {
2733          bit = caseless >> 8;
2734          c |= bit;
2735          }
2736    
2737        chars[location] = c;
2738        chars[location + 1] = bit;
2739    
2740        len--;
2741        location += 2;
2742        cc++;
2743        }
2744    
2745      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2746        break;
2747      }
2748    
2749    /* At least two characters are required. */
2750    if (location < 2 * 2)
2751        return FALSE;
2752    
2753    if (firstline)
2754      {
2755      SLJIT_ASSERT(common->first_line_end != 0);
2756      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2757      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2758      }
2759    else
2760      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2761    
2762    start = LABEL();
2763    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2764    
2765    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2766    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2767    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2768    if (chars[1] != 0)
2769      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2770    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2771    if (location > 2 * 2)
2772      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2773    if (chars[3] != 0)
2774      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2775    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2776    if (location > 2 * 2)
2777      {
2778      if (chars[5] != 0)
2779        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2780      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2781      }
2782    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2783    
2784    JUMPHERE(quit);
2785    
2786    if (firstline)
2787      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2788    else
2789      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2790    return TRUE;
2791    }
2792    
2793    #undef MAX_N_CHARS
2794    
2795    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2796  {  {
2797  DEFINE_COMPILER;  DEFINE_COMPILER;
2798  struct sljit_label *start;  struct sljit_label *start;
2799  struct sljit_jump *leave;  struct sljit_jump *quit;
2800  struct sljit_jump *found;  struct sljit_jump *found;
2801  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2802    
2803  if (firstline)  if (firstline)
2804    {    {
2805    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2806    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2807      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2808    }    }
2809    
2810  start = LABEL();  start = LABEL();
2811  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2812  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2813    
2814  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2815    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2816      {
2817      oc = TABLE_GET(first_char, common->fcc, first_char);
2818    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2819      if (first_char > 127 && common->utf)
2820        oc = UCD_OTHERCASE(first_char);
2821    #endif
2822      }
2823    if (first_char == oc)
2824      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2825  else  else
2826    {    {
2827    firstbyte &= 0xff;    bit = first_char ^ oc;
2828    oc = common->fcc[firstbyte];    if (is_powerof2(bit))
   bit = firstbyte ^ oc;  
   if (ispowerof2(bit))  
2829      {      {
2830      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2831      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2832      }      }
2833    else    else
2834      {      {
2835      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);
2836      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2837      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);
2838      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);
2839      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
2840      }      }
2841    }    }
2842    
2843  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #ifdef SUPPORT_UTF8  
 if (common->utf8)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2844  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2845  JUMPHERE(found);  JUMPHERE(found);
2846  JUMPHERE(leave);  JUMPHERE(quit);
2847    
2848  if (firstline)  if (firstline)
2849    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2850  }  }
2851    
2852  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 1764  DEFINE_COMPILER; Line 2855  DEFINE_COMPILER;
2855  struct sljit_label *loop;  struct sljit_label *loop;
2856  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2857  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2858  struct sljit_jump *leave;  struct sljit_jump *quit;
2859  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2860  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2861  jump_list *newline = NULL;  jump_list *newline = NULL;
2862    
2863  if (firstline)  if (firstline)
2864    {    {
2865    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2866    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2867      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2868    }    }
2869    
2870  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1783  if (common->nltype == NLTYPE_FIXED && co Line 2875  if (common->nltype == NLTYPE_FIXED && co
2875    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));
2876    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2877    
2878    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2879    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);
2880    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
2881    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2882      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2883    #endif
2884    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2885    
2886    loop = LABEL();    loop = LABEL();
2887    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));
2888    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2889    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2890    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2891    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);
2892    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);
2893    
2894    JUMPHERE(leave);    JUMPHERE(quit);
2895    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2896    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2897    
# Line 1820  set_jumps(newline, loop); Line 2915  set_jumps(newline, loop);
2915    
2916  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2917    {    {
2918    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2919    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2920    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2921    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2922    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);
2923    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2924    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2925      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2926    #endif
2927    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2928    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2929    JUMPHERE(leave);    JUMPHERE(quit);
2930    }    }
2931  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2932  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2933    
2934  if (firstline)  if (firstline)
2935    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2936  }  }
2937    
2938    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
2939    
2940  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)
2941  {  {
2942  DEFINE_COMPILER;  DEFINE_COMPILER;
2943  struct sljit_label *start;  struct sljit_label *start;
2944  struct sljit_jump *leave;  struct sljit_jump *quit;
2945  struct sljit_jump *found;  struct sljit_jump *found = NULL;
2946    jump_list *matches = NULL;
2947    pcre_uint8 inverted_start_bits[32];
2948    int i;
2949    #ifndef COMPILE_PCRE8
2950    struct sljit_jump *jump;
2951    #endif
2952    
2953    for (i = 0; i < 32; ++i)
2954      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
2955    
2956  if (firstline)  if (firstline)
2957    {    {
2958    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2959    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2960      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2961    }    }
2962    
2963  start = LABEL();  start = LABEL();
2964  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2965  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2966  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2967  if (common->utf8)  if (common->utf)
2968    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2969  #endif  #endif
 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  
 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  
 OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);  
 OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);  
 found = JUMP(SLJIT_C_NOT_ZERO);  
2970    
2971  #ifdef SUPPORT_UTF8  if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
2972  if (common->utf8)    {
2973    #ifndef COMPILE_PCRE8
2974      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2975      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2976      JUMPHERE(jump);
2977    #endif
2978      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2979      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2980      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2981      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2982      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
2983      found = JUMP(SLJIT_C_NOT_ZERO);
2984      }
2985    
2986    #ifdef SUPPORT_UTF
2987    if (common->utf)
2988    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2989  #endif  #endif
2990  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));
2991  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2992  if (common->utf8)  #if defined COMPILE_PCRE8
2993    if (common->utf)
2994    {    {
2995    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2996    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2997    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2998    }    }
2999  #endif  #elif defined COMPILE_PCRE16
3000    if (common->utf)
3001      {
3002      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
3003      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3004      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3005      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3006      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3007      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3008      }
3009    #endif /* COMPILE_PCRE[8|16] */
3010    #endif /* SUPPORT_UTF */
3011  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3012  JUMPHERE(found);  if (found != NULL)
3013  JUMPHERE(leave);    JUMPHERE(found);
3014    if (matches != NULL)
3015      set_jumps(matches, LABEL());
3016    JUMPHERE(quit);
3017    
3018  if (firstline)  if (firstline)
3019    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
3020  }  }
3021    
3022  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)
3023  {  {
3024  DEFINE_COMPILER;  DEFINE_COMPILER;
3025  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1894  struct sljit_jump *alreadyfound; Line 3028  struct sljit_jump *alreadyfound;
3028  struct sljit_jump *found;  struct sljit_jump *found;
3029  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
3030  struct sljit_jump *notfound;  struct sljit_jump *notfound;
3031  pcre_uint16 oc, bit;  pcre_uint32 oc, bit;
3032    
3033  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
3034    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
3035  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);
3036  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
3037  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
3038    
3039  if (has_firstbyte)  if (has_firstchar)
3040    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3041  else  else
3042    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
3043    
3044  loop = LABEL();  loop = LABEL();
3045  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
3046    
3047  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3048  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
3049    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
3050      {
3051      oc = TABLE_GET(req_char, common->fcc, req_char);
3052    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
3053      if (req_char > 127 && common->utf)
3054        oc = UCD_OTHERCASE(req_char);
3055    #endif
3056      }
3057    if (req_char == oc)
3058      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
3059  else  else
3060    {    {
3061    reqbyte &= 0xff;    bit = req_char ^ oc;
3062    oc = common->fcc[reqbyte];    if (is_powerof2(bit))
   bit = reqbyte ^ oc;  
   if (ispowerof2(bit))  
3063      {      {
3064      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3065      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
3066      }      }
3067    else    else
3068      {      {
3069      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
3070      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
3071      }      }
3072    }    }
3073  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3074  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
3075    
3076  JUMPHERE(found);  JUMPHERE(found);
3077  if (foundoc)  if (foundoc)
3078    JUMPHERE(foundoc);    JUMPHERE(foundoc);
3079  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);
3080  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
3081  JUMPHERE(toolong);  JUMPHERE(toolong);
3082  return notfound;  return notfound;
# Line 1946  DEFINE_COMPILER; Line 3088  DEFINE_COMPILER;
3088  struct sljit_jump *jump;  struct sljit_jump *jump;
3089  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3090    
3091  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3092  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3093    GET_LOCAL_BASE(TMP3, 0, 0);
3094    
3095  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3096  mainloop = LABEL();  mainloop = LABEL();
3097  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3098  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
3099  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3100  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
3101  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3102  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3103    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3104    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
3105  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3106    
3107  JUMPHERE(jump);  JUMPHERE(jump);
3108  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3109  /* End of dropping frames. */  /* End of dropping frames. */
3110  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3111    
3112  JUMPHERE(jump);  JUMPHERE(jump);
3113  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3114  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3115  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3116  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));
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
 /* Unknown command. */  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
3117  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3118  }  }
3119    
3120  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3121  {  {
3122  DEFINE_COMPILER;  DEFINE_COMPILER;
3123  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3124  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3125  struct sljit_jump *jump;  struct sljit_jump *jump;
3126  #endif  #endif
3127    
3128  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3129    
3130  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);
3131  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3132  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3133  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));
3134  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3135  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3136  skip_char_back(common);  skip_char_back(common);
3137    check_start_used_ptr(common);
3138  read_char(common);  read_char(common);
3139    
3140  /* Testing char type. */  /* Testing char type. */
3141  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3142  if (common->useucp)  if (common->use_ucp)
3143    {    {
3144    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3145    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3146    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3147    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3148    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);
3149    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3150    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);
3151    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);
3152    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3153    JUMPHERE(jump);    JUMPHERE(jump);
3154    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3155    }    }
3156  else  else
3157  #endif  #endif
3158    {    {
3159  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3160      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3161    #elif defined SUPPORT_UTF
3162    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3163    jump = NULL;    jump = NULL;
3164    if (common->utf8)    if (common->utf)
3165      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3166  #endif  #endif /* COMPILE_PCRE8 */
3167    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3168    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3169    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3170    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3171  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3172      JUMPHERE(jump);
3173    #elif defined SUPPORT_UTF
3174    if (jump != NULL)    if (jump != NULL)
3175      JUMPHERE(jump);      JUMPHERE(jump);
3176  #endif  #endif /* COMPILE_PCRE8 */
3177    }    }
3178  JUMPHERE(beginend);  JUMPHERE(skipread);
3179    
3180  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3181  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3182  peek_char(common);  peek_char(common);
3183    
3184  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3185  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3186  if (common->useucp)  if (common->use_ucp)
3187    {    {
3188    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3189    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3190    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3191    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3192    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);
3193    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3194    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);
3195    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);
3196    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3197    JUMPHERE(jump);    JUMPHERE(jump);
3198    }    }
3199  else  else
3200  #endif  #endif
3201    {    {
3202  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3203      /* TMP2 may be destroyed by peek_char. */
3204      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3205      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3206    #elif defined SUPPORT_UTF
3207    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3208    jump = NULL;    jump = NULL;
3209    if (common->utf8)    if (common->utf)
3210      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3211  #endif  #endif
3212    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3213    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3214    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3215  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3216      JUMPHERE(jump);
3217    #elif defined SUPPORT_UTF
3218    if (jump != NULL)    if (jump != NULL)
3219      JUMPHERE(jump);      JUMPHERE(jump);
3220  #endif  #endif /* COMPILE_PCRE8 */
3221    }    }
3222  JUMPHERE(beginend);  JUMPHERE(skipread);
3223    
3224  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);
3225  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3226  }  }
3227    
3228    /*
3229      range format:
3230    
3231      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3232      ranges[1] = first bit (0 or 1)
3233      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3234    */
3235    
3236    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3237    {
3238    DEFINE_COMPILER;
3239    struct sljit_jump *jump;
3240    
3241    if (ranges[0] < 0)
3242      return FALSE;
3243    
3244    switch(ranges[0])
3245      {
3246      case 1:
3247      if (readch)
3248        read_char(common);
3249      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3250      return TRUE;
3251    
3252      case 2:
3253      if (readch)
3254        read_char(common);
3255      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3256      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3257      return TRUE;
3258    
3259      case 4:
3260      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3261        {
3262        if (readch)
3263          read_char(common);
3264        if (ranges[1] != 0)
3265          {
3266          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3267          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3268          }
3269        else
3270          {
3271          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3272          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3273          JUMPHERE(jump);
3274          }
3275        return TRUE;
3276        }
3277      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3278        {
3279        if (readch)
3280          read_char(common);
3281        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3282        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3283        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3284        return TRUE;
3285        }
3286      return FALSE;
3287    
3288      default:
3289      return FALSE;
3290      }
3291    }
3292    
3293    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3294    {
3295    int i, bit, length;
3296    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3297    
3298    bit = ctypes[0] & flag;
3299    ranges[0] = -1;
3300    ranges[1] = bit != 0 ? 1 : 0;
3301    length = 0;
3302    
3303    for (i = 1; i < 256; i++)
3304      if ((ctypes[i] & flag) != bit)
3305        {
3306        if (length >= MAX_RANGE_SIZE)
3307          return;
3308        ranges[2 + length] = i;
3309        length++;
3310        bit ^= flag;
3311        }
3312    
3313    if (bit != 0)
3314      {
3315      if (length >= MAX_RANGE_SIZE)
3316        return;
3317      ranges[2 + length] = 256;
3318      length++;
3319      }
3320    ranges[0] = length;
3321    }
3322    
3323    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3324    {
3325    int ranges[2 + MAX_RANGE_SIZE];
3326    pcre_uint8 bit, cbit, all;
3327    int i, byte, length = 0;
3328    
3329    bit = bits[0] & 0x1;
3330    ranges[1] = bit;
3331    /* Can be 0 or 255. */
3332    all = -bit;
3333    
3334    for (i = 0; i < 256; )
3335      {
3336      byte = i >> 3;
3337      if ((i & 0x7) == 0 && bits[byte] == all)
3338        i += 8;
3339      else
3340        {
3341        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3342        if (cbit != bit)
3343          {
3344          if (length >= MAX_RANGE_SIZE)
3345            return FALSE;
3346          ranges[2 + length] = i;
3347          length++;
3348          bit = cbit;
3349          all = -cbit;
3350          }
3351        i++;
3352        }
3353      }
3354    
3355    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3356      {
3357      if (length >= MAX_RANGE_SIZE)
3358        return FALSE;
3359      ranges[2 + length] = 256;
3360      length++;
3361      }
3362    ranges[0] = length;
3363    
3364    return check_ranges(common, ranges, backtracks, FALSE);
3365    }
3366    
3367  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3368  {  {
3369  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3370  DEFINE_COMPILER;  DEFINE_COMPILER;
3371    
3372  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3373    
3374  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3375  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);
3376  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3377  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);
3378  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3379  if (common->utf8)  #ifdef COMPILE_PCRE8
3380    if (common->utf)
3381    {    {
3382    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  #endif
3383      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3384    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3385    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);
3386    #ifdef COMPILE_PCRE8
3387    }    }
3388  #endif  #endif
3389  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3390    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3391  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3392  }  }
3393    
# Line 2103  static void check_hspace(compiler_common Line 3396  static void check_hspace(compiler_common
3396  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3397  DEFINE_COMPILER;  DEFINE_COMPILER;
3398    
3399  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3400    
3401  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);
3402  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3403  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);
3404  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3405  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);
3406  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3407  if (common->utf8)  #ifdef COMPILE_PCRE8
3408    if (common->utf)
3409    {    {
3410    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  #endif
3411      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3412    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);
3413    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3414    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);
3415    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3416    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3417    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);
3418    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3419    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);
3420    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3421    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);
3422    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3423    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);
3424    #ifdef COMPILE_PCRE8
3425    }    }
3426  #endif  #endif
3427  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3428    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3429    
3430  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3431  }  }
# Line 2138  static void check_vspace(compiler_common Line 3435  static void check_vspace(compiler_common
3435  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3436  DEFINE_COMPILER;  DEFINE_COMPILER;
3437    
3438  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3439    
3440  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3441  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);
3442  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3443  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);
3444  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3445  if (common->utf8)  #ifdef COMPILE_PCRE8
3446    if (common->utf)
3447    {    {
3448    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif
3449      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3450    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3451    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);
3452    #ifdef COMPILE_PCRE8
3453    }    }
3454  #endif  #endif
3455  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3456    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3457    
3458  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3459  }  }
# Line 2166  DEFINE_COMPILER; Line 3467  DEFINE_COMPILER;
3467  struct sljit_jump *jump;  struct sljit_jump *jump;
3468  struct sljit_label *label;  struct sljit_label *label;
3469    
3470  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3471  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3472  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3473  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3474  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3475  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));
3476    
3477  label = LABEL();  label = LABEL();
3478  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3479  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3480  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3481  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));
3482  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3483    
3484  JUMPHERE(jump);  JUMPHERE(jump);
3485  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));
3486  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3487  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3488  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2195  DEFINE_COMPILER; Line 3496  DEFINE_COMPILER;
3496  struct sljit_jump *jump;  struct sljit_jump *jump;
3497  struct sljit_label *label;  struct sljit_label *label;
3498    
3499  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3500  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3501    
3502  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3503  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3504  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3505  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3506  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3507  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));
3508    
3509  label = LABEL();  label = LABEL();
3510  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3511  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3512    #ifndef COMPILE_PCRE8
3513    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3514    #endif
3515  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3516    #ifndef COMPILE_PCRE8
3517    JUMPHERE(jump);
3518    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3519    #endif
3520  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3521    #ifndef COMPILE_PCRE8
3522    JUMPHERE(jump);
3523    #endif
3524  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3525  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));
3526  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3527    
3528  JUMPHERE(jump);  JUMPHERE(jump);
3529  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));
3530  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3531  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3532  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2226  sljit_emit_fast_return(compiler, RETURN_ Line 3537  sljit_emit_fast_return(compiler, RETURN_
3537  #undef CHAR1  #undef CHAR1
3538  #undef CHAR2  #undef CHAR2
3539    
3540  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3541    
3542  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)
3543  {  {
3544  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3545  int c1, c2;  pcre_uint32 c1, c2;
3546  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3547  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3548    const ucd_record *ur;
3549    const pcre_uint32 *pp;
3550    
3551  while (src1 < end1)  while (src1 < end1)
3552    {    {
3553    if (src2 >= end2)    if (src2 >= end2)
3554      return 0;      return (pcre_uchar*)1;
3555    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3556    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3557    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    ur = GET_UCD(c2);
3558      if (c1 != c2 && c1 != c2 + ur->other_case)
3559        {
3560        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3561        for (;;)
3562          {
3563          if (c1 < *pp) return NULL;
3564          if (c1 == *pp++) break;
3565          }
3566        }
3567    }    }
3568  return src2;  return src2;
3569  }  }
3570    
3571  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3572    
3573  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,
3574      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3575  {  {
3576  DEFINE_COMPILER;  DEFINE_COMPILER;
3577  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3578  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3579  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3580  int utf8length;  int utflength;
3581  #endif  #endif
3582    
3583  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2265  if (caseless && char_has_othercase(commo Line 3585  if (caseless && char_has_othercase(commo
3585    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3586    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3587    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3588    othercasebyte = cc + (othercasebit >> 8);  #if defined COMPILE_PCRE8
3589      othercasechar = cc + (othercasebit >> 8);
3590    othercasebit &= 0xff;    othercasebit &= 0xff;
3591    #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3592      /* Note that this code only handles characters in the BMP. If there
3593      ever are characters outside the BMP whose othercase differs in only one
3594      bit from itself (there currently are none), this code will need to be
3595      revised for COMPILE_PCRE32. */
3596      othercasechar = cc + (othercasebit >> 9);
3597      if ((othercasebit & 0x100) != 0)
3598        othercasebit = (othercasebit & 0xff) << 8;
3599      else
3600        othercasebit &= 0xff;
3601    #endif /* COMPILE_PCRE[8|16|32] */
3602    }    }
3603    
3604  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3605    {    {
3606    #if defined COMPILE_PCRE8
3607  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3608    if (context->length >= 4)    if (context->length >= 4)
3609      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3610    else if (context->length >= 2)    else if (context->length >= 2)
3611      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3612    else    else
3613  #endif  #endif
3614      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3615    #elif defined COMPILE_PCRE16
3616    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3617      if (context->length >= 4)
3618        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3619      else
3620    #endif
3621        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3622    #elif defined COMPILE_PCRE32
3623      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3624    #endif /* COMPILE_PCRE[8|16|32] */
3625    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3626    }    }
3627    
3628  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3629  utf8length = 1;  utflength = 1;
3630  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3631    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3632    
3633  do  do
3634    {    {
3635  #endif  #endif
3636    
3637    context->length--;    context->length -= IN_UCHARS(1);
3638  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3639    
3640    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3641    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3642      {      {
3643      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3644      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3645      }      }
3646    else    else
3647      {      {
3648      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3649      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3650      }      }
3651    context->byteptr++;    context->ucharptr++;
3652    
3653    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #if defined COMPILE_PCRE8
3654      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3655    #else
3656      if (context->ucharptr >= 2 || context->length == 0)
3657    #endif
3658      {      {
3659      if (context->length >= 4)      if (context->length >= 4)
3660        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);
3661      else if (context->length >= 2)      else if (context->length >= 2)
3662        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);
3663    #if defined COMPILE_PCRE8
3664      else if (context->length >= 1)      else if (context->length >= 1)
3665        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);
3666    #endif /* COMPILE_PCRE8 */
3667      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3668    
3669      switch(context->byteptr)      switch(context->ucharptr)
3670        {        {
3671        case 4:        case 4 / sizeof(pcre_uchar):
3672        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3673          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
3674        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3675        break;        break;
3676    
3677        case 2:        case 2 / sizeof(pcre_uchar):
3678        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3679          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asshort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
3680        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asshort | context->oc.asshort));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
3681        break;        break;