/[pcre]/code/tags/pcre-8.37/pcre_jit_compile.c
ViewVC logotype

Diff of /code/tags/pcre-8.37/pcre_jit_compile.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 715 by zherczeg, Sat Oct 1 06:42:38 2011 UTC revision 1282 by zherczeg, Fri Mar 15 08:01:41 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-2013 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-2013
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* 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    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77    /* Allocate memory for the regex stack on the real machine stack.
78    Fast, but limited size. */
79    #define MACHINE_STACK_SIZE 32768
80    
81    /* Growth rate for stack allocated by the OS. Should be the multiply
82    of page size. */
83  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
84    
85  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 79  The code generator follows the recursive Line 94  The code generator follows the recursive
94  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
95  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
96  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
97  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
98    
99    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
100    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
101    
102  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
103  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.
104  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
105  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
106  branches on the hot path.  branches on the matching path.
107    
108   Greedy star operator (*) :   Greedy star operator (*) :
109     Hot path: match happens.     Matching path: match happens.
110     Fallback path: match failed.     Backtrack path: match failed.
111   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
112     Hot path: no need to perform a match.     Matching path: no need to perform a match.
113     Fallback path: match is required.     Backtrack path: match is required.
114    
115  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
116  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# Line 105  we have the following regular expression Line 120  we have the following regular expression
120    
121  The generated code will be the following:  The generated code will be the following:
122    
123   A hot path   A matching path
124   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
125   B hot path   B matching path
126   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
127   D hot path   D matching path
128   return with successful match   return with successful match
129    
130   D fallback path   D backtrack path
131   ')' 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")
132   B fallback path   B backtrack path
133   C expected path   C expected path
134   jump to D hot path   jump to D matching path
135   C fallback path   C backtrack path
136   A fallback path   A backtrack path
137    
138   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
139   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
140   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
141   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
142   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
143   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
144  */  */
145    
146  /*  /*
147  Saved stack frames:  Saved stack frames:
148    
149  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
150  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
151  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
152  mechanism.  mechanism.
153    
154  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:
155  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
156    
157  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.
158  */  */
159    
160  typedef struct jit_arguments {  typedef struct jit_arguments {
161    /* Pointers first. */    /* Pointers first. */
162    struct sljit_stack *stack;    struct sljit_stack *stack;
163    PCRE_SPTR str;    const pcre_uchar *str;
164    PCRE_SPTR begin;    const pcre_uchar *begin;
165    PCRE_SPTR end;    const pcre_uchar *end;
166    int *offsets;    int *offsets;
167    uschar *ptr;    pcre_uchar *uchar_ptr;
168      pcre_uchar *mark_ptr;
169      void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171    int offsetcount;    int real_offset_count;
172    int calllimit;    int offset_count;
173    uschar notbol;    int call_limit;
174    uschar noteol;    pcre_uint8 notbol;
175    uschar notempty;    pcre_uint8 noteol;
176    uschar notempty_atstart;    pcre_uint8 notempty;
177      pcre_uint8 notempty_atstart;
178  } jit_arguments;  } jit_arguments;
179    
180  typedef struct executable_function {  typedef struct executable_functions {
181    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182    pcre_jit_callback callback;    PUBL(jit_callback) callback;
183    void *userdata;    void *userdata;
184  } executable_function;    pcre_uint32 top_bracket;
185      sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
186    } executable_functions;
187    
188  typedef struct jump_list {  typedef struct jump_list {
189    struct sljit_jump *jump;    struct sljit_jump *jump;
190    struct jump_list *next;    struct jump_list *next;
191  } jump_list;  } jump_list;
192    
 enum stub_types { stack_alloc };  
   
193  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   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    enum bytecode_flag_types {
200      flag_optimized_cbracket = 1,
201      flag_then_start = 2,
202    };
203    
204    enum frame_types {
205      no_frame = -1,
206      no_stack = -2
207    };
208    
209    enum control_types {
210      type_commit = 0,
211      type_prune = 1,
212      type_skip = 2,
213      type_skip_arg = 3,
214      type_mark = 4,
215      type_then_trap = 5
216    };
217    
218  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
219    
220  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
221  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
222  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
223  of its descendants. */  of its descendants. */
224  typedef struct fallback_common {  typedef struct backtrack_common {
225    /* Concatenation stack. */    /* Concatenation stack. */
226    struct fallback_common *prev;    struct backtrack_common *prev;
227    jump_list *nextfallbacks;    jump_list *nextbacktracks;
228    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
229    struct fallback_common *top;    struct backtrack_common *top;
230    jump_list *topfallbacks;    jump_list *topbacktracks;
231    /* Opcode pointer. */    /* Opcode pointer. */
232    uschar *cc;    pcre_uchar *cc;
233  } fallback_common;  } backtrack_common;
234    
235  typedef struct assert_fallback {  typedef struct assert_backtrack {
236    fallback_common common;    backtrack_common common;
237    jump_list *condfailed;    jump_list *condfailed;
238    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
239    int framesize;    int framesize;
240    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
241    int localptr;    int private_data_ptr;
242    /* For iterators. */    /* For iterators. */
243    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
244  } assert_fallback;  } assert_backtrack;
245    
246  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
247    fallback_common common;    backtrack_common common;
248    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
249    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
250    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
251    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
252    /* For greedy ? operator. */    /* For greedy ? operator. */
253    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
254    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
255    union {    union {
256      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
257      jump_list *condfailed;      jump_list *condfailed;
258      assert_fallback *assert;      assert_backtrack *assert;
259      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
260      int framesize;      int framesize;
261    } u;    } u;
262    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
263    int localptr;    int private_data_ptr;
264  } bracket_fallback;  } bracket_backtrack;
265    
266  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
267    fallback_common common;    backtrack_common common;
268    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
269    int localptr;    int private_data_ptr;
270    /* Reverting stack is needed. */    /* Reverting stack is needed. */
271    int framesize;    int framesize;
272    /* Allocated stack size. */    /* Allocated stack size. */
273    int stacksize;    int stacksize;
274  } bracketpos_fallback;  } bracketpos_backtrack;
275    
276  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
277    fallback_common common;    backtrack_common common;
278    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
279  } braminzero_fallback;  } braminzero_backtrack;
280    
281  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
282    fallback_common common;    backtrack_common common;
283    /* Next iteration. */    /* Next iteration. */
284    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
285  } iterator_fallback;  } iterator_backtrack;
286    
287  typedef struct recurse_entry {  typedef struct recurse_entry {
288    struct recurse_entry *next;    struct recurse_entry *next;
# Line 256  typedef struct recurse_entry { Line 291  typedef struct recurse_entry {
291    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
292    jump_list *calls;    jump_list *calls;
293    /* Points to the starting opcode. */    /* Points to the starting opcode. */
294    int start;    sljit_sw start;
295  } recurse_entry;  } recurse_entry;
296    
297  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
298    fallback_common common;    backtrack_common common;
299  } recurse_fallback;    BOOL inlined_pattern;
300    } recurse_backtrack;
301    
302    #define OP_THEN_TRAP OP_TABLE_LENGTH
303    
304    typedef struct then_trap_backtrack {
305      backtrack_common common;
306      /* If then_trap is not NULL, this structure contains the real
307      then_trap for the backtracking path. */
308      struct then_trap_backtrack *then_trap;
309      /* Points to the starting opcode. */
310      sljit_sw start;
311      /* Exit point for the then opcodes of this alternative. */
312      jump_list *quit;
313      /* Frame size of the current alternative. */
314      int framesize;
315    } then_trap_backtrack;
316    
317    #define MAX_RANGE_SIZE 6
318    
319  typedef struct compiler_common {  typedef struct compiler_common {
320      /* The sljit ceneric compiler. */
321    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
322    uschar *start;    /* First byte code. */
323    int localsize;    pcre_uchar *start;
324    int *localptrs;    /* Maps private data offset to each opcode. */
325    const uschar *fcc;    int *private_data_ptrs;
326    sljit_w lcc;    /* Tells whether the capturing bracket is optimized. */
327    int cbraptr;    pcre_uint8 *optimized_cbracket;
328      /* Tells whether the starting offset is a target of then. */
329      pcre_uint8 *then_offsets;
330      /* Current position where a THEN must jump. */
331      then_trap_backtrack *then_trap;
332      /* Starting offset of private data for capturing brackets. */
333      int cbra_ptr;
334      /* Output vector starting point. Must be divisible by 2. */
335      int ovector_start;
336      /* Last known position of the requested byte. */
337      int req_char_ptr;
338      /* Head of the last recursion. */
339      int recursive_head_ptr;
340      /* First inspected character for partial matching. */
341      int start_used_ptr;
342      /* Starting pointer for partial soft matches. */
343      int hit_start;
344      /* End pointer of the first line. */
345      int first_line_end;
346      /* Points to the marked string. */
347      int mark_ptr;
348      /* Recursive control verb management chain. */
349      int control_head_ptr;
350      /* Points to the last matched capture block index. */
351      int capture_last_ptr;
352      /* Points to the starting position of the current match. */
353      int start_ptr;
354    
355      /* Flipped and lower case tables. */
356      const pcre_uint8 *fcc;
357      sljit_sw lcc;
358      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
359      int mode;
360      /* \K is found in the pattern. */
361      BOOL has_set_som;
362      /* (*SKIP:arg) is found in the pattern. */
363      BOOL has_skip_arg;
364      /* (*THEN) is found in the pattern. */
365      BOOL has_then;
366      /* Needs to know the start position anytime. */
367      BOOL needs_start_ptr;
368      /* Currently in recurse or assert. */
369      BOOL local_exit;
370      /* Newline control. */
371    int nltype;    int nltype;
372    int newline;    int newline;
373    int bsr_nltype;    int bsr_nltype;
374      /* Dollar endonly. */
375    int endonly;    int endonly;
376    sljit_w ctypes;    /* Tables. */
377    struct sljit_label *acceptlabel;    sljit_sw ctypes;
378      int digits[2 + MAX_RANGE_SIZE];
379      /* Named capturing brackets. */
380      sljit_uw name_table;
381      sljit_sw name_count;
382      sljit_sw name_entry_size;
383    
384      /* Labels and jump lists. */
385      struct sljit_label *partialmatchlabel;
386      struct sljit_label *quit_label;
387      struct sljit_label *forced_quit_label;
388      struct sljit_label *accept_label;
389    stub_list *stubs;    stub_list *stubs;
390    recurse_entry *entries;    recurse_entry *entries;
391    recurse_entry *currententry;    recurse_entry *currententry;
392      jump_list *partialmatch;
393      jump_list *quit;
394      jump_list *forced_quit;
395    jump_list *accept;    jump_list *accept;
396    jump_list *calllimit;    jump_list *calllimit;
397    jump_list *stackalloc;    jump_list *stackalloc;
# Line 290  typedef struct compiler_common { Line 402  typedef struct compiler_common {
402    jump_list *vspace;    jump_list *vspace;
403    jump_list *casefulcmp;    jump_list *casefulcmp;
404    jump_list *caselesscmp;    jump_list *caselesscmp;
405      jump_list *reset_match;
406    BOOL jscript_compat;    BOOL jscript_compat;
407  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
408    BOOL utf8;    BOOL utf;
409  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
410    BOOL useucp;    BOOL use_ucp;
411    #endif
412    #ifndef COMPILE_PCRE32
413      jump_list *utfreadchar;
414  #endif  #endif
415    jump_list *utf8readchar;  #ifdef COMPILE_PCRE8
416    jump_list *utf8readtype8;    jump_list *utfreadtype8;
417  #endif  #endif
418    #endif /* SUPPORT_UTF */
419  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
420    jump_list *getucd;    jump_list *getucd;
421  #endif  #endif
# Line 310  typedef struct compare_context { Line 427  typedef struct compare_context {
427    int length;    int length;
428    int sourcereg;    int sourcereg;
429  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
430    int byteptr;    int ucharptr;
431    union {    union {
432      int asint;      sljit_si asint;
433      short asshort;      sljit_uh asushort;
434    #if defined COMPILE_PCRE8
435      sljit_ub asbyte;      sljit_ub asbyte;
436      sljit_ub asbytes[4];      sljit_ub asuchars[4];
437    #elif defined COMPILE_PCRE16
438        sljit_uh asuchars[2];
439    #elif defined COMPILE_PCRE32
440        sljit_ui asuchars[1];
441    #endif
442    } c;    } c;
443    union {    union {
444      int asint;      sljit_si asint;
445      short asshort;      sljit_uh asushort;
446    #if defined COMPILE_PCRE8
447      sljit_ub asbyte;      sljit_ub asbyte;
448      sljit_ub asbytes[4];      sljit_ub asuchars[4];
449    #elif defined COMPILE_PCRE16
450        sljit_uh asuchars[2];
451    #elif defined COMPILE_PCRE32
452        sljit_ui asuchars[1];
453    #endif
454    } oc;    } oc;
455  #endif  #endif
456  } compare_context;  } compare_context;
457    
458  enum {  /* Undefine sljit macros. */
459    frame_end = 0,  #undef CMP
   frame_setstrbegin = -1  
 };  
460    
461  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
462  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
463    
464  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
465  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
466  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
467  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
468  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
469  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
470  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
471  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
472  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
473  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
474    
475  /* Locals layout. */  /* Local space layout. */
476  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
477  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
478  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
479  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
480  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
481  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
 /* Head of the saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  
482  /* Max limit of recursions. */  /* Max limit of recursions. */
483  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * sizeof(sljit_w))  
484  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
485  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
486  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
487  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. */
488  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
489  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
490  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
491  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
492    
493    #if defined COMPILE_PCRE8
494    #define MOV_UCHAR  SLJIT_MOV_UB
495    #define MOVU_UCHAR SLJIT_MOVU_UB
496    #elif defined COMPILE_PCRE16
497    #define MOV_UCHAR  SLJIT_MOV_UH
498    #define MOVU_UCHAR SLJIT_MOVU_UH
499    #elif defined COMPILE_PCRE32
500    #define MOV_UCHAR  SLJIT_MOV_UI
501    #define MOVU_UCHAR SLJIT_MOVU_UI
502    #else
503    #error Unsupported compiling mode
504    #endif
505    
506  /* Shortcuts. */  /* Shortcuts. */
507  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 386  the start pointers when the end of the c Line 518  the start pointers when the end of the c
518    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
519  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
520    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
521    #define SET_LABEL(jump, label) \
522      sljit_set_label((jump), (label))
523  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
524    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
525  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
526    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))
527  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
528    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
529    #define GET_LOCAL_BASE(dst, dstw, offset) \
530      sljit_get_local_base(compiler, (dst), (dstw), (offset))
531    
532  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
533  {  {
534  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));
535  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 404  return cc; Line 540  return cc;
540    
541  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
542   next_opcode   next_opcode
543   get_localspace   get_private_data_length
544   set_localptrs   set_private_data_ptrs
545   get_framesize   get_framesize
546   init_frame   init_frame
547   get_localsize   get_private_data_copy_length
548   copy_locals   copy_private_data
549   compile_hotpath   compile_matchingpath
550   compile_fallbackpath   compile_backtrackingpath
551  */  */
552    
553  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
554  {  {
555  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
556  switch(*cc)  switch(*cc)
# Line 432  switch(*cc) Line 568  switch(*cc)
568    case OP_WORDCHAR:    case OP_WORDCHAR:
569    case OP_ANY:    case OP_ANY:
570    case OP_ALLANY:    case OP_ALLANY:
571      case OP_NOTPROP:
572      case OP_PROP:
573    case OP_ANYNL:    case OP_ANYNL:
574    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
575    case OP_HSPACE:    case OP_HSPACE:
# Line 444  switch(*cc) Line 582  switch(*cc)
582    case OP_CIRCM:    case OP_CIRCM:
583    case OP_DOLL:    case OP_DOLL:
584    case OP_DOLLM:    case OP_DOLLM:
   case OP_TYPESTAR:  
   case OP_TYPEMINSTAR:  
   case OP_TYPEPLUS:  
   case OP_TYPEMINPLUS:  
   case OP_TYPEQUERY:  
   case OP_TYPEMINQUERY:  
   case OP_TYPEPOSSTAR:  
   case OP_TYPEPOSPLUS:  
   case OP_TYPEPOSQUERY:  
585    case OP_CRSTAR:    case OP_CRSTAR:
586    case OP_CRMINSTAR:    case OP_CRMINSTAR:
587    case OP_CRPLUS:    case OP_CRPLUS:
588    case OP_CRMINPLUS:    case OP_CRMINPLUS:
589    case OP_CRQUERY:    case OP_CRQUERY:
590    case OP_CRMINQUERY:    case OP_CRMINQUERY:
591      case OP_CRRANGE:
592      case OP_CRMINRANGE:
593      case OP_CLASS:
594      case OP_NCLASS:
595      case OP_REF:
596      case OP_REFI:
597      case OP_RECURSE:
598      case OP_CALLOUT:
599      case OP_ALT:
600      case OP_KET:
601      case OP_KETRMAX:
602      case OP_KETRMIN:
603      case OP_KETRPOS:
604      case OP_REVERSE:
605      case OP_ASSERT:
606      case OP_ASSERT_NOT:
607      case OP_ASSERTBACK:
608      case OP_ASSERTBACK_NOT:
609      case OP_ONCE:
610      case OP_ONCE_NC:
611      case OP_BRA:
612      case OP_BRAPOS:
613      case OP_CBRA:
614      case OP_CBRAPOS:
615      case OP_COND:
616      case OP_SBRA:
617      case OP_SBRAPOS:
618      case OP_SCBRA:
619      case OP_SCBRAPOS:
620      case OP_SCOND:
621      case OP_CREF:
622      case OP_NCREF:
623      case OP_RREF:
624      case OP_NRREF:
625    case OP_DEF:    case OP_DEF:
626    case OP_BRAZERO:    case OP_BRAZERO:
627    case OP_BRAMINZERO:    case OP_BRAMINZERO:
628    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
629      case OP_PRUNE:
630      case OP_SKIP:
631      case OP_THEN:
632      case OP_COMMIT:
633    case OP_FAIL:    case OP_FAIL:
634    case OP_ACCEPT:    case OP_ACCEPT:
635    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
636      case OP_CLOSE:
637    case OP_SKIPZERO:    case OP_SKIPZERO:
638    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
639    
640    case OP_CHAR:    case OP_CHAR:
641    case OP_CHARI:    case OP_CHARI:
642    case OP_NOT:    case OP_NOT:
643    case OP_NOTI:    case OP_NOTI:
   
644    case OP_STAR:    case OP_STAR:
645    case OP_MINSTAR:    case OP_MINSTAR:
646    case OP_PLUS:    case OP_PLUS:
647    case OP_MINPLUS:    case OP_MINPLUS:
648    case OP_QUERY:    case OP_QUERY:
649    case OP_MINQUERY:    case OP_MINQUERY:
650      case OP_UPTO:
651      case OP_MINUPTO:
652      case OP_EXACT:
653    case OP_POSSTAR:    case OP_POSSTAR:
654    case OP_POSPLUS:    case OP_POSPLUS:
655    case OP_POSQUERY:    case OP_POSQUERY:
656      case OP_POSUPTO:
657    case OP_STARI:    case OP_STARI:
658    case OP_MINSTARI:    case OP_MINSTARI:
659    case OP_PLUSI:    case OP_PLUSI:
660    case OP_MINPLUSI:    case OP_MINPLUSI:
661    case OP_QUERYI:    case OP_QUERYI:
662    case OP_MINQUERYI:    case OP_MINQUERYI:
663      case OP_UPTOI:
664      case OP_MINUPTOI:
665      case OP_EXACTI:
666    case OP_POSSTARI:    case OP_POSSTARI:
667    case OP_POSPLUSI:    case OP_POSPLUSI:
668    case OP_POSQUERYI:    case OP_POSQUERYI:
669      case OP_POSUPTOI:
670    case OP_NOTSTAR:    case OP_NOTSTAR:
671    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
672    case OP_NOTPLUS:    case OP_NOTPLUS:
673    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
674    case OP_NOTQUERY:    case OP_NOTQUERY:
675    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
676      case OP_NOTUPTO:
677      case OP_NOTMINUPTO:
678      case OP_NOTEXACT:
679    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
680    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
681    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
682      case OP_NOTPOSUPTO:
683    case OP_NOTSTARI:    case OP_NOTSTARI:
684    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
685    case OP_NOTPLUSI:    case OP_NOTPLUSI:
686    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
687    case OP_NOTQUERYI:    case OP_NOTQUERYI:
688    case OP_NOTMINQUERYI:    case OP_NOTMINQUERYI:
   case OP_NOTPOSSTARI:  
   case OP_NOTPOSPLUSI:  
   case OP_NOTPOSQUERYI:  
   cc += 2;  
 #ifdef SUPPORT_UTF8  
   if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];  
 #endif  
   return cc;  
   
   case OP_UPTO:  
   case OP_MINUPTO:  
   case OP_EXACT:  
   case OP_POSUPTO:  
   case OP_UPTOI:  
   case OP_MINUPTOI:  
   case OP_EXACTI:  
   case OP_POSUPTOI:  
   case OP_NOTUPTO:  
   case OP_NOTMINUPTO:  
   case OP_NOTEXACT:  
   case OP_NOTPOSUPTO:  
689    case OP_NOTUPTOI:    case OP_NOTUPTOI:
690    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
691    case OP_NOTEXACTI:    case OP_NOTEXACTI:
692      case OP_NOTPOSSTARI:
693      case OP_NOTPOSPLUSI:
694      case OP_NOTPOSQUERYI:
695    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
696    cc += 4;    cc += PRIV(OP_lengths)[*cc];
697  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
698    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]);
699  #endif  #endif
700    return cc;    return cc;
701    
702    case OP_NOTPROP:    /* Special cases. */
703    case OP_PROP:    case OP_TYPESTAR:
704      case OP_TYPEMINSTAR:
705      case OP_TYPEPLUS:
706      case OP_TYPEMINPLUS:
707      case OP_TYPEQUERY:
708      case OP_TYPEMINQUERY:
709    case OP_TYPEUPTO:    case OP_TYPEUPTO:
710    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
711    case OP_TYPEEXACT:    case OP_TYPEEXACT:
712      case OP_TYPEPOSSTAR:
713      case OP_TYPEPOSPLUS:
714      case OP_TYPEPOSQUERY:
715    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
716    case OP_REF:    return cc + PRIV(OP_lengths)[*cc] - 1;
   case OP_REFI:  
   case OP_CREF:  
   case OP_CLOSE:  
   cc += 3;  
   return cc;  
717    
718    case OP_CRRANGE:    case OP_ANYBYTE:
719    case OP_CRMINRANGE:  #ifdef SUPPORT_UTF
720    return cc + 5;    if (common->utf) return NULL;
721    #endif
722    case OP_CLASS:    return cc + 1;
   case OP_NCLASS:  
   return cc + 33;  
723    
724  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
725    case OP_XCLASS:    case OP_XCLASS:
726    return cc + GET(cc, 1);    return cc + GET(cc, 1);
727  #endif  #endif
728    
729    case OP_RECURSE:    case OP_MARK:
730    case OP_ASSERT:    case OP_PRUNE_ARG:
731    case OP_ASSERT_NOT:    case OP_SKIP_ARG:
732    case OP_ASSERTBACK:    case OP_THEN_ARG:
733    case OP_ASSERTBACK_NOT:    return cc + 1 + 2 + cc[1];
   case OP_REVERSE:  
   case OP_ONCE:  
   case OP_BRA:  
   case OP_BRAPOS:  
   case OP_COND:  
   case OP_SBRA:  
   case OP_SBRAPOS:  
   case OP_SCOND:  
   case OP_ALT:  
   case OP_KET:  
   case OP_KETRMAX:  
   case OP_KETRMIN:  
   case OP_KETRPOS:  
   return cc + 1 + LINK_SIZE;  
   
   case OP_CBRA:  
   case OP_CBRAPOS:  
   case OP_SCBRA:  
   case OP_SCBRAPOS:  
   return cc + 1 + LINK_SIZE + 2;  
734    
735    default:    default:
736      /* All opcodes are supported now! */
737      SLJIT_ASSERT_STOP();
738    return NULL;    return NULL;
739    }    }
740  }  }
741    
742  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
743        case OP_MINSTAR: \
744        case OP_MINPLUS: \
745        case OP_QUERY: \
746        case OP_MINQUERY: \
747        case OP_MINSTARI: \
748        case OP_MINPLUSI: \
749        case OP_QUERYI: \
750        case OP_MINQUERYI: \
751        case OP_NOTMINSTAR: \
752        case OP_NOTMINPLUS: \
753        case OP_NOTQUERY: \
754        case OP_NOTMINQUERY: \
755        case OP_NOTMINSTARI: \
756        case OP_NOTMINPLUSI: \
757        case OP_NOTQUERYI: \
758        case OP_NOTMINQUERYI:
759    
760    #define CASE_ITERATOR_PRIVATE_DATA_2A \
761        case OP_STAR: \
762        case OP_PLUS: \
763        case OP_STARI: \
764        case OP_PLUSI: \
765        case OP_NOTSTAR: \
766        case OP_NOTPLUS: \
767        case OP_NOTSTARI: \
768        case OP_NOTPLUSI:
769    
770    #define CASE_ITERATOR_PRIVATE_DATA_2B \
771        case OP_UPTO: \
772        case OP_MINUPTO: \
773        case OP_UPTOI: \
774        case OP_MINUPTOI: \
775        case OP_NOTUPTO: \
776        case OP_NOTMINUPTO: \
777        case OP_NOTUPTOI: \
778        case OP_NOTMINUPTOI:
779    
780    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
781        case OP_TYPEMINSTAR: \
782        case OP_TYPEMINPLUS: \
783        case OP_TYPEQUERY: \
784        case OP_TYPEMINQUERY:
785    
786    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
787        case OP_TYPESTAR: \
788        case OP_TYPEPLUS:
789    
790    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
791        case OP_TYPEUPTO: \
792        case OP_TYPEMINUPTO:
793    
794    static int get_class_iterator_size(pcre_uchar *cc)
795  {  {
796  int localspace = 0;  switch(*cc)
797  uschar *alternative;    {
798      case OP_CRSTAR:
799      case OP_CRPLUS:
800      return 2;
801    
802      case OP_CRMINSTAR:
803      case OP_CRMINPLUS:
804      case OP_CRQUERY:
805      case OP_CRMINQUERY:
806      return 1;
807    
808      case OP_CRRANGE:
809      case OP_CRMINRANGE:
810      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
811        return 0;
812      return 2;
813    
814      default:
815      return 0;
816      }
817    }
818    
819    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
820    {
821    int private_data_length = 0;
822    pcre_uchar *alternative;
823    pcre_uchar *name;
824    pcre_uchar *end = NULL;
825    int space, size, i;
826    pcre_uint32 bracketlen;
827    
828  /* 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. */
829  while (cc < ccend)  while (cc < ccend)
830    {    {
831      space = 0;
832      size = 0;
833      bracketlen = 0;
834    switch(*cc)    switch(*cc)
835      {      {
836        case OP_SET_SOM:
837        common->has_set_som = TRUE;
838        cc += 1;
839        break;
840    
841        case OP_REF:
842        case OP_REFI:
843        common->optimized_cbracket[GET2(cc, 1)] = 0;
844        cc += 1 + IMM2_SIZE;
845        break;
846    
847      case OP_ASSERT:      case OP_ASSERT:
848      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
849      case OP_ASSERTBACK:      case OP_ASSERTBACK:
850      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
851      case OP_ONCE:      case OP_ONCE:
852        case OP_ONCE_NC:
853      case OP_BRAPOS:      case OP_BRAPOS:
854      case OP_SBRA:      case OP_SBRA:
855      case OP_SBRAPOS:      case OP_SBRAPOS:
856      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
857      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
858      break;      break;
859    
860      case OP_CBRAPOS:      case OP_CBRAPOS:
861      case OP_SCBRAPOS:      case OP_SCBRAPOS:
862      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
863      cc += 1 + LINK_SIZE + 2;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
864        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
865      break;      break;
866    
867      case OP_COND:      case OP_COND:
868      /* Might be a hidden SCOND. */      case OP_SCOND:
869      alternative = cc + GET(cc, 1);      /* Only AUTO_CALLOUT can insert this opcode. We do
870      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)         not intend to support this case. */
871        localspace += sizeof(sljit_w);      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
872          return -1;
873    
874        if (*cc == OP_COND)
875          {
876          /* Might be a hidden SCOND. */
877          alternative = cc + GET(cc, 1);
878          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
879            private_data_length += sizeof(sljit_sw);
880          }
881        else
882          private_data_length += sizeof(sljit_sw);
883        bracketlen = 1 + LINK_SIZE;
884        break;
885    
886        case OP_CREF:
887        i = GET2(cc, 1);
888        common->optimized_cbracket[i] = 0;
889        cc += 1 + IMM2_SIZE;
890        break;
891    
892        case OP_NCREF:
893        bracketlen = GET2(cc, 1);
894        name = (pcre_uchar *)common->name_table;
895        alternative = name;
896        for (i = 0; i < common->name_count; i++)
897          {
898          if (GET2(name, 0) == bracketlen) break;
899          name += common->name_entry_size;
900          }
901        SLJIT_ASSERT(i != common->name_count);
902    
903        for (i = 0; i < common->name_count; i++)
904          {
905          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
906            common->optimized_cbracket[GET2(alternative, 0)] = 0;
907          alternative += common->name_entry_size;
908          }
909        bracketlen = 0;
910        cc += 1 + IMM2_SIZE;
911        break;
912    
913        case OP_BRA:
914        bracketlen = 1 + LINK_SIZE;
915        break;
916    
917        case OP_CBRA:
918        case OP_SCBRA:
919        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
920        break;
921    
922        CASE_ITERATOR_PRIVATE_DATA_1
923        space = 1;
924        size = -2;
925        break;
926    
927        CASE_ITERATOR_PRIVATE_DATA_2A
928        space = 2;
929        size = -2;
930        break;
931    
932        CASE_ITERATOR_PRIVATE_DATA_2B
933        space = 2;
934        size = -(2 + IMM2_SIZE);
935        break;
936    
937        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
938        space = 1;
939        size = 1;
940        break;
941    
942        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
943        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
944          space = 2;
945        size = 1;
946        break;
947    
948        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
949        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
950          space = 2;
951        size = 1 + IMM2_SIZE;
952        break;
953    
954        case OP_CLASS:
955        case OP_NCLASS:
956        size += 1 + 32 / sizeof(pcre_uchar);
957        space = get_class_iterator_size(cc + size);
958        break;
959    
960    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
961        case OP_XCLASS:
962        size = GET(cc, 1);
963        space = get_class_iterator_size(cc + size);
964        break;
965    #endif
966    
967        case OP_RECURSE:
968        /* Set its value only once. */
969        if (common->recursive_head_ptr == 0)
970          {
971          common->recursive_head_ptr = common->ovector_start;
972          common->ovector_start += sizeof(sljit_sw);
973          }
974      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
975      break;      break;
976    
977        case OP_CALLOUT:
978        if (common->capture_last_ptr == 0)
979          {
980          common->capture_last_ptr = common->ovector_start;
981          common->ovector_start += sizeof(sljit_sw);
982          }
983        cc += 2 + 2 * LINK_SIZE;
984        break;
985    
986        case OP_THEN_ARG:
987        common->has_then = TRUE;
988        /* Fall through. */
989    
990        case OP_PRUNE_ARG:
991        common->needs_start_ptr = TRUE;
992        common->control_head_ptr = 1;
993        /* Fall through. */
994    
995        case OP_MARK:
996        if (common->mark_ptr == 0)
997          {
998          common->mark_ptr = common->ovector_start;
999          common->ovector_start += sizeof(sljit_sw);
1000          }
1001        cc += 1 + 2 + cc[1];
1002        break;
1003    
1004        case OP_THEN:
1005        common->has_then = TRUE;
1006        /* Fall through. */
1007    
1008        case OP_PRUNE:
1009        case OP_SKIP:
1010        common->needs_start_ptr = TRUE;
1011        common->control_head_ptr = 1;
1012        cc += 1;
1013        break;
1014    
1015        case OP_SKIP_ARG:
1016        common->control_head_ptr = 1;
1017        common->has_skip_arg = TRUE;
1018        cc += 1 + 2 + cc[1];
1019        break;
1020    
1021      default:      default:
1022      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1023      if (cc == NULL)      if (cc == NULL)
1024        return -1;        return -1;
1025      break;      break;
1026      }      }
1027    
1028      if (space > 0 && cc >= end)
1029        private_data_length += sizeof(sljit_sw) * space;
1030    
1031      if (size != 0)
1032        {
1033        if (size < 0)
1034          {
1035          cc += -size;
1036    #ifdef SUPPORT_UTF
1037          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1038    #endif
1039          }
1040        else
1041          cc += size;
1042        }
1043    
1044      if (bracketlen != 0)
1045        {
1046        if (cc >= end)
1047          {
1048          end = bracketend(cc);
1049          if (end[-1 - LINK_SIZE] == OP_KET)
1050            end = NULL;
1051          }
1052        cc += bracketlen;
1053        }
1054    }    }
1055  return localspace;  return private_data_length;
1056  }  }
1057    
1058  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)
1059  {  {
1060  uschar *cc = common->start;  pcre_uchar *cc = common->start;
1061  uschar *alternative;  pcre_uchar *alternative;
1062    pcre_uchar *end = NULL;
1063    int space, size, bracketlen;
1064    
1065  while (cc < ccend)  while (cc < ccend)
1066    {    {
1067      space = 0;
1068      size = 0;
1069      bracketlen = 0;
1070    switch(*cc)    switch(*cc)
1071      {      {
1072      case OP_ASSERT:      case OP_ASSERT:
# Line 654  while (cc < ccend) Line 1074  while (cc < ccend)
1074      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1075      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1076      case OP_ONCE:      case OP_ONCE:
1077        case OP_ONCE_NC:
1078      case OP_BRAPOS:      case OP_BRAPOS:
1079      case OP_SBRA:      case OP_SBRA:
1080      case OP_SBRAPOS:      case OP_SBRAPOS:
1081      case OP_SCOND:      case OP_SCOND:
1082      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1083      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1084      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1085      break;      break;
1086    
1087      case OP_CBRAPOS:      case OP_CBRAPOS:
1088      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1089      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1090      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1091      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1092      break;      break;
1093    
1094      case OP_COND:      case OP_COND:
# Line 675  while (cc < ccend) Line 1096  while (cc < ccend)
1096      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1097      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1098        {        {
1099        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1100        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1101        }        }
1102      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1103        break;
1104    
1105        case OP_BRA:
1106        bracketlen = 1 + LINK_SIZE;
1107        break;
1108    
1109        case OP_CBRA:
1110        case OP_SCBRA:
1111        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1112      break;      break;
1113    
1114        CASE_ITERATOR_PRIVATE_DATA_1
1115        space = 1;
1116        size = -2;
1117        break;
1118    
1119        CASE_ITERATOR_PRIVATE_DATA_2A
1120        space = 2;
1121        size = -2;
1122        break;
1123    
1124        CASE_ITERATOR_PRIVATE_DATA_2B
1125        space = 2;
1126        size = -(2 + IMM2_SIZE);
1127        break;
1128    
1129        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1130        space = 1;
1131        size = 1;
1132        break;
1133    
1134        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1135        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1136          space = 2;
1137        size = 1;
1138        break;
1139    
1140        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1141        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1142          space = 2;
1143        size = 1 + IMM2_SIZE;
1144        break;
1145    
1146        case OP_CLASS:
1147        case OP_NCLASS:
1148        size += 1 + 32 / sizeof(pcre_uchar);
1149        space = get_class_iterator_size(cc + size);
1150        break;
1151    
1152    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1153        case OP_XCLASS:
1154        size = GET(cc, 1);
1155        space = get_class_iterator_size(cc + size);
1156        break;
1157    #endif
1158    
1159      default:      default:
1160      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1161      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1162      break;      break;
1163      }      }
1164    
1165      if (space > 0 && cc >= end)
1166        {
1167        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1168        private_data_ptr += sizeof(sljit_sw) * space;
1169        }
1170    
1171      if (size != 0)
1172        {
1173        if (size < 0)
1174          {
1175          cc += -size;
1176    #ifdef SUPPORT_UTF
1177          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1178    #endif
1179          }
1180        else
1181          cc += size;
1182        }
1183    
1184      if (bracketlen > 0)
1185        {
1186        if (cc >= end)
1187          {
1188          end = bracketend(cc);
1189          if (end[-1 - LINK_SIZE] == OP_KET)
1190            end = NULL;
1191          }
1192        cc += bracketlen;
1193        }
1194    }    }
1195  }  }
1196    
1197  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1198  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
1199  {  {
 uschar *ccend = bracketend(cc);  
 uschar *end;  
1200  int length = 0;  int length = 0;
1201  BOOL possessive = FALSE;  int possessive = 0;
1202  BOOL needs_frame = FALSE;  BOOL stack_restore = FALSE;
1203  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1204    BOOL setmark_found = recursive;
1205    /* The last capture is a local variable even for recursions. */
1206    BOOL capture_last_found = FALSE;
1207    
1208    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1209    SLJIT_ASSERT(common->control_head_ptr != 0);
1210    *needs_control_head = TRUE;
1211    #else
1212    *needs_control_head = FALSE;
1213    #endif
1214    
1215  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (ccend == NULL)
1216    {    {
1217    length = 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1218    possessive = TRUE;    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1219        {
1220        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1221        /* This is correct regardless of common->capture_last_ptr. */
1222        capture_last_found = TRUE;
1223        }
1224      cc = next_opcode(common, cc);
1225    }    }
1226    
 cc = next_opcode(common, cc);  
1227  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1228  while (cc < ccend)  while (cc < ccend)
1229    switch(*cc)    switch(*cc)
1230      {      {
1231      case OP_SET_SOM:      case OP_SET_SOM:
1232      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1233        stack_restore = TRUE;
1234      if (!setsom_found)      if (!setsom_found)
1235        {        {
1236        length += 2;        length += 2;
1237        setsom_found = TRUE;        setsom_found = TRUE;
1238        }        }
1239      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1240      break;      break;
1241    
1242      case OP_ASSERT:      case OP_MARK:
1243      case OP_ASSERT_NOT:      case OP_PRUNE_ARG:
1244      case OP_ASSERTBACK:      case OP_THEN_ARG:
1245      case OP_ASSERTBACK_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
1246      case OP_ONCE:      stack_restore = TRUE;
1247      if (needs_frame || length > 0)      if (!setmark_found)
1248          {
1249          length += 2;
1250          setmark_found = TRUE;
1251          }
1252        if (common->control_head_ptr != 0)
1253          *needs_control_head = TRUE;
1254        cc += 1 + 2 + cc[1];
1255        break;
1256    
1257        case OP_RECURSE:
1258        stack_restore = TRUE;
1259        if (common->has_set_som && !setsom_found)
1260          {
1261          length += 2;
1262          setsom_found = TRUE;
1263          }
1264        if (common->mark_ptr != 0 && !setmark_found)
1265        {        {
1266        cc = bracketend(cc);        length += 2;
1267        break;        setmark_found = TRUE;
1268        }        }
1269      /* Check whether a frame must be created. */      if (common->capture_last_ptr != 0 && !capture_last_found)
1270      end = bracketend(cc);        {
1271      while (cc < end)        length += 2;
1272        {        capture_last_found = TRUE;
       if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS  
           || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)  
         needs_frame = TRUE;  
       cc = next_opcode(common, cc);  
       SLJIT_ASSERT(cc != NULL);  
1273        }        }
1274        cc += 1 + LINK_SIZE;
1275      break;      break;
1276    
1277      case OP_CBRA:      case OP_CBRA:
1278      case OP_CBRAPOS:      case OP_CBRAPOS:
1279      case OP_SCBRA:      case OP_SCBRA:
1280      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1281        stack_restore = TRUE;
1282        if (common->capture_last_ptr != 0 && !capture_last_found)
1283          {
1284          length += 2;
1285          capture_last_found = TRUE;
1286          }
1287      length += 3;      length += 3;
1288      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1289      break;      break;
1290    
1291        case OP_PRUNE:
1292        case OP_SKIP:
1293        case OP_SKIP_ARG:
1294        case OP_COMMIT:
1295        if (common->control_head_ptr != 0)
1296          *needs_control_head = TRUE;
1297        /* Fall through. */
1298    
1299      default:      default:
1300        stack_restore = TRUE;
1301        /* Fall through. */
1302    
1303        case OP_NOT_WORD_BOUNDARY:
1304        case OP_WORD_BOUNDARY:
1305        case OP_NOT_DIGIT:
1306        case OP_DIGIT:
1307        case OP_NOT_WHITESPACE:
1308        case OP_WHITESPACE:
1309        case OP_NOT_WORDCHAR:
1310        case OP_WORDCHAR:
1311        case OP_ANY:
1312        case OP_ALLANY:
1313        case OP_ANYBYTE:
1314        case OP_NOTPROP:
1315        case OP_PROP:
1316        case OP_ANYNL:
1317        case OP_NOT_HSPACE:
1318        case OP_HSPACE:
1319        case OP_NOT_VSPACE:
1320        case OP_VSPACE:
1321        case OP_EXTUNI:
1322        case OP_EODN:
1323        case OP_EOD:
1324        case OP_CIRC:
1325        case OP_CIRCM:
1326        case OP_DOLL:
1327        case OP_DOLLM:
1328        case OP_CHAR:
1329        case OP_CHARI:
1330        case OP_NOT:
1331        case OP_NOTI:
1332    
1333        case OP_EXACT:
1334        case OP_POSSTAR:
1335        case OP_POSPLUS:
1336        case OP_POSQUERY:
1337        case OP_POSUPTO:
1338    
1339        case OP_EXACTI:
1340        case OP_POSSTARI:
1341        case OP_POSPLUSI:
1342        case OP_POSQUERYI:
1343        case OP_POSUPTOI:
1344    
1345        case OP_NOTEXACT:
1346        case OP_NOTPOSSTAR:
1347        case OP_NOTPOSPLUS:
1348        case OP_NOTPOSQUERY:
1349        case OP_NOTPOSUPTO:
1350    
1351        case OP_NOTEXACTI:
1352        case OP_NOTPOSSTARI:
1353        case OP_NOTPOSPLUSI:
1354        case OP_NOTPOSQUERYI:
1355        case OP_NOTPOSUPTOI:
1356    
1357        case OP_TYPEEXACT:
1358        case OP_TYPEPOSSTAR:
1359        case OP_TYPEPOSPLUS:
1360        case OP_TYPEPOSQUERY:
1361        case OP_TYPEPOSUPTO:
1362    
1363        case OP_CLASS:
1364        case OP_NCLASS:
1365        case OP_XCLASS:
1366    
1367      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1368      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1369      break;      break;
1370      }      }
1371    
1372  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1373  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive == length))
1374    return -1;    return stack_restore ? no_frame : no_stack;
1375    
1376  if (length > 0)  if (length > 0)
1377    return length + 2;    return length + 1;
1378  return needs_frame ? 0 : -1;  return stack_restore ? no_frame : no_stack;
1379  }  }
1380    
1381  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, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1382  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
1383  DEFINE_COMPILER;  DEFINE_COMPILER;
1384  uschar *ccend = bracketend(cc);  BOOL setsom_found = recursive;
1385  BOOL setsom_found = FALSE;  BOOL setmark_found = recursive;
1386    /* The last capture is a local variable even for recursions. */
1387    BOOL capture_last_found = FALSE;
1388  int offset;  int offset;
1389    
1390  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
1391    {  SLJIT_UNUSED_ARG(stacktop);
1392    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
1393    
1394  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1395  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  if (ccend == NULL)
1396  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);    {
1397  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacktop), TMP1, 0);    ccend = bracketend(cc) - (1 + LINK_SIZE);
1398      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1399        cc = next_opcode(common, cc);
1400      }
1401    
 if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  
   cc = next_opcode(common, cc);  
1402  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1403  while (cc < ccend)  while (cc < ccend)
1404    switch(*cc)    switch(*cc)
1405      {      {
1406      case OP_SET_SOM:      case OP_SET_SOM:
1407      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1408      if (!setsom_found)      if (!setsom_found)
1409        {        {
1410        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1411        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1412        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1413        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1414        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1415        setsom_found = TRUE;        setsom_found = TRUE;
1416        }        }
1417      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1418      break;      break;
1419    
1420      case OP_ASSERT:      case OP_MARK:
1421      case OP_ASSERT_NOT:      case OP_PRUNE_ARG:
1422      case OP_ASSERTBACK:      case OP_THEN_ARG:
1423      case OP_ASSERTBACK_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
1424      case OP_ONCE:      if (!setmark_found)
1425      cc = bracketend(cc);        {
1426          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1427          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1428          stackpos += (int)sizeof(sljit_sw);
1429          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1430          stackpos += (int)sizeof(sljit_sw);
1431          setmark_found = TRUE;
1432          }
1433        cc += 1 + 2 + cc[1];
1434        break;
1435    
1436        case OP_RECURSE:
1437        if (common->has_set_som && !setsom_found)
1438          {
1439          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1440          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1441          stackpos += (int)sizeof(sljit_sw);
1442          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1443          stackpos += (int)sizeof(sljit_sw);
1444          setsom_found = TRUE;
1445          }
1446        if (common->mark_ptr != 0 && !setmark_found)
1447          {
1448          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1449          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1450          stackpos += (int)sizeof(sljit_sw);
1451          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1452          stackpos += (int)sizeof(sljit_sw);
1453          setmark_found = TRUE;
1454          }
1455        if (common->capture_last_ptr != 0 && !capture_last_found)
1456          {
1457          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1458          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1459          stackpos += (int)sizeof(sljit_sw);
1460          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1461          stackpos += (int)sizeof(sljit_sw);
1462          capture_last_found = TRUE;
1463          }
1464        cc += 1 + LINK_SIZE;
1465      break;      break;
1466    
1467      case OP_CBRA:      case OP_CBRA:
1468      case OP_CBRAPOS:      case OP_CBRAPOS:
1469      case OP_SCBRA:      case OP_SCBRA:
1470      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1471        if (common->capture_last_ptr != 0 && !capture_last_found)
1472          {
1473          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1474          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1475          stackpos += (int)sizeof(sljit_sw);
1476          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1477          stackpos += (int)sizeof(sljit_sw);
1478          capture_last_found = TRUE;
1479          }
1480      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1481      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1482      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1483      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1484      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));
1485      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1486      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1487      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1488      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1489    
1490      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1491      break;      break;
1492    
1493      default:      default:
# Line 835  while (cc < ccend) Line 1496  while (cc < ccend)
1496      break;      break;
1497      }      }
1498    
1499  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1500  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1501  }  }
1502    
1503  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1504  {  {
1505  int localsize = 2;  int private_data_length = needs_control_head ? 3 : 2;
1506  uschar *alternative;  int size;
1507  /* Calculate the sum of the local variables. */  pcre_uchar *alternative;
1508    /* Calculate the sum of the private machine words. */
1509  while (cc < ccend)  while (cc < ccend)
1510    {    {
1511      size = 0;
1512    switch(*cc)    switch(*cc)
1513      {      {
1514      case OP_ASSERT:      case OP_ASSERT:
# Line 853  while (cc < ccend) Line 1516  while (cc < ccend)
1516      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1517      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1518      case OP_ONCE:      case OP_ONCE:
1519        case OP_ONCE_NC:
1520      case OP_BRAPOS:      case OP_BRAPOS:
1521      case OP_SBRA:      case OP_SBRA:
1522      case OP_SBRAPOS:      case OP_SBRAPOS:
1523      case OP_SCOND:      case OP_SCOND:
1524      localsize++;      private_data_length++;
1525      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1526      break;      break;
1527    
1528      case OP_CBRA:      case OP_CBRA:
1529      case OP_SCBRA:      case OP_SCBRA:
1530      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1531      cc += 1 + LINK_SIZE + 2;        private_data_length++;
1532        cc += 1 + LINK_SIZE + IMM2_SIZE;
1533      break;      break;
1534    
1535      case OP_CBRAPOS:      case OP_CBRAPOS:
1536      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1537      localsize += 2;      private_data_length += 2;
1538      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1539      break;      break;
1540    
1541      case OP_COND:      case OP_COND:
1542      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1543      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1544      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1545        localsize++;        private_data_length++;
1546      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1547      break;      break;
1548    
1549        CASE_ITERATOR_PRIVATE_DATA_1
1550        if (PRIVATE_DATA(cc))
1551          private_data_length++;
1552        cc += 2;
1553    #ifdef SUPPORT_UTF
1554        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1555    #endif
1556        break;
1557    
1558        CASE_ITERATOR_PRIVATE_DATA_2A
1559        if (PRIVATE_DATA(cc))
1560          private_data_length += 2;
1561        cc += 2;
1562    #ifdef SUPPORT_UTF
1563        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1564    #endif
1565        break;
1566    
1567        CASE_ITERATOR_PRIVATE_DATA_2B
1568        if (PRIVATE_DATA(cc))
1569          private_data_length += 2;
1570        cc += 2 + IMM2_SIZE;
1571    #ifdef SUPPORT_UTF
1572        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1573    #endif
1574        break;
1575    
1576        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1577        if (PRIVATE_DATA(cc))
1578          private_data_length++;
1579        cc += 1;
1580        break;
1581    
1582        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1583        if (PRIVATE_DATA(cc))
1584          private_data_length += 2;
1585        cc += 1;
1586        break;
1587    
1588        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1589        if (PRIVATE_DATA(cc))
1590          private_data_length += 2;
1591        cc += 1 + IMM2_SIZE;
1592        break;
1593    
1594        case OP_CLASS:
1595        case OP_NCLASS:
1596    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1597        case OP_XCLASS:
1598        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1599    #else
1600        size = 1 + 32 / (int)sizeof(pcre_uchar);
1601    #endif
1602        if (PRIVATE_DATA(cc))
1603          private_data_length += get_class_iterator_size(cc + size);
1604        cc += size;
1605        break;
1606    
1607      default:      default:
1608      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1609      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 888  while (cc < ccend) Line 1611  while (cc < ccend)
1611      }      }
1612    }    }
1613  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1614  return localsize;  return private_data_length;
1615  }  }
1616    
1617  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,
1618    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1619  {  {
1620  DEFINE_COMPILER;  DEFINE_COMPILER;
1621  int srcw[2];  int srcw[2];
1622  int count;  int count, size;
1623  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1624  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1625  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1626  uschar *alternative;  pcre_uchar *alternative;
1627  enum {  enum {
1628    start,    start,
1629    loop,    loop,
# Line 913  stacktop = STACK(stacktop - 1); Line 1636  stacktop = STACK(stacktop - 1);
1636    
1637  if (!save)  if (!save)
1638    {    {
1639    stackptr += sizeof(sljit_w);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1640    if (stackptr < stacktop)    if (stackptr < stacktop)
1641      {      {
1642      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1643      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1644      tmp1empty = FALSE;      tmp1empty = FALSE;
1645      }      }
1646    if (stackptr < stacktop)    if (stackptr < stacktop)
1647      {      {
1648      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1649      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1650      tmp2empty = FALSE;      tmp2empty = FALSE;
1651      }      }
1652    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1653    }    }
1654    
1655  while (status != end)  do
1656    {    {
1657    count = 0;    count = 0;
1658    switch(status)    switch(status)
1659      {      {
1660      case start:      case start:
1661      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1662      count = 1;      count = 1;
1663      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head_ptr;
1664        if (needs_control_head)
1665          {
1666          SLJIT_ASSERT(common->control_head_ptr != 0);
1667          count = 2;
1668          srcw[1] = common->control_head_ptr;
1669          }
1670      status = loop;      status = loop;
1671      break;      break;
1672    
# Line 955  while (status != end) Line 1684  while (status != end)
1684        case OP_ASSERTBACK:        case OP_ASSERTBACK:
1685        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
1686        case OP_ONCE:        case OP_ONCE:
1687          case OP_ONCE_NC:
1688        case OP_BRAPOS:        case OP_BRAPOS:
1689        case OP_SBRA:        case OP_SBRA:
1690        case OP_SBRAPOS:        case OP_SBRAPOS:
1691        case OP_SCOND:        case OP_SCOND:
1692        count = 1;        count = 1;
1693        srcw[0] = PRIV(cc);        srcw[0] = PRIVATE_DATA(cc);
1694        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1695        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1696        break;        break;
1697    
1698        case OP_CBRA:        case OP_CBRA:
1699        case OP_SCBRA:        case OP_SCBRA:
1700        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1701        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1702        cc += 1 + LINK_SIZE + 2;          count = 1;
1703            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1704            }
1705          cc += 1 + LINK_SIZE + IMM2_SIZE;
1706        break;        break;
1707    
1708        case OP_CBRAPOS:        case OP_CBRAPOS:
1709        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1710        count = 2;        count = 2;
1711          srcw[0] = PRIVATE_DATA(cc);
1712        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1713        srcw[0] = PRIV(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1714        SLJIT_ASSERT(srcw[0] != 0);        cc += 1 + LINK_SIZE + IMM2_SIZE;
       cc += 1 + LINK_SIZE + 2;  
1715        break;        break;
1716    
1717        case OP_COND:        case OP_COND:
# Line 987  while (status != end) Line 1720  while (status != end)
1720        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1721          {          {
1722          count = 1;          count = 1;
1723          srcw[0] = PRIV(cc);          srcw[0] = PRIVATE_DATA(cc);
1724          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1725          }          }
1726        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1727        break;        break;
1728    
1729          CASE_ITERATOR_PRIVATE_DATA_1
1730          if (PRIVATE_DATA(cc))
1731            {
1732            count = 1;
1733            srcw[0] = PRIVATE_DATA(cc);
1734            }
1735          cc += 2;
1736    #ifdef SUPPORT_UTF
1737          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1738    #endif
1739          break;
1740    
1741          CASE_ITERATOR_PRIVATE_DATA_2A
1742          if (PRIVATE_DATA(cc))
1743            {
1744            count = 2;
1745            srcw[0] = PRIVATE_DATA(cc);
1746            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1747            }
1748          cc += 2;
1749    #ifdef SUPPORT_UTF
1750          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1751    #endif
1752          break;
1753    
1754          CASE_ITERATOR_PRIVATE_DATA_2B
1755          if (PRIVATE_DATA(cc))
1756            {
1757            count = 2;
1758            srcw[0] = PRIVATE_DATA(cc);
1759            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1760            }
1761          cc += 2 + IMM2_SIZE;
1762    #ifdef SUPPORT_UTF
1763          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1764    #endif
1765          break;
1766    
1767          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1768          if (PRIVATE_DATA(cc))
1769            {
1770            count = 1;
1771            srcw[0] = PRIVATE_DATA(cc);
1772            }
1773          cc += 1;
1774          break;
1775    
1776          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1777          if (PRIVATE_DATA(cc))
1778            {
1779            count = 2;
1780            srcw[0] = PRIVATE_DATA(cc);
1781            srcw[1] = srcw[0] + sizeof(sljit_sw);
1782            }
1783          cc += 1;
1784          break;
1785    
1786          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1787          if (PRIVATE_DATA(cc))
1788            {
1789            count = 2;
1790            srcw[0] = PRIVATE_DATA(cc);
1791            srcw[1] = srcw[0] + sizeof(sljit_sw);
1792            }
1793          cc += 1 + IMM2_SIZE;
1794          break;
1795    
1796          case OP_CLASS:
1797          case OP_NCLASS:
1798    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1799          case OP_XCLASS:
1800          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1801    #else
1802          size = 1 + 32 / (int)sizeof(pcre_uchar);
1803    #endif
1804          if (PRIVATE_DATA(cc))
1805            switch(get_class_iterator_size(cc + size))
1806              {
1807              case 1:
1808              count = 1;
1809              srcw[0] = PRIVATE_DATA(cc);
1810              break;
1811    
1812              case 2:
1813              count = 2;
1814              srcw[0] = PRIVATE_DATA(cc);
1815              srcw[1] = srcw[0] + sizeof(sljit_sw);
1816              break;
1817    
1818              default:
1819              SLJIT_ASSERT_STOP();
1820              break;
1821              }
1822          cc += size;
1823          break;
1824    
1825        default:        default:
1826        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1827        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1015  while (status != end) Line 1844  while (status != end)
1844          if (!tmp1empty)          if (!tmp1empty)
1845            {            {
1846            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1847            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1848            }            }
1849          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1850          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1026  while (status != end) Line 1855  while (status != end)
1855          if (!tmp2empty)          if (!tmp2empty)
1856            {            {
1857            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1858            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1859            }            }
1860          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1861          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1043  while (status != end) Line 1872  while (status != end)
1872          if (!tmp1empty)          if (!tmp1empty)
1873            {            {
1874            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1875            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1876            }            }
1877          tmp1next = FALSE;          tmp1next = FALSE;
1878          }          }
# Line 1055  while (status != end) Line 1884  while (status != end)
1884          if (!tmp2empty)          if (!tmp2empty)
1885            {            {
1886            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1887            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1888            }            }
1889          tmp1next = TRUE;          tmp1next = TRUE;
1890          }          }
1891        }        }
1892      }      }
1893    }    }
1894    while (status != end);
1895    
1896  if (save)  if (save)
1897    {    {
# Line 1070  if (save) Line 1900  if (save)
1900      if (!tmp1empty)      if (!tmp1empty)
1901        {        {
1902        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1903        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1904        }        }
1905      if (!tmp2empty)      if (!tmp2empty)
1906        {        {
1907        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1908        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1909        }        }
1910      }      }
1911    else    else
# Line 1083  if (save) Line 1913  if (save)
1913      if (!tmp2empty)      if (!tmp2empty)
1914        {        {
1915        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1916        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1917        }        }
1918      if (!tmp1empty)      if (!tmp1empty)
1919        {        {
1920        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1921        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1922        }        }
1923      }      }
1924    }    }
1925  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1926  }  }
1927    
1928  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1929    {
1930    pcre_uchar *end = bracketend(cc);
1931    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1932    
1933    /* Assert captures then. */
1934    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1935      current_offset = NULL;
1936    /* Conditional block does not. */
1937    if (*cc == OP_COND || *cc == OP_SCOND)
1938      has_alternatives = FALSE;
1939    
1940    cc = next_opcode(common, cc);
1941    if (has_alternatives)
1942      current_offset = common->then_offsets + (cc - common->start);
1943    
1944    while (cc < end)
1945      {
1946      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1947        cc = set_then_offsets(common, cc, current_offset);
1948      else
1949        {
1950        if (*cc == OP_ALT && has_alternatives)
1951          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1952        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1953          *current_offset = 1;
1954        cc = next_opcode(common, cc);
1955        }
1956      }
1957    
1958    return end;
1959    }
1960    
1961    #undef CASE_ITERATOR_PRIVATE_DATA_1
1962    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1963    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1964    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1965    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1966    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1967    
1968    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1969  {  {
1970  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1971  }  }
# Line 1105  static SLJIT_INLINE void set_jumps(jump_ Line 1975  static SLJIT_INLINE void set_jumps(jump_
1975  while (list)  while (list)
1976    {    {
1977    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1978    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1979    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1980    list = list->next;    list = list->next;
1981    }    }
1982  }  }
# Line 1122  if (list_item) Line 1992  if (list_item)
1992    }    }
1993  }  }
1994    
1995  static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)  static void add_stub(compiler_common *common, struct sljit_jump *start)
1996  {  {
1997  DEFINE_COMPILER;  DEFINE_COMPILER;
1998  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1999    
2000  if (list_item)  if (list_item)
2001    {    {
   list_item->type = type;  
   list_item->data = data;  
2002    list_item->start = start;    list_item->start = start;
2003    list_item->leave = LABEL();    list_item->quit = LABEL();
2004    list_item->next = common->stubs;    list_item->next = common->stubs;
2005    common->stubs = list_item;    common->stubs = list_item;
2006    }    }
# Line 1146  stub_list* list_item = common->stubs; Line 2014  stub_list* list_item = common->stubs;
2014  while (list_item)  while (list_item)
2015    {    {
2016    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
2017    switch(list_item->type)    add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
2018      {    JUMPTO(SLJIT_JUMP, list_item->quit);
     case stack_alloc:  
     add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));  
     break;  
     }  
   JUMPTO(SLJIT_JUMP, list_item->leave);  
2019    list_item = list_item->next;    list_item = list_item->next;
2020    }    }
2021  common->stubs = NULL;  common->stubs = NULL;
# Line 1171  static SLJIT_INLINE void allocate_stack( Line 2034  static SLJIT_INLINE void allocate_stack(
2034  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
2035  DEFINE_COMPILER;  DEFINE_COMPILER;
2036    
2037  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));
2038  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
2039  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
2040  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1179  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 2042  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2042  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
2043  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2044  #endif  #endif
2045  add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));  add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
2046  }  }
2047    
2048  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
2049  {  {
2050  DEFINE_COMPILER;  DEFINE_COMPILER;
2051  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));
2052  }  }
2053    
2054  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1193  static SLJIT_INLINE void reset_ovector(c Line 2056  static SLJIT_INLINE void reset_ovector(c
2056  DEFINE_COMPILER;  DEFINE_COMPILER;
2057  struct sljit_label *loop;  struct sljit_label *loop;
2058  int i;  int i;
2059    
2060  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2061    SLJIT_ASSERT(length > 1);
2062  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2063  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));
2064    if (length < 8)
2065      {
2066      for (i = 1; i < length; i++)
2067        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2068      }
2069    else
2070      {
2071      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2072      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2073      loop = LABEL();
2074      OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2075      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
2076      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2077      }
2078    }
2079    
2080    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2081    {
2082    DEFINE_COMPILER;
2083    struct sljit_label *loop;
2084    int i;
2085    
2086    SLJIT_ASSERT(length > 1);
2087    /* OVECTOR(1) contains the "string begin - 1" constant. */
2088    if (length > 2)
2089      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2090  if (length < 8)  if (length < 8)
2091    {    {
2092    for (i = 0; i < length; i++)    for (i = 2; i < length; i++)
2093      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2094    }    }
2095  else  else
2096    {    {
2097    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2098    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2099    loop = LABEL();    loop = LABEL();
2100    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2101    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2102    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
2103    }    }
2104    
2105    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2106    if (common->mark_ptr != 0)
2107      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2108    SLJIT_ASSERT(common->control_head_ptr != 0);
2109    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2110    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2111    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2112    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2113    }
2114    
2115    static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2116    {
2117    sljit_sw return_value = 0;
2118    const pcre_uchar *skip_arg = NULL;
2119    
2120    SLJIT_ASSERT(current != NULL);
2121    do
2122      {
2123      switch (current[-2])
2124        {
2125        case type_commit:
2126        /* Commit overwrites all. */
2127        return -1;
2128    
2129        case type_prune:
2130        case type_then_trap:
2131        break;
2132    
2133        case type_skip:
2134        /* Overwrites prune, but not other skips. */
2135        if (return_value == 0 && skip_arg == NULL)
2136          return_value = current[-3];
2137        break;
2138    
2139        case type_skip_arg:
2140        if (return_value == 0 && skip_arg == NULL)
2141          skip_arg = (pcre_uchar *)current[-3];
2142        break;
2143    
2144        case type_mark:
2145        if (return_value == 0 && skip_arg != NULL)
2146          if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2147            return_value = current[-4];
2148        break;
2149    
2150        default:
2151        SLJIT_ASSERT_STOP();
2152        break;
2153        }
2154      current = (sljit_sw*)current[-1];
2155      }
2156    while (current != NULL);
2157    return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2158    }
2159    
2160    static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)
2161    {
2162    do
2163      {
2164      switch (current[-2])
2165        {
2166        case type_commit:
2167        /* Commit overwrites all. */
2168        return 0;
2169    
2170        case type_then_trap:
2171        if (current[-3] == start)
2172          return (sljit_sw)current;
2173        break;
2174    
2175        case type_prune:
2176        case type_skip:
2177        case type_skip_arg:
2178        case type_mark:
2179        break;
2180    
2181        default:
2182        SLJIT_ASSERT_STOP();
2183        break;
2184        }
2185      current = (sljit_sw*)current[-1];
2186      SLJIT_ASSERT(current != NULL);
2187      }
2188    while (TRUE);
2189  }  }
2190    
2191  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2192  {  {
2193  DEFINE_COMPILER;  DEFINE_COMPILER;
2194  struct sljit_label *loop;  struct sljit_label *loop;
2195  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
2196    
2197  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2198  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));
2199  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);
2200    
2201  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
2202  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  if (common->mark_ptr != 0)
2203  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);
2204  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));
2205  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  if (common->mark_ptr != 0)
2206      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
2207    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2208    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
2209    GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
2210  /* Unlikely, but possible */  /* Unlikely, but possible */
2211  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);
2212  loop = LABEL();  loop = LABEL();
2213  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);
2214  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));
2215  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
2216  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2217  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);
2218    #endif
2219    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
2220    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
2221  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2222  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2223    
2224  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2225  if (topbracket > 1)  if (topbracket > 1)
2226    {    {
2227    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));
2228    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
2229    
2230    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
2231    loop = LABEL();    loop = LABEL();
2232    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)));
2233    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);
2234    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);
2235    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
2236    }    }
2237  else  else
2238    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
2239  }  }
2240    
2241  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)
2242    {
2243    DEFINE_COMPILER;
2244    struct sljit_jump *jump;
2245    
2246    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
2247    SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2248      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2249    
2250    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2251    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2252    OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2253    CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
2254    
2255    /* Store match begin and end. */
2256    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
2257    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2258    
2259    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2260    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);
2261    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2262    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2263    #endif
2264    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2265    JUMPHERE(jump);
2266    
2267    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);
2268    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
2269    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2270    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2271    #endif
2272    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
2273    
2274    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
2275    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2276    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2277    #endif
2278    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
2279    
2280    JUMPTO(SLJIT_JUMP, quit);
2281    }
2282    
2283    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
2284    {
2285    /* May destroy TMP1. */
2286    DEFINE_COMPILER;
2287    struct sljit_jump *jump;
2288    
2289    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2290      {
2291      /* The value of -1 must be kept for start_used_ptr! */
2292      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
2293      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
2294      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
2295      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
2296      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2297      JUMPHERE(jump);
2298      }
2299    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
2300      {
2301      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2302      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2303      JUMPHERE(jump);
2304      }
2305    }
2306    
2307    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
2308  {  {
2309  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
2310  unsigned int c;  unsigned int c;
2311    
2312  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2313  if (common->utf8)  if (common->utf)
2314    {    {
2315    GETCHAR(c, cc);    GETCHAR(c, cc);
2316    if (c > 127)    if (c > 127)
# Line 1272  if (common->utf8) Line 2321  if (common->utf8)
2321      return FALSE;      return FALSE;
2322  #endif  #endif
2323      }      }
2324    #ifndef COMPILE_PCRE8
2325      return common->fcc[c] != c;
2326    #endif
2327    }    }
2328  else  else
2329  #endif  #endif
2330    c = *cc;    c = *cc;
2331  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
2332  }  }
2333    
2334  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)
2335  {  {
2336  /* Returns with the othercase. */  /* Returns with the othercase. */
2337  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2338  if (common->utf8 && c > 127)  if (common->utf && c > 127)
2339    {    {
2340  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2341    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1292  if (common->utf8 && c > 127) Line 2344  if (common->utf8 && c > 127)
2344  #endif  #endif
2345    }    }
2346  #endif  #endif
2347  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
2348  }  }
2349    
2350  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)
2351  {  {
2352  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
2353  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2354  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2355  int n;  int n;
2356  #endif  #endif
2357    
2358  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2359  if (common->utf8)  if (common->utf)
2360    {    {
2361    GETCHAR(c, cc);    GETCHAR(c, cc);
2362    if (c <= 127)    if (c <= 127)
# Line 1321  if (common->utf8) Line 2373  if (common->utf8)
2373  else  else
2374    {    {
2375    c = *cc;    c = *cc;
2376    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
2377    }    }
2378  #else  #else
2379  c = *cc;  c = *cc;
2380  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
2381  #endif  #endif
2382    
2383  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1336  if (c <= 127 && bit == 0x20) Line 2388  if (c <= 127 && bit == 0x20)
2388    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2389    
2390  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2391  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2392    return 0;    return 0;
2393    
2394  #ifdef SUPPORT_UTF8  #if defined COMPILE_PCRE8
2395  if (common->utf8 && c > 127)  
2396    #ifdef SUPPORT_UTF
2397    if (common->utf && c > 127)
2398    {    {
2399    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
2400    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
2401      {      {
2402      n--;      n--;
# Line 1350  if (common->utf8 && c > 127) Line 2404  if (common->utf8 && c > 127)
2404      }      }
2405    return (n << 8) | bit;    return (n << 8) | bit;
2406    }    }
2407  #endif  #endif /* SUPPORT_UTF */
2408  return (0 << 8) | bit;  return (0 << 8) | bit;
2409    
2410    #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2411    
2412    #ifdef SUPPORT_UTF
2413    if (common->utf && c > 65535)
2414      {
2415      if (bit >= (1 << 10))
2416        bit >>= 10;
2417      else
2418        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
2419      }
2420    #endif /* SUPPORT_UTF */
2421    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
2422    
2423    #endif /* COMPILE_PCRE[8|16|32] */
2424    }
2425    
2426    static void check_partial(compiler_common *common, BOOL force)
2427    {
2428    /* Checks whether a partial matching is occured. Does not modify registers. */
2429    DEFINE_COMPILER;
2430    struct sljit_jump *jump = NULL;
2431    
2432    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2433    
2434    if (common->mode == JIT_COMPILE)
2435      return;
2436    
2437    if (!force)
2438      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2439    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2440      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2441    
2442    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2443      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2444    else
2445      {
2446      if (common->partialmatchlabel != NULL)
2447        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2448      else
2449        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2450      }
2451    
2452    if (jump != NULL)
2453      JUMPHERE(jump);
2454    }
2455    
2456    static void check_str_end(compiler_common *common, jump_list **end_reached)
2457    {
2458    /* Does not affect registers. Usually used in a tight spot. */
2459    DEFINE_COMPILER;
2460    struct sljit_jump *jump;
2461    
2462    if (common->mode == JIT_COMPILE)
2463      {
2464      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2465      return;
2466      }
2467    
2468    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2469    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2470      {
2471      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2472      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2473      add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
2474      }
2475    else
2476      {
2477      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2478      if (common->partialmatchlabel != NULL)
2479        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2480      else
2481        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2482      }
2483    JUMPHERE(jump);
2484  }  }
2485    
2486  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2487  {  {
2488  DEFINE_COMPILER;  DEFINE_COMPILER;
2489  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
2490    
2491    if (common->mode == JIT_COMPILE)
2492      {
2493      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2494      return;
2495      }
2496    
2497    /* Partial matching mode. */
2498    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2499    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2500    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2501      {
2502      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2503      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2504      }
2505    else
2506      {
2507      if (common->partialmatchlabel != NULL)
2508        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2509      else
2510        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2511      }
2512    JUMPHERE(jump);
2513  }  }
2514    
2515  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1365  static void read_char(compiler_common *c Line 2517  static void read_char(compiler_common *c
2517  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2518  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2519  DEFINE_COMPILER;  DEFINE_COMPILER;
2520  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2521  struct sljit_jump *jump;  struct sljit_jump *jump;
2522  #endif  #endif
2523    
2524  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2525  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2526  if (common->utf8)  if (common->utf)
2527    {    {
2528    /* Should not found a value between 128 and 192 here. */  #if defined COMPILE_PCRE8
2529    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2530    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #elif defined COMPILE_PCRE16
2531      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2532    #endif /* COMPILE_PCRE[8|16] */
2533      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2534    JUMPHERE(jump);    JUMPHERE(jump);
2535    }    }
2536  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2537  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2538  }  }
2539    
2540  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1387  static void peek_char(compiler_common *c Line 2542  static void peek_char(compiler_common *c
2542  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2543  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2544  DEFINE_COMPILER;  DEFINE_COMPILER;
2545  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2546  struct sljit_jump *jump;  struct sljit_jump *jump;
2547  #endif  #endif
2548    
2549  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2550  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2551  if (common->utf8)  if (common->utf)
2552    {    {
2553    /* Should not found a value between 128 and 192 here. */  #if defined COMPILE_PCRE8
2554    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2555    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #elif defined COMPILE_PCRE16
2556      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2557    #endif /* COMPILE_PCRE[8|16] */
2558      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2559    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2560    JUMPHERE(jump);    JUMPHERE(jump);
2561    }    }
2562  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2563  }  }
2564    
2565  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2566  {  {
2567  /* 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. */
2568  DEFINE_COMPILER;  DEFINE_COMPILER;
2569  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2570  struct sljit_jump *jump;  struct sljit_jump *jump;
2571  #endif  #endif
2572    
2573  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2574  if (common->utf8)  if (common->utf)
2575    {    {
2576    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2577    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));
2578    #if defined COMPILE_PCRE8
2579    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2580    it is a clever early read in most cases. */    it is needed in most cases. */
2581    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2582    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2583    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  
2584    JUMPHERE(jump);    JUMPHERE(jump);
2585    #elif defined COMPILE_PCRE16
2586      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2587      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2588      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2589      JUMPHERE(jump);
2590      /* Skip low surrogate if necessary. */
2591      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2592      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2593      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2594      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2595      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2596    #elif defined COMPILE_PCRE32
2597      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2598      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2599      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2600      JUMPHERE(jump);
2601    #endif /* COMPILE_PCRE[8|16|32] */
2602    return;    return;
2603    }    }
2604    #endif /* SUPPORT_UTF */
2605    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2606    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2607    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2608    /* The ctypes array contains only 256 values. */
2609    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2610    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2611    #endif
2612    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2613    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2614    JUMPHERE(jump);
2615  #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);  
2616  }  }
2617    
2618  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2619  {  {
2620  /* 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. */
2621  DEFINE_COMPILER;  DEFINE_COMPILER;
2622  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2623    #if defined COMPILE_PCRE8
2624  struct sljit_label *label;  struct sljit_label *label;
2625    
2626  if (common->utf8)  if (common->utf)
2627    {    {
2628    label = LABEL();    label = LABEL();
2629    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2630    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));
2631    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2632    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2633    return;    return;
2634    }    }
2635  #endif  #elif defined COMPILE_PCRE16
2636  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2637      {
2638      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2639      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2640      /* Skip low surrogate if necessary. */
2641      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2642      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2643      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2644      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2645      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2646      return;
2647      }
2648    #endif /* COMPILE_PCRE[8|16] */
2649    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2650    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2651  }  }
2652    
2653  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)
2654  {  {
2655  /* 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. */
2656  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1460  DEFINE_COMPILER; Line 2658  DEFINE_COMPILER;
2658  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2659    {    {
2660    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2661    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));
2662    }    }
2663  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2664    {    {
2665    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);
2666    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2667    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);
2668    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);
2669    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));
2670    }    }
2671  else  else
2672    {    {
2673    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2674    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));
2675    }    }
2676  }  }
2677    
2678  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2679  static void do_utf8readchar(compiler_common *common)  
2680    #if defined COMPILE_PCRE8
2681    static void do_utfreadchar(compiler_common *common)
2682  {  {
2683  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2684  of the character (>= 192). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
2685  DEFINE_COMPILER;  DEFINE_COMPILER;
2686  struct sljit_jump *jump;  struct sljit_jump *jump;
2687    
2688  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2689  /* Searching for the first zero. */  /* Searching for the first zero. */
2690  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);
2691  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2692  /* 2 byte sequence */  /* Two byte sequence. */
2693  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2694  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));
2695  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2696  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2697  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2698  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2699  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2700  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2701  JUMPHERE(jump);  JUMPHERE(jump);
2702    
2703  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);
2704  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2705  /* 3 byte sequence */  /* Three byte sequence. */
2706  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2707  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2708  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2709  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2710  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2711  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2712  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2713  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));
2714  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2715  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2716  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2717  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2718  JUMPHERE(jump);  JUMPHERE(jump);
2719    
2720  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2721  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);  
2722  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2723  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2724  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2725  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2726  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2727  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
2728  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2729  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2730  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2731  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2732  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2733  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2734  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2735  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
2736  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2737  }  }
2738    
2739  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2740  {  {
2741  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2742  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2743  DEFINE_COMPILER;  DEFINE_COMPILER;
2744  struct sljit_jump *jump;  struct sljit_jump *jump;
2745  struct sljit_jump *compare;  struct sljit_jump *compare;
2746    
2747  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2748    
2749  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);
2750  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2751  /* 2 byte sequence */  /* Two byte sequence. */
2752  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2753  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));
2754  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2755  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2756  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1590  sljit_emit_fast_return(compiler, RETURN_ Line 2765  sljit_emit_fast_return(compiler, RETURN_
2765  JUMPHERE(jump);  JUMPHERE(jump);
2766    
2767  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2768  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
2769  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2770  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2771  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2772  }  }
2773    
2774  #endif  #elif defined COMPILE_PCRE16
2775    
2776    static void do_utfreadchar(compiler_common *common)
2777    {
2778    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2779    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2780    DEFINE_COMPILER;
2781    struct sljit_jump *jump;
2782    
2783    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2784    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2785    /* Do nothing, only return. */
2786    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2787    
2788    JUMPHERE(jump);
2789    /* Combine two 16 bit characters. */
2790    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2791    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2792    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2793    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2794    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2795    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2796    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2797    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2798    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2799    }
2800    
2801    #endif /* COMPILE_PCRE[8|16] */
2802    
2803    #endif /* SUPPORT_UTF */
2804    
2805  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2806    
# Line 1613  DEFINE_COMPILER; Line 2816  DEFINE_COMPILER;
2816    
2817  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2818    
2819  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2820  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2821  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));
2822  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2823  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2824  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2825  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2826  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2827  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));
2828  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2829  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2830  }  }
# Line 1635  struct sljit_label *newlinelabel = NULL; Line 2838  struct sljit_label *newlinelabel = NULL;
2838  struct sljit_jump *start;  struct sljit_jump *start;
2839  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2840  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2841    #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2842    struct sljit_jump *singlechar;
2843    #endif
2844  jump_list *newline = NULL;  jump_list *newline = NULL;
2845  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
2846  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
2847    
2848  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2849      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1646  if (!(hascrorlf || firstline) && (common Line 2852  if (!(hascrorlf || firstline) && (common
2852  if (firstline)  if (firstline)
2853    {    {
2854    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2855    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2856    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2857    
2858    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2859      {      {
2860      mainloop = LABEL();      mainloop = LABEL();
2861      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));
2862      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2863      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2864      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2865      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);
2866      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);
2867      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      JUMPHERE(end);
2868        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2869      }      }
2870    else    else
2871      {      {
2872      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2873      mainloop = LABEL();      mainloop = LABEL();
2874      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2875      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);
2876      read_char(common);      read_char(common);
2877      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2878      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2879      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2880        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2881      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2882      }      }
2883    
2884    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2885    }    }
2886    
2887  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1682  start = JUMP(SLJIT_JUMP); Line 2889  start = JUMP(SLJIT_JUMP);
2889  if (newlinecheck)  if (newlinecheck)
2890    {    {
2891    newlinelabel = LABEL();    newlinelabel = LABEL();
2892    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));
2893    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2894    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2895    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);
2896    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2897    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2898      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2899    #endif
2900    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2901    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2902    }    }
# Line 1694  if (newlinecheck) Line 2904  if (newlinecheck)
2904  mainloop = LABEL();  mainloop = LABEL();
2905    
2906  /* 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. */
2907  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2908  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2909  #endif  #endif
2910  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2911    
2912  if (readbyte)  if (readuchar)
2913    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2914    
2915  if (newlinecheck)  if (newlinecheck)
2916    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);
2917    
2918  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2919  if (common->utf8)  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2920    #if defined COMPILE_PCRE8
2921    if (common->utf)
2922    {    {
2923    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2924      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2925    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2926      JUMPHERE(singlechar);
2927    }    }
2928  else  #elif defined COMPILE_PCRE16
2929    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2930  #else    {
2931  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2932  #endif    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2933      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2934      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2935      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2936      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2937      JUMPHERE(singlechar);
2938      }
2939    #endif /* COMPILE_PCRE[8|16] */
2940    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2941  JUMPHERE(start);  JUMPHERE(start);
2942    
2943  if (newlinecheck)  if (newlinecheck)
# Line 1727  if (newlinecheck) Line 2949  if (newlinecheck)
2949  return mainloop;  return mainloop;
2950  }  }
2951    
2952  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  #define MAX_N_CHARS 3
2953    
2954    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2955    {
2956    DEFINE_COMPILER;
2957    struct sljit_label *start;
2958    struct sljit_jump *quit;
2959    pcre_uint32 chars[MAX_N_CHARS * 2];
2960    pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2961    int location = 0;
2962    pcre_int32 len, c, bit, caseless;
2963    int must_stop;
2964    
2965    /* We do not support alternatives now. */
2966    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2967      return FALSE;
2968    
2969    while (TRUE)
2970      {
2971      caseless = 0;
2972      must_stop = 1;
2973      switch(*cc)
2974        {
2975        case OP_CHAR:
2976        must_stop = 0;
2977        cc++;
2978        break;
2979    
2980        case OP_CHARI:
2981        caseless = 1;
2982        must_stop = 0;
2983        cc++;
2984        break;
2985    
2986        case OP_SOD:
2987        case OP_SOM:
2988        case OP_SET_SOM:
2989        case OP_NOT_WORD_BOUNDARY:
2990        case OP_WORD_BOUNDARY:
2991        case OP_EODN:
2992        case OP_EOD:
2993        case OP_CIRC:
2994        case OP_CIRCM:
2995        case OP_DOLL:
2996        case OP_DOLLM:
2997        /* Zero width assertions. */
2998        cc++;
2999        continue;
3000    
3001        case OP_PLUS:
3002        case OP_MINPLUS:
3003        case OP_POSPLUS:
3004        cc++;
3005        break;
3006    
3007        case OP_EXACT:
3008        cc += 1 + IMM2_SIZE;
3009        break;
3010    
3011        case OP_PLUSI:
3012        case OP_MINPLUSI:
3013        case OP_POSPLUSI:
3014        caseless = 1;
3015        cc++;
3016        break;
3017    
3018        case OP_EXACTI:
3019        caseless = 1;
3020        cc += 1 + IMM2_SIZE;
3021        break;
3022    
3023        default:
3024        must_stop = 2;
3025        break;
3026        }
3027    
3028      if (must_stop == 2)
3029          break;
3030    
3031      len = 1;
3032    #ifdef SUPPORT_UTF
3033      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
3034    #endif
3035    
3036      if (caseless && char_has_othercase(common, cc))
3037        {
3038        caseless = char_get_othercase_bit(common, cc);
3039        if (caseless == 0)
3040          return FALSE;
3041    #ifdef COMPILE_PCRE8
3042        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
3043    #else
3044        if ((caseless & 0x100) != 0)
3045          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
3046        else
3047          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
3048    #endif
3049        }
3050      else
3051        caseless = 0;
3052    
3053      while (len > 0 && location < MAX_N_CHARS * 2)
3054        {
3055        c = *cc;
3056        bit = 0;
3057        if (len == (caseless & 0xff))
3058          {
3059          bit = caseless >> 8;
3060          c |= bit;
3061          }
3062    
3063        chars[location] = c;
3064        chars[location + 1] = bit;
3065    
3066        len--;
3067        location += 2;
3068        cc++;
3069        }
3070    
3071      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
3072        break;
3073      }
3074    
3075    /* At least two characters are required. */
3076    if (location < 2 * 2)
3077        return FALSE;
3078    
3079    if (firstline)
3080      {
3081      SLJIT_ASSERT(common->first_line_end != 0);
3082      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3083      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3084      }
3085    else
3086      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3087    
3088    start = LABEL();
3089    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3090    
3091    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3092    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3093    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3094    if (chars[1] != 0)
3095      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3096    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3097    if (location > 2 * 2)
3098      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3099    if (chars[3] != 0)
3100      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
3101    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
3102    if (location > 2 * 2)
3103      {
3104      if (chars[5] != 0)
3105        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
3106      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
3107      }
3108    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3109    
3110    JUMPHERE(quit);
3111    
3112    if (firstline)
3113      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3114    else
3115      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3116    return TRUE;
3117    }
3118    
3119    #undef MAX_N_CHARS
3120    
3121    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
3122  {  {
3123  DEFINE_COMPILER;  DEFINE_COMPILER;
3124  struct sljit_label *start;  struct sljit_label *start;
3125  struct sljit_jump *leave;  struct sljit_jump *quit;
3126  struct sljit_jump *found;  struct sljit_jump *found;
3127  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
3128    
3129  if (firstline)  if (firstline)
3130    {    {
3131    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
3132    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3133      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3134    }    }
3135    
3136  start = LABEL();  start = LABEL();
3137  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3138  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3139    
3140  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
3141    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
3142      {
3143      oc = TABLE_GET(first_char, common->fcc, first_char);
3144    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
3145      if (first_char > 127 && common->utf)
3146        oc = UCD_OTHERCASE(first_char);
3147    #endif
3148      }
3149    if (first_char == oc)
3150      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
3151  else  else
3152    {    {
3153    firstbyte &= 0xff;    bit = first_char ^ oc;
3154    oc = common->fcc[firstbyte];    if (is_powerof2(bit))
   bit = firstbyte ^ oc;  
   if (ispowerof2(bit))  
3155      {      {
3156      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
3157      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
3158      }      }
3159    else    else
3160      {      {
3161      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);
3162      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3163      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);
3164      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);
3165      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
3166      }      }
3167    }    }
3168    
3169  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 if (common->utf8)  
   {  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #endif  
3170  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3171  JUMPHERE(found);  JUMPHERE(found);
3172  JUMPHERE(leave);  JUMPHERE(quit);
3173    
3174  if (firstline)  if (firstline)
3175    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3176  }  }
3177    
3178  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 1792  DEFINE_COMPILER; Line 3181  DEFINE_COMPILER;
3181  struct sljit_label *loop;  struct sljit_label *loop;
3182  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
3183  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
3184  struct sljit_jump *leave;  struct sljit_jump *quit;
3185  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
3186  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
3187  jump_list *newline = NULL;  jump_list *newline = NULL;
3188    
3189  if (firstline)  if (firstline)
3190    {    {
3191    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
3192    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3193      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3194    }    }
3195    
3196  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1811  if (common->nltype == NLTYPE_FIXED && co Line 3201  if (common->nltype == NLTYPE_FIXED && co
3201    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));
3202    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
3203    
3204    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
3205    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);
3206    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
3207    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3208      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
3209    #endif
3210    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3211    
3212    loop = LABEL();    loop = LABEL();
3213    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));
3214    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3215    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3216    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3217    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);
3218    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);
3219    
3220    JUMPHERE(leave);    JUMPHERE(quit);
3221    JUMPHERE(firstchar);    JUMPHERE(firstchar);
3222    JUMPHERE(lastchar);    JUMPHERE(lastchar);
3223    
# Line 1848  set_jumps(newline, loop); Line 3241  set_jumps(newline, loop);
3241    
3242  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
3243    {    {
3244    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
3245    JUMPHERE(foundcr);    JUMPHERE(foundcr);
3246    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3247    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3248    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);
3249    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3250    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3251      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3252    #endif
3253    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3254    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
3255    JUMPHERE(leave);    JUMPHERE(quit);
3256    }    }
3257  JUMPHERE(lastchar);  JUMPHERE(lastchar);
3258  JUMPHERE(firstchar);  JUMPHERE(firstchar);
3259    
3260  if (firstline)  if (firstline)
3261    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3262  }  }
3263    
3264    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3265    
3266  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)
3267  {  {
3268  DEFINE_COMPILER;  DEFINE_COMPILER;
3269  struct sljit_label *start;  struct sljit_label *start;
3270  struct sljit_jump *leave;  struct sljit_jump *quit;
3271  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3272    jump_list *matches = NULL;
3273    pcre_uint8 inverted_start_bits[32];
3274    int i;
3275    #ifndef COMPILE_PCRE8
3276    struct sljit_jump *jump;
3277    #endif
3278    
3279    for (i = 0; i < 32; ++i)
3280      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3281    
3282  if (firstline)  if (firstline)
3283    {    {
3284    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
3285    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
3286      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3287      }
3288    
3289    start = LABEL();
3290    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3291    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3292    #ifdef SUPPORT_UTF
3293    if (common->utf)
3294      OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3295    #endif
3296    
3297    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3298      {
3299    #ifndef COMPILE_PCRE8
3300      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3301      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3302      JUMPHERE(jump);
3303    #endif
3304      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3305      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3306      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3307      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3308      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3309      found = JUMP(SLJIT_C_NOT_ZERO);
3310    }    }
3311    
3312  start = LABEL();  #ifdef SUPPORT_UTF
3313  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  if (common->utf)
3314  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
 #ifdef SUPPORT_UTF8  
 if (common->utf8)  
   OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
 #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);  
   
 #ifdef SUPPORT_UTF8  
 if (common->utf8)  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);  
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
3315  #endif  #endif
3316    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3317    #ifdef SUPPORT_UTF
3318    #if defined COMPILE_PCRE8
3319    if (common->utf)
3320      {
3321      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
3322      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3323      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3324      }
3325    #elif defined COMPILE_PCRE16
3326    if (common->utf)
3327      {
3328      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
3329      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3330      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3331      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3332      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3333      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3334      }
3335    #endif /* COMPILE_PCRE[8|16] */
3336    #endif /* SUPPORT_UTF */
3337  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3338  JUMPHERE(found);  if (found != NULL)
3339  JUMPHERE(leave);    JUMPHERE(found);
3340    if (matches != NULL)
3341      set_jumps(matches, LABEL());
3342    JUMPHERE(quit);
3343    
3344  if (firstline)  if (firstline)
3345    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
3346  }  }
3347    
3348  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)
3349  {  {
3350  DEFINE_COMPILER;  DEFINE_COMPILER;
3351  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1917  struct sljit_jump *alreadyfound; Line 3354  struct sljit_jump *alreadyfound;
3354  struct sljit_jump *found;  struct sljit_jump *found;
3355  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
3356  struct sljit_jump *notfound;  struct sljit_jump *notfound;
3357  pcre_uint16 oc, bit;  pcre_uint32 oc, bit;
3358    
3359  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
3360    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
3361  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);
3362  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
3363  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
3364    
3365  if (has_firstbyte)  if (has_firstchar)
3366    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3367  else  else
3368    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
3369    
3370  loop = LABEL();  loop = LABEL();
3371  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
3372    
3373  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3374  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
3375    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
3376      {
3377      oc = TABLE_GET(req_char, common->fcc, req_char);
3378    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
3379      if (req_char > 127 && common->utf)
3380        oc = UCD_OTHERCASE(req_char);
3381    #endif
3382      }
3383    if (req_char == oc)
3384      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
3385  else  else
3386    {    {
3387    reqbyte &= 0xff;    bit = req_char ^ oc;
3388    oc = common->fcc[reqbyte];    if (is_powerof2(bit))
   bit = reqbyte ^ oc;  
   if (ispowerof2(bit))  
3389      {      {
3390      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3391      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
3392      }      }
3393    else    else
3394      {      {
3395      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
3396      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
3397      }      }
3398    }    }
3399  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3400  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
3401    
3402  JUMPHERE(found);  JUMPHERE(found);
3403  if (foundoc)  if (foundoc)
3404    JUMPHERE(foundoc);    JUMPHERE(foundoc);
3405  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);
3406  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
3407  JUMPHERE(toolong);  JUMPHERE(toolong);
3408  return notfound;  return notfound;
# Line 1966  return notfound; Line 3411  return notfound;
3411  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
3412  {  {
3413  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
3414  struct sljit_jump *jump;  struct sljit_jump *jump;
3415  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3416    
3417  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3418  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3419    GET_LOCAL_BASE(TMP3, 0, 0);
3420    
3421  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
3422  mainloop = LABEL();  mainloop = LABEL();
3423  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3424  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);
3425  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3426  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
3427  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);
3428  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));
3429    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3430    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
3431  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3432    
3433  JUMPHERE(jump);  JUMPHERE(jump);
3434  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3435  /* End of dropping frames. */  /* End of dropping frames. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
 CMPTO(SLJIT_C_GREATER_EQUAL, TMP1, 0, STACK_TOP, 0, mainloop);  
 JUMPHERE(earlyexit);  
3436  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3437    
3438  JUMPHERE(jump);  JUMPHERE(jump);
3439  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3440  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3441  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3442  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));  
3443  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3444  }  }
3445    
3446  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3447  {  {
3448  DEFINE_COMPILER;  DEFINE_COMPILER;
3449  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3450  #ifdef SUPPORT_UTF8  jump_list *skipread_list = NULL;
3451    #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3452  struct sljit_jump *jump;  struct sljit_jump *jump;
3453  #endif  #endif
3454    
3455  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3456    
3457  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);
3458  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3459  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3460  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));
3461  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3462  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3463  skip_char_back(common);  skip_char_back(common);
3464    check_start_used_ptr(common);
3465  read_char(common);  read_char(common);
3466    
3467  /* Testing char type. */  /* Testing char type. */
3468  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3469  if (common->useucp)  if (common->use_ucp)
3470    {    {
3471    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3472    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3473    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3474    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3475    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);
3476    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3477    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);
3478    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);
3479    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3480    JUMPHERE(jump);    JUMPHERE(jump);
3481    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3482    }    }
3483  else  else
3484  #endif  #endif
3485    {    {
3486  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3487      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3488    #elif defined SUPPORT_UTF
3489    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3490    jump = NULL;    jump = NULL;
3491    if (common->utf8)    if (common->utf)
3492      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3493  #endif  #endif /* COMPILE_PCRE8 */
3494    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3495    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3496    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3497    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3498  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3499      JUMPHERE(jump);
3500    #elif defined SUPPORT_UTF
3501    if (jump != NULL)    if (jump != NULL)
3502      JUMPHERE(jump);      JUMPHERE(jump);
3503  #endif  #endif /* COMPILE_PCRE8 */
3504    }    }
3505  JUMPHERE(beginend);  JUMPHERE(skipread);
3506    
3507  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3508  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  check_str_end(common, &skipread_list);
3509  peek_char(common);  peek_char(common);
3510    
3511  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3512  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3513  if (common->useucp)  if (common->use_ucp)
3514    {    {
3515    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3516    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3517    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3518    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);