/[pcre]/code/trunk/pcre_jit_compile.c
ViewVC logotype

Diff of /code/trunk/pcre_jit_compile.c

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

revision 941 by zherczeg, Tue Feb 28 11:33:34 2012 UTC revision 1371 by zherczeg, Fri Oct 11 10:59: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-2012 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-2012                        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
# Line 65  system files. */ Line 65  system files. */
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 82  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 108  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 {
# Line 154  typedef struct jit_arguments { Line 166  typedef struct jit_arguments {
166    int *offsets;    int *offsets;
167    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169      void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171    int offsetcount;    pcre_uint32 limit_match;
172    int calllimit;    int real_offset_count;
173      int offset_count;
174    pcre_uint8 notbol;    pcre_uint8 notbol;
175    pcre_uint8 noteol;    pcre_uint8 noteol;
176    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 167  typedef struct executable_functions { Line 181  typedef struct executable_functions {
181    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
183    void *userdata;    void *userdata;
184      pcre_uint32 top_bracket;
185      pcre_uint32 limit_match;
186    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
187  } executable_functions;  } executable_functions;
188    
# Line 175  typedef struct jump_list { Line 191  typedef struct jump_list {
191    struct jump_list *next;    struct jump_list *next;
192  } jump_list;  } jump_list;
193    
 enum stub_types { stack_alloc };  
   
194  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   int data;  
195    struct sljit_jump *start;    struct sljit_jump *start;
196    struct sljit_label *leave;    struct sljit_label *quit;
197    struct stub_list *next;    struct stub_list *next;
198  } stub_list;  } stub_list;
199    
200    enum frame_types {
201      no_frame = -1,
202      no_stack = -2
203    };
204    
205    enum control_types {
206      type_mark = 0,
207      type_then_trap = 1
208    };
209    
210  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
211    
212  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
213  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
214  the aguments for compile_fallbackpath. Must be the first member  the arguments for compile_backtrackingpath. Must be the first member
215  of its descendants. */  of its descendants. */
216  typedef struct fallback_common {  typedef struct backtrack_common {
217    /* Concatenation stack. */    /* Concatenation stack. */
218    struct fallback_common *prev;    struct backtrack_common *prev;
219    jump_list *nextfallbacks;    jump_list *nextbacktracks;
220    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
221    struct fallback_common *top;    struct backtrack_common *top;
222    jump_list *topfallbacks;    jump_list *topbacktracks;
223    /* Opcode pointer. */    /* Opcode pointer. */
224    pcre_uchar *cc;    pcre_uchar *cc;
225  } fallback_common;  } backtrack_common;
226    
227  typedef struct assert_fallback {  typedef struct assert_backtrack {
228    fallback_common common;    backtrack_common common;
229    jump_list *condfailed;    jump_list *condfailed;
230    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
231    int framesize;    int framesize;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int localptr;    int private_data_ptr;
234    /* For iterators. */    /* For iterators. */
235    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
236  } assert_fallback;  } assert_backtrack;
237    
238  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
239    fallback_common common;    backtrack_common common;
240    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
241    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
242    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
243    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
244    /* For greedy ? operator. */    /* For greedy ? operator. */
245    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
246    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
247    union {    union {
248      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
249      jump_list *condfailed;      jump_list *condfailed;
250      assert_fallback *assert;      assert_backtrack *assert;
251      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
252      int framesize;      int framesize;
253    } u;    } u;
254    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
255    int localptr;    int private_data_ptr;
256  } bracket_fallback;  } bracket_backtrack;
257    
258  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
259    fallback_common common;    backtrack_common common;
260    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
261    int localptr;    int private_data_ptr;
262    /* Reverting stack is needed. */    /* Reverting stack is needed. */
263    int framesize;    int framesize;
264    /* Allocated stack size. */    /* Allocated stack size. */
265    int stacksize;    int stacksize;
266  } bracketpos_fallback;  } bracketpos_backtrack;
267    
268  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
269    fallback_common common;    backtrack_common common;
270    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
271  } braminzero_fallback;  } braminzero_backtrack;
272    
273  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
274    fallback_common common;    backtrack_common common;
275    /* Next iteration. */    /* Next iteration. */
276    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
277  } iterator_fallback;  } iterator_backtrack;
278    
279  typedef struct recurse_entry {  typedef struct recurse_entry {
280    struct recurse_entry *next;    struct recurse_entry *next;
# Line 261  typedef struct recurse_entry { Line 283  typedef struct recurse_entry {
283    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
284    jump_list *calls;    jump_list *calls;
285    /* Points to the starting opcode. */    /* Points to the starting opcode. */
286    int start;    sljit_sw start;
287  } recurse_entry;  } recurse_entry;
288    
289  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
290    fallback_common common;    backtrack_common common;
291  } recurse_fallback;    BOOL inlined_pattern;
292    } recurse_backtrack;
293    
294    #define OP_THEN_TRAP OP_TABLE_LENGTH
295    
296    typedef struct then_trap_backtrack {
297      backtrack_common common;
298      /* If then_trap is not NULL, this structure contains the real
299      then_trap for the backtracking path. */
300      struct then_trap_backtrack *then_trap;
301      /* Points to the starting opcode. */
302      sljit_sw start;
303      /* Exit point for the then opcodes of this alternative. */
304      jump_list *quit;
305      /* Frame size of the current alternative. */
306      int framesize;
307    } then_trap_backtrack;
308    
309    #define MAX_RANGE_SIZE 6
310    
311  typedef struct compiler_common {  typedef struct compiler_common {
312      /* The sljit ceneric compiler. */
313    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
314      /* First byte code. */
315    pcre_uchar *start;    pcre_uchar *start;
316      /* Maps private data offset to each opcode. */
317    /* Local stack area size and variable pointers. */    sljit_si *private_data_ptrs;
318    int localsize;    /* Tells whether the capturing bracket is optimized. */
319    int *localptrs;    pcre_uint8 *optimized_cbracket;
320    int cbraptr;    /* Tells whether the starting offset is a target of then. */
321    /* OVector starting point. Must be divisible by 2. */    pcre_uint8 *then_offsets;
322      /* Current position where a THEN must jump. */
323      then_trap_backtrack *then_trap;
324      /* Starting offset of private data for capturing brackets. */
325      int cbra_ptr;
326      /* Output vector starting point. Must be divisible by 2. */
327    int ovector_start;    int ovector_start;
328    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
329    int req_char_ptr;    int req_char_ptr;
330    /* Head of the last recursion. */    /* Head of the last recursion. */
331    int recursive_head;    int recursive_head_ptr;
332    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
333    int start_used_ptr;    int start_used_ptr;
334    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 290  typedef struct compiler_common { Line 337  typedef struct compiler_common {
337    int first_line_end;    int first_line_end;
338    /* Points to the marked string. */    /* Points to the marked string. */
339    int mark_ptr;    int mark_ptr;
340      /* Recursive control verb management chain. */
341      int control_head_ptr;
342      /* Points to the last matched capture block index. */
343      int capture_last_ptr;
344      /* Points to the starting position of the current match. */
345      int start_ptr;
346    
347    /* Other  */    /* Flipped and lower case tables. */
348    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
349    sljit_w lcc;    sljit_sw lcc;
350      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
351    int mode;    int mode;
352      /* \K is found in the pattern. */
353      BOOL has_set_som;
354      /* (*SKIP:arg) is found in the pattern. */
355      BOOL has_skip_arg;
356      /* (*THEN) is found in the pattern. */
357      BOOL has_then;
358      /* Needs to know the start position anytime. */
359      BOOL needs_start_ptr;
360      /* Currently in recurse or negative assert. */
361      BOOL local_exit;
362      /* Currently in a positive assert. */
363      BOOL positive_assert;
364      /* Newline control. */
365    int nltype;    int nltype;
366    int newline;    int newline;
367    int bsr_nltype;    int bsr_nltype;
368      /* Dollar endonly. */
369    int endonly;    int endonly;
370    BOOL has_set_som;    /* Tables. */
371    sljit_w ctypes;    sljit_sw ctypes;
372    sljit_uw name_table;    int digits[2 + MAX_RANGE_SIZE];
373    sljit_w name_count;    /* Named capturing brackets. */
374    sljit_w name_entry_size;    pcre_uchar *name_table;
375      sljit_sw name_count;
376      sljit_sw name_entry_size;
377    
378    /* Labels and jump lists. */    /* Labels and jump lists. */
379    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
380    struct sljit_label *leavelabel;    struct sljit_label *quit_label;
381    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
382      struct sljit_label *accept_label;
383    stub_list *stubs;    stub_list *stubs;
384    recurse_entry *entries;    recurse_entry *entries;
385    recurse_entry *currententry;    recurse_entry *currententry;
386    jump_list *partialmatch;    jump_list *partialmatch;
387    jump_list *leave;    jump_list *quit;
388      jump_list *positive_assert_quit;
389      jump_list *forced_quit;
390    jump_list *accept;    jump_list *accept;
391    jump_list *calllimit;    jump_list *calllimit;
392    jump_list *stackalloc;    jump_list *stackalloc;
# Line 324  typedef struct compiler_common { Line 397  typedef struct compiler_common {
397    jump_list *vspace;    jump_list *vspace;
398    jump_list *casefulcmp;    jump_list *casefulcmp;
399    jump_list *caselesscmp;    jump_list *caselesscmp;
400      jump_list *reset_match;
401    BOOL jscript_compat;    BOOL jscript_compat;
402  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
403    BOOL utf;    BOOL utf;
404  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
405    BOOL use_ucp;    BOOL use_ucp;
406  #endif  #endif
407    #ifndef COMPILE_PCRE32
408    jump_list *utfreadchar;    jump_list *utfreadchar;
409    #endif
410  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
411    jump_list *utfreadtype8;    jump_list *utfreadtype8;
412  #endif  #endif
# Line 348  typedef struct compare_context { Line 424  typedef struct compare_context {
424  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
425    int ucharptr;    int ucharptr;
426    union {    union {
427      sljit_i asint;      sljit_si asint;
428      sljit_uh asushort;      sljit_uh asushort;
429  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
430      sljit_ub asbyte;      sljit_ub asbyte;
431      sljit_ub asuchars[4];      sljit_ub asuchars[4];
432  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
433      sljit_uh asuchars[2];      sljit_uh asuchars[2];
434  #endif  #elif defined COMPILE_PCRE32
435        sljit_ui asuchars[1];
436  #endif  #endif
437    } c;    } c;
438    union {    union {
439      sljit_i asint;      sljit_si asint;
440      sljit_uh asushort;      sljit_uh asushort;
441  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
442      sljit_ub asbyte;      sljit_ub asbyte;
443      sljit_ub asuchars[4];      sljit_ub asuchars[4];
444  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
445      sljit_uh asuchars[2];      sljit_uh asuchars[2];
446  #endif  #elif defined COMPILE_PCRE32
447        sljit_ui asuchars[1];
448  #endif  #endif
449    } oc;    } oc;
450  #endif  #endif
451  } compare_context;  } compare_context;
452    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
453  /* Undefine sljit macros. */  /* Undefine sljit macros. */
454  #undef CMP  #undef CMP
455    
456  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
457  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
458    
459  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
460  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
461  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
462  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_SAVED_REG1
463  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_SAVED_REG2
464  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
465  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
466  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
467  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define COUNT_MATCH   SLJIT_SAVED_EREG2
468  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
469    
470  /* Locals layout. */  /* Local space layout. */
471  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
472  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
473  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
474  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
475  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
476  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
477  /* Max limit of recursions. */  /* Max limit of recursions. */
478  #define CALL_LIMIT       (4 * sizeof(sljit_w))  #define LIMIT_MATCH      (4 * sizeof(sljit_sw))
479  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
480  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
481  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
482  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. */
483  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
484  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * (sljit_sw)sizeof(sljit_sw))
485  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * (sljit_sw)sizeof(sljit_sw))
486  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
487    
488  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
489  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
490  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
491  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
492  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
493  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
494    #elif defined COMPILE_PCRE32
495    #define MOV_UCHAR  SLJIT_MOV_UI
496    #define MOVU_UCHAR SLJIT_MOVU_UI
497  #else  #else
498  #error Unsupported compiling mode  #error Unsupported compiling mode
499  #endif  #endif
 #endif  
500    
501  /* Shortcuts. */  /* Shortcuts. */
502  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 442  the start pointers when the end of the c Line 513  the start pointers when the end of the c
513    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
514  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
515    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
516    #define SET_LABEL(jump, label) \
517      sljit_set_label((jump), (label))
518  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
519    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
520  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
521    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))
522  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
523    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
524    #define GET_LOCAL_BASE(dst, dstw, offset) \
525      sljit_get_local_base(compiler, (dst), (dstw), (offset))
526    
527  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
528  {  {
# Line 460  return cc; Line 535  return cc;
535    
536  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
537   next_opcode   next_opcode
538   get_localspace   check_opcode_types
539   set_localptrs   set_private_data_ptrs
540   get_framesize   get_framesize
541   init_frame   init_frame
542   get_localsize   get_private_data_copy_length
543   copy_locals   copy_private_data
544   compile_hotpath   compile_matchingpath
545   compile_fallbackpath   compile_backtrackingpath
546  */  */
547    
548  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 488  switch(*cc) Line 563  switch(*cc)
563    case OP_WORDCHAR:    case OP_WORDCHAR:
564    case OP_ANY:    case OP_ANY:
565    case OP_ALLANY:    case OP_ALLANY:
566      case OP_NOTPROP:
567      case OP_PROP:
568    case OP_ANYNL:    case OP_ANYNL:
569    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
570    case OP_HSPACE:    case OP_HSPACE:
# Line 500  switch(*cc) Line 577  switch(*cc)
577    case OP_CIRCM:    case OP_CIRCM:
578    case OP_DOLL:    case OP_DOLL:
579    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:  
580    case OP_CRSTAR:    case OP_CRSTAR:
581    case OP_CRMINSTAR:    case OP_CRMINSTAR:
582    case OP_CRPLUS:    case OP_CRPLUS:
583    case OP_CRMINPLUS:    case OP_CRMINPLUS:
584    case OP_CRQUERY:    case OP_CRQUERY:
585    case OP_CRMINQUERY:    case OP_CRMINQUERY:
586      case OP_CRRANGE:
587      case OP_CRMINRANGE:
588      case OP_CLASS:
589      case OP_NCLASS:
590      case OP_REF:
591      case OP_REFI:
592      case OP_DNREF:
593      case OP_DNREFI:
594      case OP_RECURSE:
595      case OP_CALLOUT:
596      case OP_ALT:
597      case OP_KET:
598      case OP_KETRMAX:
599      case OP_KETRMIN:
600      case OP_KETRPOS:
601      case OP_REVERSE:
602      case OP_ASSERT:
603      case OP_ASSERT_NOT:
604      case OP_ASSERTBACK:
605      case OP_ASSERTBACK_NOT:
606      case OP_ONCE:
607      case OP_ONCE_NC:
608      case OP_BRA:
609      case OP_BRAPOS:
610      case OP_CBRA:
611      case OP_CBRAPOS:
612      case OP_COND:
613      case OP_SBRA:
614      case OP_SBRAPOS:
615      case OP_SCBRA:
616      case OP_SCBRAPOS:
617      case OP_SCOND:
618      case OP_CREF:
619      case OP_DNCREF:
620      case OP_RREF:
621      case OP_DNRREF:
622    case OP_DEF:    case OP_DEF:
623    case OP_BRAZERO:    case OP_BRAZERO:
624    case OP_BRAMINZERO:    case OP_BRAMINZERO:
625    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
626      case OP_PRUNE:
627      case OP_SKIP:
628      case OP_THEN:
629    case OP_COMMIT:    case OP_COMMIT:
630    case OP_FAIL:    case OP_FAIL:
631    case OP_ACCEPT:    case OP_ACCEPT:
632    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
633      case OP_CLOSE:
634    case OP_SKIPZERO:    case OP_SKIPZERO:
635    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
636    
637    case OP_CHAR:    case OP_CHAR:
638    case OP_CHARI:    case OP_CHARI:
# Line 542  switch(*cc) Line 644  switch(*cc)
644    case OP_MINPLUS:    case OP_MINPLUS:
645    case OP_QUERY:    case OP_QUERY:
646    case OP_MINQUERY:    case OP_MINQUERY:
647      case OP_UPTO:
648      case OP_MINUPTO:
649      case OP_EXACT:
650    case OP_POSSTAR:    case OP_POSSTAR:
651    case OP_POSPLUS:    case OP_POSPLUS:
652    case OP_POSQUERY:    case OP_POSQUERY:
653      case OP_POSUPTO:
654    case OP_STARI:    case OP_STARI:
655    case OP_MINSTARI:    case OP_MINSTARI:
656    case OP_PLUSI:    case OP_PLUSI:
657    case OP_MINPLUSI:    case OP_MINPLUSI:
658    case OP_QUERYI:    case OP_QUERYI:
659    case OP_MINQUERYI:    case OP_MINQUERYI:
660      case OP_UPTOI:
661      case OP_MINUPTOI:
662      case OP_EXACTI:
663    case OP_POSSTARI:    case OP_POSSTARI:
664    case OP_POSPLUSI:    case OP_POSPLUSI:
665    case OP_POSQUERYI:    case OP_POSQUERYI:
666      case OP_POSUPTOI:
667    case OP_NOTSTAR:    case OP_NOTSTAR:
668    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
669    case OP_NOTPLUS:    case OP_NOTPLUS:
670    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
671    case OP_NOTQUERY:    case OP_NOTQUERY:
672    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
673      case OP_NOTUPTO:
674      case OP_NOTMINUPTO:
675      case OP_NOTEXACT:
676    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
677    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
678    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
679      case OP_NOTPOSUPTO:
680    case OP_NOTSTARI:    case OP_NOTSTARI:
681    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
682    case OP_NOTPLUSI:    case OP_NOTPLUSI:
683    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
684    case OP_NOTQUERYI:    case OP_NOTQUERYI:
685    case OP_NOTMINQUERYI:    case OP_NOTMINQUERYI:
   case OP_NOTPOSSTARI:  
   case OP_NOTPOSPLUSI:  
   case OP_NOTPOSQUERYI:  
   cc += 2;  
 #ifdef SUPPORT_UTF  
   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #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:  
686    case OP_NOTUPTOI:    case OP_NOTUPTOI:
687    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
688    case OP_NOTEXACTI:    case OP_NOTEXACTI:
689      case OP_NOTPOSSTARI:
690      case OP_NOTPOSPLUSI:
691      case OP_NOTPOSQUERYI:
692    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
693    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
694  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
695    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
696  #endif  #endif
697    return cc;    return cc;
698    
699    case OP_NOTPROP:    /* Special cases. */
700    case OP_PROP:    case OP_TYPESTAR:
701    return cc + 1 + 2;    case OP_TYPEMINSTAR:
702      case OP_TYPEPLUS:
703      case OP_TYPEMINPLUS:
704      case OP_TYPEQUERY:
705      case OP_TYPEMINQUERY:
706    case OP_TYPEUPTO:    case OP_TYPEUPTO:
707    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
708    case OP_TYPEEXACT:    case OP_TYPEEXACT:
709      case OP_TYPEPOSSTAR:
710      case OP_TYPEPOSPLUS:
711      case OP_TYPEPOSQUERY:
712    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
713    case OP_REF:    return cc + PRIV(OP_lengths)[*cc] - 1;
   case OP_REFI:  
   case OP_CREF:  
   case OP_NCREF:  
   case OP_RREF:  
   case OP_NRREF:  
   case OP_CLOSE:  
   cc += 1 + IMM2_SIZE;  
   return cc;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   return cc + 1 + 2 * IMM2_SIZE;  
714    
715    case OP_CLASS:    case OP_ANYBYTE:
716    case OP_NCLASS:  #ifdef SUPPORT_UTF
717    return cc + 1 + 32 / sizeof(pcre_uchar);    if (common->utf) return NULL;
718    #endif
719      return cc + 1;
720    
721  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
722    case OP_XCLASS:    case OP_XCLASS:
723    return cc + GET(cc, 1);    return cc + GET(cc, 1);
724  #endif  #endif
725    
   case OP_RECURSE:  
   case OP_ASSERT:  
   case OP_ASSERT_NOT:  
   case OP_ASSERTBACK:  
   case OP_ASSERTBACK_NOT:  
   case OP_REVERSE:  
   case OP_ONCE:  
   case OP_ONCE_NC:  
   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 + IMM2_SIZE;  
   
726    case OP_MARK:    case OP_MARK:
727      case OP_PRUNE_ARG:
728      case OP_SKIP_ARG:
729      case OP_THEN_ARG:
730    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
731    
732    default:    default:
733      /* All opcodes are supported now! */
734      SLJIT_ASSERT_STOP();
735    return NULL;    return NULL;
736    }    }
737  }  }
738    
739  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static BOOL check_opcode_types(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
740  {  {
741  int localspace = 0;  int count;
742  pcre_uchar *alternative;  pcre_uchar *slot;
743    
744  /* 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. */
745  while (cc < ccend)  while (cc < ccend)
746    {    {
# Line 680  while (cc < ccend) Line 751  while (cc < ccend)
751      cc += 1;      cc += 1;
752      break;      break;
753    
754      case OP_ASSERT:      case OP_REF:
755      case OP_ASSERT_NOT:      case OP_REFI:
756      case OP_ASSERTBACK:      common->optimized_cbracket[GET2(cc, 1)] = 0;
757      case OP_ASSERTBACK_NOT:      cc += 1 + IMM2_SIZE;
     case OP_ONCE:  
     case OP_ONCE_NC:  
     case OP_BRAPOS:  
     case OP_SBRA:  
     case OP_SBRAPOS:  
     case OP_SCOND:  
     localspace += sizeof(sljit_w);  
     cc += 1 + LINK_SIZE;  
758      break;      break;
759    
760      case OP_CBRAPOS:      case OP_CBRAPOS:
761      case OP_SCBRAPOS:      case OP_SCBRAPOS:
762      localspace += sizeof(sljit_w);      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
763      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
764      break;      break;
765    
766      case OP_COND:      case OP_COND:
767      /* Might be a hidden SCOND. */      case OP_SCOND:
768      alternative = cc + GET(cc, 1);      /* Only AUTO_CALLOUT can insert this opcode. We do
769      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)         not intend to support this case. */
770        localspace += sizeof(sljit_w);      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
771          return FALSE;
772      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
773      break;      break;
774    
775        case OP_CREF:
776        common->optimized_cbracket[GET2(cc, 1)] = 0;
777        cc += 1 + IMM2_SIZE;
778        break;
779    
780        case OP_DNREF:
781        case OP_DNREFI:
782        case OP_DNCREF:
783        count = GET2(cc, 1 + IMM2_SIZE);
784        slot = common->name_table + GET2(cc, 1) * common->name_entry_size;
785        while (count-- > 0)
786          {
787          common->optimized_cbracket[GET2(slot, 0)] = 0;
788          slot += common->name_entry_size;
789          }
790        cc += 1 + 2 * IMM2_SIZE;
791        break;
792    
793      case OP_RECURSE:      case OP_RECURSE:
794      /* Set its value only once. */      /* Set its value only once. */
795      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
796        {        {
797        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
798        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
799        }        }
800      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
801      break;      break;
802    
803        case OP_CALLOUT:
804        if (common->capture_last_ptr == 0)
805          {
806          common->capture_last_ptr = common->ovector_start;
807          common->ovector_start += sizeof(sljit_sw);
808          }
809        cc += 2 + 2 * LINK_SIZE;
810        break;
811    
812        case OP_THEN_ARG:
813        common->has_then = TRUE;
814        common->control_head_ptr = 1;
815        /* Fall through. */
816    
817        case OP_PRUNE_ARG:
818        common->needs_start_ptr = TRUE;
819        /* Fall through. */
820    
821      case OP_MARK:      case OP_MARK:
822      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
823        {        {
824        common->mark_ptr = common->ovector_start;        common->mark_ptr = common->ovector_start;
825        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
826        }        }
827      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
828      break;      break;
829    
830        case OP_THEN:
831        common->has_then = TRUE;
832        common->control_head_ptr = 1;
833        /* Fall through. */
834    
835        case OP_PRUNE:
836        case OP_SKIP:
837        common->needs_start_ptr = TRUE;
838        cc += 1;
839        break;
840    
841        case OP_SKIP_ARG:
842        common->control_head_ptr = 1;
843        common->has_skip_arg = TRUE;
844        cc += 1 + 2 + cc[1];
845        break;
846    
847      default:      default:
848      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
849      if (cc == NULL)      if (cc == NULL)
850        return -1;        return FALSE;
851      break;      break;
852      }      }
853    }    }
854  return localspace;  return TRUE;
855    }
856    
857    static int get_class_iterator_size(pcre_uchar *cc)
858    {
859    switch(*cc)
860      {
861      case OP_CRSTAR:
862      case OP_CRPLUS:
863      return 2;
864    
865      case OP_CRMINSTAR:
866      case OP_CRMINPLUS:
867      case OP_CRQUERY:
868      case OP_CRMINQUERY:
869      return 1;
870    
871      case OP_CRRANGE:
872      case OP_CRMINRANGE:
873      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
874        return 0;
875      return 2;
876    
877      default:
878      return 0;
879      }
880  }  }
881    
882  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static BOOL detect_repeat(compiler_common *common, pcre_uchar *begin)
883    {
884    pcre_uchar *end = bracketend(begin);
885    pcre_uchar *next;
886    pcre_uchar *next_end;
887    pcre_uchar *max_end;
888    pcre_uchar type;
889    sljit_sw length = end - begin;
890    int min, max, i;
891    
892    /* Detect fixed iterations first. */
893    if (end[-(1 + LINK_SIZE)] != OP_KET)
894      return FALSE;
895    
896    /* Already detected repeat. */
897    if (common->private_data_ptrs[end - common->start - LINK_SIZE] != 0)
898      return TRUE;
899    
900    next = end;
901    min = 1;
902    while (1)
903      {
904      if (*next != *begin)
905        break;
906      next_end = bracketend(next);
907      if (next_end - next != length || memcmp(begin, next, IN_UCHARS(length)) != 0)
908        break;
909      next = next_end;
910      min++;
911      }
912    
913    if (min == 2)
914      return FALSE;
915    
916    max = 0;
917    max_end = next;
918    if (*next == OP_BRAZERO || *next == OP_BRAMINZERO)
919      {
920      type = *next;
921      while (1)
922        {
923        if (next[0] != type || next[1] != OP_BRA || next[2 + LINK_SIZE] != *begin)
924          break;
925        next_end = bracketend(next + 2 + LINK_SIZE);
926        if (next_end - next != (length + 2 + LINK_SIZE) || memcmp(begin, next + 2 + LINK_SIZE, IN_UCHARS(length)) != 0)
927          break;
928        next = next_end;
929        max++;
930        }
931    
932      if (next[0] == type && next[1] == *begin && max >= 1)
933        {
934        next_end = bracketend(next + 1);
935        if (next_end - next == (length + 1) && memcmp(begin, next + 1, IN_UCHARS(length)) == 0)
936          {
937          for (i = 0; i < max; i++, next_end += 1 + LINK_SIZE)
938            if (*next_end != OP_KET)
939              break;
940    
941          if (i == max)
942            {
943            common->private_data_ptrs[max_end - common->start - LINK_SIZE] = next_end - max_end;
944            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 1] = (type == OP_BRAZERO) ? OP_UPTO : OP_MINUPTO;
945            /* +2 the original and the last. */
946            common->private_data_ptrs[max_end - common->start - LINK_SIZE + 2] = max + 2;
947            if (min == 1)
948              return TRUE;
949            min--;
950            max_end -= (1 + LINK_SIZE) + GET(max_end, -LINK_SIZE);
951            }
952          }
953        }
954      }
955    
956    if (min >= 3)
957      {
958      common->private_data_ptrs[end - common->start - LINK_SIZE] = max_end - end;
959      common->private_data_ptrs[end - common->start - LINK_SIZE + 1] = OP_EXACT;
960      common->private_data_ptrs[end - common->start - LINK_SIZE + 2] = min;
961      return TRUE;
962      }
963    
964    return FALSE;
965    }
966    
967    #define CASE_ITERATOR_PRIVATE_DATA_1 \
968        case OP_MINSTAR: \
969        case OP_MINPLUS: \
970        case OP_QUERY: \
971        case OP_MINQUERY: \
972        case OP_MINSTARI: \
973        case OP_MINPLUSI: \
974        case OP_QUERYI: \
975        case OP_MINQUERYI: \
976        case OP_NOTMINSTAR: \
977        case OP_NOTMINPLUS: \
978        case OP_NOTQUERY: \
979        case OP_NOTMINQUERY: \
980        case OP_NOTMINSTARI: \
981        case OP_NOTMINPLUSI: \
982        case OP_NOTQUERYI: \
983        case OP_NOTMINQUERYI:
984    
985    #define CASE_ITERATOR_PRIVATE_DATA_2A \
986        case OP_STAR: \
987        case OP_PLUS: \
988        case OP_STARI: \
989        case OP_PLUSI: \
990        case OP_NOTSTAR: \
991        case OP_NOTPLUS: \
992        case OP_NOTSTARI: \
993        case OP_NOTPLUSI:
994    
995    #define CASE_ITERATOR_PRIVATE_DATA_2B \
996        case OP_UPTO: \
997        case OP_MINUPTO: \
998        case OP_UPTOI: \
999        case OP_MINUPTOI: \
1000        case OP_NOTUPTO: \
1001        case OP_NOTMINUPTO: \
1002        case OP_NOTUPTOI: \
1003        case OP_NOTMINUPTOI:
1004    
1005    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
1006        case OP_TYPEMINSTAR: \
1007        case OP_TYPEMINPLUS: \
1008        case OP_TYPEQUERY: \
1009        case OP_TYPEMINQUERY:
1010    
1011    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
1012        case OP_TYPESTAR: \
1013        case OP_TYPEPLUS:
1014    
1015    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
1016        case OP_TYPEUPTO: \
1017        case OP_TYPEMINUPTO:
1018    
1019    static void set_private_data_ptrs(compiler_common *common, int *private_data_start, pcre_uchar *ccend)
1020  {  {
1021  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1022  pcre_uchar *alternative;  pcre_uchar *alternative;
1023    pcre_uchar *end = NULL;
1024    int private_data_ptr = *private_data_start;
1025    int space, size, bracketlen;
1026    
1027  while (cc < ccend)  while (cc < ccend)
1028    {    {
1029      space = 0;
1030      size = 0;
1031      bracketlen = 0;
1032      if (private_data_ptr > SLJIT_MAX_LOCAL_SIZE)
1033        return;
1034    
1035      if (*cc == OP_ONCE || *cc == OP_ONCE_NC || *cc == OP_BRA || *cc == OP_CBRA || *cc == OP_COND)
1036        if (detect_repeat(common, cc))
1037          {
1038          /* These brackets are converted to repeats, so no global
1039          based single character repeat is allowed. */
1040          if (cc >= end)
1041            end = bracketend(cc);
1042          }
1043    
1044    switch(*cc)    switch(*cc)
1045      {      {
1046        case OP_KET:
1047        if (common->private_data_ptrs[cc + 1 - common->start] != 0)
1048          {
1049          common->private_data_ptrs[cc - common->start] = private_data_ptr;
1050          private_data_ptr += sizeof(sljit_sw);
1051          cc += common->private_data_ptrs[cc + 1 - common->start];
1052          }
1053        cc += 1 + LINK_SIZE;
1054        break;
1055    
1056      case OP_ASSERT:      case OP_ASSERT:
1057      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1058      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 755  while (cc < ccend) Line 1063  while (cc < ccend)
1063      case OP_SBRA:      case OP_SBRA:
1064      case OP_SBRAPOS:      case OP_SBRAPOS:
1065      case OP_SCOND:      case OP_SCOND:
1066      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1067      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1068      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1069      break;      break;
1070    
1071      case OP_CBRAPOS:      case OP_CBRAPOS:
1072      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1073      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1074      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1075      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1076      break;      break;
1077    
1078      case OP_COND:      case OP_COND:
# Line 772  while (cc < ccend) Line 1080  while (cc < ccend)
1080      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1081      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1082        {        {
1083        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1084        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1085        }        }
1086      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1087        break;
1088    
1089        case OP_BRA:
1090        bracketlen = 1 + LINK_SIZE;
1091        break;
1092    
1093        case OP_CBRA:
1094        case OP_SCBRA:
1095        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1096        break;
1097    
1098        CASE_ITERATOR_PRIVATE_DATA_1
1099        space = 1;
1100        size = -2;
1101        break;
1102    
1103        CASE_ITERATOR_PRIVATE_DATA_2A
1104        space = 2;
1105        size = -2;
1106        break;
1107    
1108        CASE_ITERATOR_PRIVATE_DATA_2B
1109        space = 2;
1110        size = -(2 + IMM2_SIZE);
1111        break;
1112    
1113        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1114        space = 1;
1115        size = 1;
1116        break;
1117    
1118        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1119        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1120          space = 2;
1121        size = 1;
1122      break;      break;
1123    
1124        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1125        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1126          space = 2;
1127        size = 1 + IMM2_SIZE;
1128        break;
1129    
1130        case OP_CLASS:
1131        case OP_NCLASS:
1132        size += 1 + 32 / sizeof(pcre_uchar);
1133        space = get_class_iterator_size(cc + size);
1134        break;
1135    
1136    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1137        case OP_XCLASS:
1138        size = GET(cc, 1);
1139        space = get_class_iterator_size(cc + size);
1140        break;
1141    #endif
1142    
1143      default:      default:
1144      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1145      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1146      break;      break;
1147      }      }
1148    
1149      /* Character iterators, which are not inside a repeated bracket,
1150         gets a private slot instead of allocating it on the stack. */
1151      if (space > 0 && cc >= end)
1152        {
1153        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1154        private_data_ptr += sizeof(sljit_sw) * space;
1155        }
1156    
1157      if (size != 0)
1158        {
1159        if (size < 0)
1160          {
1161          cc += -size;
1162    #ifdef SUPPORT_UTF
1163          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1164    #endif
1165          }
1166        else
1167          cc += size;
1168        }
1169    
1170      if (bracketlen > 0)
1171        {
1172        if (cc >= end)
1173          {
1174          end = bracketend(cc);
1175          if (end[-1 - LINK_SIZE] == OP_KET)
1176            end = NULL;
1177          }
1178        cc += bracketlen;
1179        }
1180    }    }
1181    *private_data_start = private_data_ptr;
1182  }  }
1183    
1184  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1185  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
1186  {  {
 pcre_uchar *ccend = bracketend(cc);  
1187  int length = 0;  int length = 0;
1188  BOOL possessive = FALSE;  int possessive = 0;
1189    BOOL stack_restore = FALSE;
1190  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1191  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1192    /* The last capture is a local variable even for recursions. */
1193    BOOL capture_last_found = FALSE;
1194    
1195  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1196    SLJIT_ASSERT(common->control_head_ptr != 0);
1197    *needs_control_head = TRUE;
1198    #else
1199    *needs_control_head = FALSE;
1200    #endif
1201    
1202    if (ccend == NULL)
1203    {    {
1204    length = 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1205    possessive = TRUE;    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1206        {
1207        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1208        /* This is correct regardless of common->capture_last_ptr. */
1209        capture_last_found = TRUE;
1210        }
1211      cc = next_opcode(common, cc);
1212    }    }
1213    
 cc = next_opcode(common, cc);  
1214  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1215  while (cc < ccend)  while (cc < ccend)
1216    switch(*cc)    switch(*cc)
1217      {      {
1218      case OP_SET_SOM:      case OP_SET_SOM:
1219      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1220        stack_restore = TRUE;
1221      if (!setsom_found)      if (!setsom_found)
1222        {        {
1223        length += 2;        length += 2;
# Line 817  while (cc < ccend) Line 1227  while (cc < ccend)
1227      break;      break;
1228    
1229      case OP_MARK:      case OP_MARK:
1230        case OP_PRUNE_ARG:
1231        case OP_THEN_ARG:
1232      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1233        stack_restore = TRUE;
1234      if (!setmark_found)      if (!setmark_found)
1235        {        {
1236        length += 2;        length += 2;
1237        setmark_found = TRUE;        setmark_found = TRUE;
1238        }        }
1239        if (common->control_head_ptr != 0)
1240          *needs_control_head = TRUE;
1241      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1242      break;      break;
1243    
1244      case OP_RECURSE:      case OP_RECURSE:
1245        stack_restore = TRUE;
1246      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1247        {        {
1248        length += 2;        length += 2;
# Line 837  while (cc < ccend) Line 1253  while (cc < ccend)
1253        length += 2;        length += 2;
1254        setmark_found = TRUE;        setmark_found = TRUE;
1255        }        }
1256        if (common->capture_last_ptr != 0 && !capture_last_found)
1257          {
1258          length += 2;
1259          capture_last_found = TRUE;
1260          }
1261      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1262      break;      break;
1263    
# Line 844  while (cc < ccend) Line 1265  while (cc < ccend)
1265      case OP_CBRAPOS:      case OP_CBRAPOS:
1266      case OP_SCBRA:      case OP_SCBRA:
1267      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1268        stack_restore = TRUE;
1269        if (common->capture_last_ptr != 0 && !capture_last_found)
1270          {
1271          length += 2;
1272          capture_last_found = TRUE;
1273          }
1274      length += 3;      length += 3;
1275      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1276      break;      break;
1277    
1278      default:      default:
1279        stack_restore = TRUE;
1280        /* Fall through. */
1281    
1282        case OP_NOT_WORD_BOUNDARY:
1283        case OP_WORD_BOUNDARY:
1284        case OP_NOT_DIGIT:
1285        case OP_DIGIT:
1286        case OP_NOT_WHITESPACE:
1287        case OP_WHITESPACE:
1288        case OP_NOT_WORDCHAR:
1289        case OP_WORDCHAR:
1290        case OP_ANY:
1291        case OP_ALLANY:
1292        case OP_ANYBYTE:
1293        case OP_NOTPROP:
1294        case OP_PROP:
1295        case OP_ANYNL:
1296        case OP_NOT_HSPACE:
1297        case OP_HSPACE:
1298        case OP_NOT_VSPACE:
1299        case OP_VSPACE:
1300        case OP_EXTUNI:
1301        case OP_EODN:
1302        case OP_EOD:
1303        case OP_CIRC:
1304        case OP_CIRCM:
1305        case OP_DOLL:
1306        case OP_DOLLM:
1307        case OP_CHAR:
1308        case OP_CHARI:
1309        case OP_NOT:
1310        case OP_NOTI:
1311    
1312        case OP_EXACT:
1313        case OP_POSSTAR:
1314        case OP_POSPLUS:
1315        case OP_POSQUERY:
1316        case OP_POSUPTO:
1317    
1318        case OP_EXACTI:
1319        case OP_POSSTARI:
1320        case OP_POSPLUSI:
1321        case OP_POSQUERYI:
1322        case OP_POSUPTOI:
1323    
1324        case OP_NOTEXACT:
1325        case OP_NOTPOSSTAR:
1326        case OP_NOTPOSPLUS:
1327        case OP_NOTPOSQUERY:
1328        case OP_NOTPOSUPTO:
1329    
1330        case OP_NOTEXACTI:
1331        case OP_NOTPOSSTARI:
1332        case OP_NOTPOSPLUSI:
1333        case OP_NOTPOSQUERYI:
1334        case OP_NOTPOSUPTOI:
1335    
1336        case OP_TYPEEXACT:
1337        case OP_TYPEPOSSTAR:
1338        case OP_TYPEPOSPLUS:
1339        case OP_TYPEPOSQUERY:
1340        case OP_TYPEPOSUPTO:
1341    
1342        case OP_CLASS:
1343        case OP_NCLASS:
1344        case OP_XCLASS:
1345    
1346      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1347      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1348      break;      break;
1349      }      }
1350    
1351  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1352  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1353    return -1;    return stack_restore ? no_frame : no_stack;
1354    
1355  if (length > 0)  if (length > 0)
1356    return length + 1;    return length + 1;
1357  return -1;  return stack_restore ? no_frame : no_stack;
1358  }  }
1359    
1360  static void init_frame(compiler_common *common, pcre_uchar *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)
1361  {  {
1362  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc);  
1363  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1364  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1365    /* The last capture is a local variable even for recursions. */
1366    BOOL capture_last_found = FALSE;
1367  int offset;  int offset;
1368    
1369  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 876  SLJIT_UNUSED_ARG(stacktop); Line 1371  SLJIT_UNUSED_ARG(stacktop);
1371  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1372    
1373  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1374  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1375    cc = next_opcode(common, cc);    {
1376      ccend = bracketend(cc) - (1 + LINK_SIZE);
1377      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1378        cc = next_opcode(common, cc);
1379      }
1380    
1381  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1382  while (cc < ccend)  while (cc < ccend)
1383    switch(*cc)    switch(*cc)
# Line 887  while (cc < ccend) Line 1387  while (cc < ccend)
1387      if (!setsom_found)      if (!setsom_found)
1388        {        {
1389        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1390        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1391        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1392        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1393        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1394        setsom_found = TRUE;        setsom_found = TRUE;
1395        }        }
1396      cc += 1;      cc += 1;
1397      break;      break;
1398    
1399      case OP_MARK:      case OP_MARK:
1400        case OP_PRUNE_ARG:
1401        case OP_THEN_ARG:
1402      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1403      if (!setmark_found)      if (!setmark_found)
1404        {        {
1405        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1406        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1407        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1408        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1409        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1410        setmark_found = TRUE;        setmark_found = TRUE;
1411        }        }
1412      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
# Line 914  while (cc < ccend) Line 1416  while (cc < ccend)
1416      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1417        {        {
1418        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1419        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1420        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1421        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1422        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1423        setsom_found = TRUE;        setsom_found = TRUE;
1424        }        }
1425      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1426        {        {
1427        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1428        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1429        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1430        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1431        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1432        setmark_found = TRUE;        setmark_found = TRUE;
1433        }        }
1434        if (common->capture_last_ptr != 0 && !capture_last_found)
1435          {
1436          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1437          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1438          stackpos += (int)sizeof(sljit_sw);
1439          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1440          stackpos += (int)sizeof(sljit_sw);
1441          capture_last_found = TRUE;
1442          }
1443      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1444      break;      break;
1445    
# Line 936  while (cc < ccend) Line 1447  while (cc < ccend)
1447      case OP_CBRAPOS:      case OP_CBRAPOS:
1448      case OP_SCBRA:      case OP_SCBRA:
1449      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1450        if (common->capture_last_ptr != 0 && !capture_last_found)
1451          {
1452          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1453          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1454          stackpos += (int)sizeof(sljit_sw);
1455          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1456          stackpos += (int)sizeof(sljit_sw);
1457          capture_last_found = TRUE;
1458          }
1459      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1460      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1461      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1462      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1463      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));
1464      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1465      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1466      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1467      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1468    
1469      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1470      break;      break;
# Line 955  while (cc < ccend) Line 1475  while (cc < ccend)
1475      break;      break;
1476      }      }
1477    
1478  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1479  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1480  }  }
1481    
1482  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1483  {  {
1484  int localsize = 2;  int private_data_length = needs_control_head ? 3 : 2;
1485    int size;
1486  pcre_uchar *alternative;  pcre_uchar *alternative;
1487  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1488  while (cc < ccend)  while (cc < ccend)
1489    {    {
1490      size = 0;
1491    switch(*cc)    switch(*cc)
1492      {      {
1493        case OP_KET:
1494        if (PRIVATE_DATA(cc) != 0)
1495          private_data_length++;
1496        cc += 1 + LINK_SIZE;
1497        break;
1498    
1499      case OP_ASSERT:      case OP_ASSERT:
1500      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
1501      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 978  while (cc < ccend) Line 1506  while (cc < ccend)
1506      case OP_SBRA:      case OP_SBRA:
1507      case OP_SBRAPOS:      case OP_SBRAPOS:
1508      case OP_SCOND:      case OP_SCOND:
1509      localsize++;      private_data_length++;
1510      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1511      break;      break;
1512    
1513      case OP_CBRA:      case OP_CBRA:
1514      case OP_SCBRA:      case OP_SCBRA:
1515      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1516          private_data_length++;
1517      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1518      break;      break;
1519    
1520      case OP_CBRAPOS:      case OP_CBRAPOS:
1521      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1522      localsize += 2;      private_data_length += 2;
1523      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1524      break;      break;
1525    
# Line 998  while (cc < ccend) Line 1527  while (cc < ccend)
1527      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1528      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1529      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1530        localsize++;        private_data_length++;
1531      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1532      break;      break;
1533    
1534        CASE_ITERATOR_PRIVATE_DATA_1
1535        if (PRIVATE_DATA(cc))
1536          private_data_length++;
1537        cc += 2;
1538    #ifdef SUPPORT_UTF
1539        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1540    #endif
1541        break;
1542    
1543        CASE_ITERATOR_PRIVATE_DATA_2A
1544        if (PRIVATE_DATA(cc))
1545          private_data_length += 2;
1546        cc += 2;
1547    #ifdef SUPPORT_UTF
1548        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1549    #endif
1550        break;
1551    
1552        CASE_ITERATOR_PRIVATE_DATA_2B
1553        if (PRIVATE_DATA(cc))
1554          private_data_length += 2;
1555        cc += 2 + IMM2_SIZE;
1556    #ifdef SUPPORT_UTF
1557        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1558    #endif
1559        break;
1560    
1561        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1562        if (PRIVATE_DATA(cc))
1563          private_data_length++;
1564        cc += 1;
1565        break;
1566    
1567        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1568        if (PRIVATE_DATA(cc))
1569          private_data_length += 2;
1570        cc += 1;
1571        break;
1572    
1573        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1574        if (PRIVATE_DATA(cc))
1575          private_data_length += 2;
1576        cc += 1 + IMM2_SIZE;
1577        break;
1578    
1579        case OP_CLASS:
1580        case OP_NCLASS:
1581    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1582        case OP_XCLASS:
1583        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1584    #else
1585        size = 1 + 32 / (int)sizeof(pcre_uchar);
1586    #endif
1587        if (PRIVATE_DATA(cc))
1588          private_data_length += get_class_iterator_size(cc + size);
1589        cc += size;
1590        break;
1591    
1592      default:      default:
1593      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1594      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 1009  while (cc < ccend) Line 1596  while (cc < ccend)
1596      }      }
1597    }    }
1598  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1599  return localsize;  return private_data_length;
1600  }  }
1601    
1602  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1603    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1604  {  {
1605  DEFINE_COMPILER;  DEFINE_COMPILER;
1606  int srcw[2];  int srcw[2];
1607  int count;  int count, size;
1608  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1609  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1610  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 1034  stacktop = STACK(stacktop - 1); Line 1621  stacktop = STACK(stacktop - 1);
1621    
1622  if (!save)  if (!save)
1623    {    {
1624    stackptr += sizeof(sljit_w);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1625    if (stackptr < stacktop)    if (stackptr < stacktop)
1626      {      {
1627      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1628      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1629      tmp1empty = FALSE;      tmp1empty = FALSE;
1630      }      }
1631    if (stackptr < stacktop)    if (stackptr < stacktop)
1632      {      {
1633      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1634      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1635      tmp2empty = FALSE;      tmp2empty = FALSE;
1636      }      }
1637    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1638    }    }
1639    
1640  while (status != end)  do
1641    {    {
1642    count = 0;    count = 0;
1643    switch(status)    switch(status)
1644      {      {
1645      case start:      case start:
1646      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1647      count = 1;      count = 1;
1648      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1649        if (needs_control_head)
1650          {
1651          SLJIT_ASSERT(common->control_head_ptr != 0);
1652          count = 2;
1653          srcw[1] = common->control_head_ptr;
1654          }
1655      status = loop;      status = loop;
1656      break;      break;
1657    
# Line 1071  while (status != end) Line 1664  while (status != end)
1664    
1665      switch(*cc)      switch(*cc)
1666        {        {
1667          case OP_KET:
1668          if (PRIVATE_DATA(cc) != 0)
1669            {
1670            count = 1;
1671            srcw[0] = PRIVATE_DATA(cc);
1672            }
1673          cc += 1 + LINK_SIZE;
1674          break;
1675    
1676        case OP_ASSERT:        case OP_ASSERT:
1677        case OP_ASSERT_NOT:        case OP_ASSERT_NOT:
1678        case OP_ASSERTBACK:        case OP_ASSERTBACK:
# Line 1082  while (status != end) Line 1684  while (status != end)
1684        case OP_SBRAPOS:        case OP_SBRAPOS:
1685        case OP_SCOND:        case OP_SCOND:
1686        count = 1;        count = 1;
1687        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1688        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1689        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1690        break;        break;
1691    
1692        case OP_CBRA:        case OP_CBRA:
1693        case OP_SCBRA:        case OP_SCBRA:
1694        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1695        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1696            count = 1;
1697            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1698            }
1699        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1700        break;        break;
1701    
1702        case OP_CBRAPOS:        case OP_CBRAPOS:
1703        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1704        count = 2;        count = 2;
1705          srcw[0] = PRIVATE_DATA(cc);
1706        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1707        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1708        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1709        break;        break;
1710    
# Line 1109  while (status != end) Line 1714  while (status != end)
1714        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1715          {          {
1716          count = 1;          count = 1;
1717          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1718          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1719          }          }
1720        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1721        break;        break;
1722    
1723          CASE_ITERATOR_PRIVATE_DATA_1
1724          if (PRIVATE_DATA(cc))
1725            {
1726            count = 1;
1727            srcw[0] = PRIVATE_DATA(cc);
1728            }
1729          cc += 2;
1730    #ifdef SUPPORT_UTF
1731          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1732    #endif
1733          break;
1734    
1735          CASE_ITERATOR_PRIVATE_DATA_2A
1736          if (PRIVATE_DATA(cc))
1737            {
1738            count = 2;
1739            srcw[0] = PRIVATE_DATA(cc);
1740            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1741            }
1742          cc += 2;
1743    #ifdef SUPPORT_UTF
1744          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1745    #endif
1746          break;
1747    
1748          CASE_ITERATOR_PRIVATE_DATA_2B
1749          if (PRIVATE_DATA(cc))
1750            {
1751            count = 2;
1752            srcw[0] = PRIVATE_DATA(cc);
1753            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1754            }
1755          cc += 2 + IMM2_SIZE;
1756    #ifdef SUPPORT_UTF
1757          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1758    #endif
1759          break;
1760    
1761          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1762          if (PRIVATE_DATA(cc))
1763            {
1764            count = 1;
1765            srcw[0] = PRIVATE_DATA(cc);
1766            }
1767          cc += 1;
1768          break;
1769    
1770          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1771          if (PRIVATE_DATA(cc))
1772            {
1773            count = 2;
1774            srcw[0] = PRIVATE_DATA(cc);
1775            srcw[1] = srcw[0] + sizeof(sljit_sw);
1776            }
1777          cc += 1;
1778          break;
1779    
1780          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1781          if (PRIVATE_DATA(cc))
1782            {
1783            count = 2;
1784            srcw[0] = PRIVATE_DATA(cc);
1785            srcw[1] = srcw[0] + sizeof(sljit_sw);
1786            }
1787          cc += 1 + IMM2_SIZE;
1788          break;
1789    
1790          case OP_CLASS:
1791          case OP_NCLASS:
1792    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1793          case OP_XCLASS:
1794          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1795    #else
1796          size = 1 + 32 / (int)sizeof(pcre_uchar);
1797    #endif
1798          if (PRIVATE_DATA(cc))
1799            switch(get_class_iterator_size(cc + size))
1800              {
1801              case 1:
1802              count = 1;
1803              srcw[0] = PRIVATE_DATA(cc);
1804              break;
1805    
1806              case 2:
1807              count = 2;
1808              srcw[0] = PRIVATE_DATA(cc);
1809              srcw[1] = srcw[0] + sizeof(sljit_sw);
1810              break;
1811    
1812              default:
1813              SLJIT_ASSERT_STOP();
1814              break;
1815              }
1816          cc += size;
1817          break;
1818    
1819        default:        default:
1820        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1821        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1137  while (status != end) Line 1838  while (status != end)
1838          if (!tmp1empty)          if (!tmp1empty)
1839            {            {
1840            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1841            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1842            }            }
1843          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1844          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1148  while (status != end) Line 1849  while (status != end)
1849          if (!tmp2empty)          if (!tmp2empty)
1850            {            {
1851            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1852            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1853            }            }
1854          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1855          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1165  while (status != end) Line 1866  while (status != end)
1866          if (!tmp1empty)          if (!tmp1empty)
1867            {            {
1868            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1869            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1870            }            }
1871          tmp1next = FALSE;          tmp1next = FALSE;
1872          }          }
# Line 1177  while (status != end) Line 1878  while (status != end)
1878          if (!tmp2empty)          if (!tmp2empty)
1879            {            {
1880            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1881            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1882            }            }
1883          tmp1next = TRUE;          tmp1next = TRUE;
1884          }          }
1885        }        }
1886      }      }
1887    }    }
1888    while (status != end);
1889    
1890  if (save)  if (save)
1891    {    {
# Line 1192  if (save) Line 1894  if (save)
1894      if (!tmp1empty)      if (!tmp1empty)
1895        {        {
1896        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1897        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1898        }        }
1899      if (!tmp2empty)      if (!tmp2empty)
1900        {        {
1901        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1902        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1903        }        }
1904      }      }
1905    else    else
# Line 1205  if (save) Line 1907  if (save)
1907      if (!tmp2empty)      if (!tmp2empty)
1908        {        {
1909        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1910        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1911        }        }
1912      if (!tmp1empty)      if (!tmp1empty)
1913        {        {
1914        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1915        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1916        }        }
1917      }      }
1918    }    }
1919  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1920  }  }
1921    
1922  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)
1923    {
1924    pcre_uchar *end = bracketend(cc);
1925    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1926    
1927    /* Assert captures then. */
1928    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1929      current_offset = NULL;
1930    /* Conditional block does not. */
1931    if (*cc == OP_COND || *cc == OP_SCOND)
1932      has_alternatives = FALSE;
1933    
1934    cc = next_opcode(common, cc);
1935    if (has_alternatives)
1936      current_offset = common->then_offsets + (cc - common->start);
1937    
1938    while (cc < end)
1939      {
1940      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1941        cc = set_then_offsets(common, cc, current_offset);
1942      else
1943        {
1944        if (*cc == OP_ALT && has_alternatives)
1945          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1946        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1947          *current_offset = 1;
1948        cc = next_opcode(common, cc);
1949        }
1950      }
1951    
1952    return end;
1953    }
1954    
1955    #undef CASE_ITERATOR_PRIVATE_DATA_1
1956    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1957    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1958    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1959    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1960    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1961    
1962    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1963  {  {
1964  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1965  }  }
# Line 1227  static SLJIT_INLINE void set_jumps(jump_ Line 1969  static SLJIT_INLINE void set_jumps(jump_
1969  while (list)  while (list)
1970    {    {
1971    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1972    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1973    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1974    list = list->next;    list = list->next;
1975    }    }
1976  }  }
# Line 1244  if (list_item) Line 1986  if (list_item)
1986    }    }
1987  }  }
1988    
1989  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)
1990  {  {
1991  DEFINE_COMPILER;  DEFINE_COMPILER;
1992  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1993    
1994  if (list_item)  if (list_item)
1995    {    {
   list_item->type = type;  
   list_item->data = data;  
1996    list_item->start = start;    list_item->start = start;
1997    list_item->leave = LABEL();    list_item->quit = LABEL();
1998    list_item->next = common->stubs;    list_item->next = common->stubs;
1999    common->stubs = list_item;    common->stubs = list_item;
2000    }    }
# Line 1268  stub_list* list_item = common->stubs; Line 2008  stub_list* list_item = common->stubs;
2008  while (list_item)  while (list_item)
2009    {    {
2010    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
2011    switch(list_item->type)    add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
2012      {    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);  
2013    list_item = list_item->next;    list_item = list_item->next;
2014    }    }
2015  common->stubs = NULL;  common->stubs = NULL;
2016  }  }
2017    
2018  static SLJIT_INLINE void decrease_call_count(compiler_common *common)  static SLJIT_INLINE void count_match(compiler_common *common)
2019  {  {
2020  DEFINE_COMPILER;  DEFINE_COMPILER;
2021    
2022  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, COUNT_MATCH, 0, COUNT_MATCH, 0, SLJIT_IMM, 1);
2023  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
2024  }  }
2025    
# Line 1293  static SLJIT_INLINE void allocate_stack( Line 2028  static SLJIT_INLINE void allocate_stack(
2028  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
2029  DEFINE_COMPILER;  DEFINE_COMPILER;
2030    
2031  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));
2032  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
2033  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
2034  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1301  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 2036  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2036  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
2037  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2038  #endif  #endif
2039  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));
2040  }  }
2041    
2042  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
2043  {  {
2044  DEFINE_COMPILER;  DEFINE_COMPILER;
2045  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));
2046  }  }
2047    
2048  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1315  static SLJIT_INLINE void reset_ovector(c Line 2050  static SLJIT_INLINE void reset_ovector(c
2050  DEFINE_COMPILER;  DEFINE_COMPILER;
2051  struct sljit_label *loop;  struct sljit_label *loop;
2052  int i;  int i;
2053    
2054  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2055    SLJIT_ASSERT(length > 1);
2056  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2057  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
2058    if (length < 8)
2059      {
2060      for (i = 1; i < length; i++)
2061        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2062      }
2063    else
2064      {
2065      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2066      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2067      loop = LABEL();
2068      OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2069      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
2070      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2071      }
2072    }
2073    
2074    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2075    {
2076    DEFINE_COMPILER;
2077    struct sljit_label *loop;
2078    int i;
2079    
2080    SLJIT_ASSERT(length > 1);
2081    /* OVECTOR(1) contains the "string begin - 1" constant. */
2082    if (length > 2)
2083      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2084  if (length < 8)  if (length < 8)
2085    {    {
2086    for (i = 0; i < length; i++)    for (i = 2; i < length; i++)
2087      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);
2088    }    }
2089  else  else
2090    {    {
2091    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));
2092    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2093    loop = LABEL();    loop = LABEL();
2094    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);
2095    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);
2096    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
2097    }    }
2098    
2099    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2100    if (common->mark_ptr != 0)
2101      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2102    if (common->control_head_ptr != 0)
2103      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2104    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2105    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2106    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2107    }
2108    
2109    static sljit_sw SLJIT_CALL do_search_mark(sljit_sw *current, const pcre_uchar *skip_arg)
2110    {
2111    while (current != NULL)
2112      {
2113      switch (current[-2])
2114        {
2115        case type_then_trap:
2116        break;
2117    
2118        case type_mark:
2119        if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2120          return current[-4];
2121        break;
2122    
2123        default:
2124        SLJIT_ASSERT_STOP();
2125        break;
2126        }
2127      current = (sljit_sw*)current[-1];
2128      }
2129    return -1;
2130  }  }
2131    
2132  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2133  {  {
2134  DEFINE_COMPILER;  DEFINE_COMPILER;
2135  struct sljit_label *loop;  struct sljit_label *loop;
2136  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
2137    
2138  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2139  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2140  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);
2141    
2142  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
2143  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2144    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
2145  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
2146  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2147    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
2148  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2149  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
2150  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
2151  /* Unlikely, but possible */  /* Unlikely, but possible */
2152  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);
2153  loop = LABEL();  loop = LABEL();
2154  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
2155  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
2156  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
2157  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2158  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2159  #endif  #endif
2160  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
2161  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
2162  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2163  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2164    
2165  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2166  if (topbracket > 1)  if (topbracket > 1)
2167    {    {
2168    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));
2169    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
2170    
2171    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
2172    loop = LABEL();    loop = LABEL();
2173    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)));
2174    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);
2175    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
2176    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
2177    }    }
2178  else  else
2179    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
2180  }  }
2181    
2182  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
2183  {  {
2184  DEFINE_COMPILER;  DEFINE_COMPILER;
2185    struct sljit_jump *jump;
2186    
2187  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
2188  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));  SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2189      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2190    
2191  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2192  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2193  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2194  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);  CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
2195    
2196  /* Store match begin and end. */  /* Store match begin and end. */
2197  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
2198  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2199  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  
2200    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2201    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);
2202    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2203    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2204    #endif
2205    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2206    JUMPHERE(jump);
2207    
2208    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);
2209  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
2210  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2211  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2212  #endif  #endif
2213  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
2214    
2215  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
2216  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2217  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2218  #endif  #endif
2219  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
2220    
2221  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, quit);
2222  }  }
2223    
2224  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)  static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
# Line 1523  if (c <= 127 && bit == 0x20) Line 2329  if (c <= 127 && bit == 0x20)
2329    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2330    
2331  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2332  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2333    return 0;    return 0;
2334    
2335  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2336    
2337  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2338  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1542  if (common->utf && c > 127) Line 2348  if (common->utf && c > 127)
2348  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2349  return (0 << 8) | bit;  return (0 << 8) | bit;
2350    
2351  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2352    
 #ifdef COMPILE_PCRE16  
2353  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2354  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2355    {    {
# Line 1555  if (common->utf && c > 65535) Line 2360  if (common->utf && c > 65535)
2360    }    }
2361  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2362  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2363    
2364  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2365  }  }
2366    
2367  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
2368  {  {
2369  /* Checks whether a partial matching is occured. Does not modify registers. */  /* Checks whether a partial matching is occurred. Does not modify registers. */
2370  DEFINE_COMPILER;  DEFINE_COMPILER;
2371  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2372    
# Line 1577  else if (common->mode == JIT_PARTIAL_SOF Line 2381  else if (common->mode == JIT_PARTIAL_SOF
2381    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2382    
2383  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2384    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2385  else  else
2386    {    {
2387    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 1590  if (jump != NULL) Line 2394  if (jump != NULL)
2394    JUMPHERE(jump);    JUMPHERE(jump);
2395  }  }
2396    
2397  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2398  {  {
2399  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2400  DEFINE_COMPILER;  DEFINE_COMPILER;
2401  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2402    
2403  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2404    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2405      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2406      return;
2407      }
2408    
2409  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2410  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2411    {    {
2412    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2413    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2414    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2415    }    }
2416  else  else
2417    {    {
2418    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2419    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2420      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2421    else    else
2422      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2423    }    }
2424  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2425  }  }
2426    
2427  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2428  {  {
2429  DEFINE_COMPILER;  DEFINE_COMPILER;
2430  struct sljit_jump *jump;  struct sljit_jump *jump;
2431    
2432  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2433    {    {
2434    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2435    return;    return;
2436    }    }
2437    
2438  /* Partial matching mode. */  /* Partial matching mode. */
2439  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2440  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2441  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2442    {    {
2443    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2444    add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2445    }    }
2446  else  else
2447    {    {
# Line 1655  static void read_char(compiler_common *c Line 2458  static void read_char(compiler_common *c
2458  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2459  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2460  DEFINE_COMPILER;  DEFINE_COMPILER;
2461  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2462  struct sljit_jump *jump;  struct sljit_jump *jump;
2463  #endif  #endif
2464    
2465  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2466  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2467  if (common->utf)  if (common->utf)
2468    {    {
2469  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2470    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2471  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2472    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2473  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2474    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2475    JUMPHERE(jump);    JUMPHERE(jump);
2476    }    }
2477  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2478  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2479  }  }
2480    
# Line 1682  static void peek_char(compiler_common *c Line 2483  static void peek_char(compiler_common *c
2483  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2484  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2485  DEFINE_COMPILER;  DEFINE_COMPILER;
2486  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2487  struct sljit_jump *jump;  struct sljit_jump *jump;
2488  #endif  #endif
2489    
2490  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2491  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2492  if (common->utf)  if (common->utf)
2493    {    {
2494  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2495    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2496  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2497    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2498  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2499    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2500    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2501    JUMPHERE(jump);    JUMPHERE(jump);
2502    }    }
2503  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2504  }  }
2505    
2506  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2507  {  {
2508  /* 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. */
2509  DEFINE_COMPILER;  DEFINE_COMPILER;
2510  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2511  struct sljit_jump *jump;  struct sljit_jump *jump;
2512  #endif  #endif
2513    
# Line 1717  if (common->utf) Line 2516  if (common->utf)
2516    {    {
2517    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2518    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2519  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2520    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2521    it is needed in most cases. */    it is needed in most cases. */
2522    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2523    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2524    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2525    JUMPHERE(jump);    JUMPHERE(jump);
2526  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2527    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2528    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2529    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 1733  if (common->utf) Line 2531  if (common->utf)
2531    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2532    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2533    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2534    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2535    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2536    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2537  #endif  #elif defined COMPILE_PCRE32
2538  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2539      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2540      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2541      JUMPHERE(jump);
2542    #endif /* COMPILE_PCRE[8|16|32] */
2543    return;    return;
2544    }    }
2545  #endif  #endif /* SUPPORT_UTF */
2546  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2547  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2548  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2549  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2550  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2551  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2552  #endif  #endif
2553  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2554  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2555  JUMPHERE(jump);  JUMPHERE(jump);
2556  #endif  #endif
2557  }  }
# Line 1758  static void skip_char_back(compiler_comm Line 2560  static void skip_char_back(compiler_comm
2560  {  {
2561  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2562  DEFINE_COMPILER;  DEFINE_COMPILER;
2563  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2564    #if defined COMPILE_PCRE8
2565  struct sljit_label *label;  struct sljit_label *label;
2566    
2567  if (common->utf)  if (common->utf)
# Line 1770  if (common->utf) Line 2573  if (common->utf)
2573    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2574    return;    return;
2575    }    }
2576  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2577  if (common->utf)  if (common->utf)
2578    {    {
2579    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 1779  if (common->utf) Line 2581  if (common->utf)
2581    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2582    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2583    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2584    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2585    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2586    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2587    return;    return;
2588    }    }
2589  #endif  #endif /* COMPILE_PCRE[8|16] */
2590    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2591  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2592  }  }
2593    
2594  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)
2595  {  {
2596  /* 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. */
2597  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1796  DEFINE_COMPILER; Line 2599  DEFINE_COMPILER;
2599  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2600    {    {
2601    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2602    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));
2603    }    }
2604  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2605    {    {
2606    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);
2607    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2608    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);
2609    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);
2610    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));
2611    }    }
2612  else  else
2613    {    {
2614    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2615    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));
2616    }    }
2617  }  }
2618    
2619  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2620    
2621  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2622  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2623  {  {
2624  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 1823  of the character (>= 0xc0). Return char Line 2626  of the character (>= 0xc0). Return char
2626  DEFINE_COMPILER;  DEFINE_COMPILER;
2627  struct sljit_jump *jump;  struct sljit_jump *jump;
2628    
2629  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2630  /* Searching for the first zero. */  /* Searching for the first zero. */
2631  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);
2632  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1882  DEFINE_COMPILER; Line 2685  DEFINE_COMPILER;
2685  struct sljit_jump *jump;  struct sljit_jump *jump;
2686  struct sljit_jump *compare;  struct sljit_jump *compare;
2687    
2688  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2689    
2690  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);
2691  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1903  sljit_emit_fast_return(compiler, RETURN_ Line 2706  sljit_emit_fast_return(compiler, RETURN_
2706  JUMPHERE(jump);  JUMPHERE(jump);
2707    
2708  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2709  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2710  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2711  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2712  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2713  }  }
2714    
2715  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2716    
 #ifdef COMPILE_PCRE16  
2717  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2718  {  {
2719  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 1919  of the character (>= 0xd800). Return cha Line 2721  of the character (>= 0xd800). Return cha
2721  DEFINE_COMPILER;  DEFINE_COMPILER;
2722  struct sljit_jump *jump;  struct sljit_jump *jump;
2723    
2724  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2725  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2726  /* Do nothing, only return. */  /* Do nothing, only return. */
2727  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1936  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2738  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2738  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2739  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2740  }  }
 #endif /* COMPILE_PCRE16 */  
2741    
2742  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2743    
2744  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2745    
# Line 1956  DEFINE_COMPILER; Line 2757  DEFINE_COMPILER;
2757    
2758  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2759    
2760  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2761  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2762  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
2763  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2764  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2765  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2766  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2767  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2768  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
2769  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2770  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2771  }  }
# Line 1978  struct sljit_label *newlinelabel = NULL; Line 2779  struct sljit_label *newlinelabel = NULL;
2779  struct sljit_jump *start;  struct sljit_jump *start;
2780  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2781  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2782  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2783  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2784  #endif  #endif
2785  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 1993  if (firstline) Line 2794  if (firstline)
2794    {    {
2795    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2796    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2797    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);  
2798    
2799    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2800      {      {
# Line 2005  if (firstline) Line 2805  if (firstline)
2805      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2806      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);
2807      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);
2808        JUMPHERE(end);
2809      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2810      }      }
2811    else    else
# Line 2016  if (firstline) Line 2817  if (firstline)
2817      read_char(common);      read_char(common);
2818      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2819      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2820        JUMPHERE(end);
2821      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2822      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2823      }      }
2824    
2825    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2826    }    }
2827    
2828  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 2033  if (newlinecheck) Line 2834  if (newlinecheck)
2834    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2835    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2836    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);
2837    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2838  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2839    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2840  #endif  #endif
2841    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2842    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2056  if (newlinecheck) Line 2857  if (newlinecheck)
2857    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);
2858    
2859  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2860  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2861    #if defined COMPILE_PCRE8
2862  if (common->utf)  if (common->utf)
2863    {    {
2864    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2865    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2866      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2867      JUMPHERE(singlechar);
2868      }
2869    #elif defined COMPILE_PCRE16
2870    if (common->utf)
2871      {
2872      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2873      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2874      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2875      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2876      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2877    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2878    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2879    }    }
2880  #endif  #endif /* COMPILE_PCRE[8|16] */
2881  #if defined SUPPORT_UTF && defined COMPILE_PCRE16  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2882  if (common->utf)  JUMPHERE(start);
2883    
2884    if (newlinecheck)
2885      {
2886      JUMPHERE(end);
2887      JUMPHERE(nl);
2888      }
2889    
2890    return mainloop;
2891    }
2892    
2893    #define MAX_N_CHARS 3
2894    
2895    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2896    {
2897    DEFINE_COMPILER;
2898    struct sljit_label *start;
2899    struct sljit_jump *quit;
2900    pcre_uint32 chars[MAX_N_CHARS * 2];
2901    pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2902    int location = 0;
2903    pcre_int32 len, c, bit, caseless;
2904    int must_stop;
2905    
2906    /* We do not support alternatives now. */
2907    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2908      return FALSE;
2909    
2910    while (TRUE)
2911      {
2912      caseless = 0;
2913      must_stop = 1;
2914      switch(*cc)
2915        {
2916        case OP_CHAR:
2917        must_stop = 0;
2918        cc++;
2919        break;
2920    
2921        case OP_CHARI:
2922        caseless = 1;
2923        must_stop = 0;
2924        cc++;
2925        break;
2926    
2927        case OP_SOD:
2928        case OP_SOM:
2929        case OP_SET_SOM:
2930        case OP_NOT_WORD_BOUNDARY:
2931        case OP_WORD_BOUNDARY:
2932        case OP_EODN:
2933        case OP_EOD:
2934        case OP_CIRC:
2935        case OP_CIRCM:
2936        case OP_DOLL:
2937        case OP_DOLLM:
2938        /* Zero width assertions. */
2939        cc++;
2940        continue;
2941    
2942        case OP_PLUS:
2943        case OP_MINPLUS:
2944        case OP_POSPLUS:
2945        cc++;
2946        break;
2947    
2948        case OP_EXACT:
2949        cc += 1 + IMM2_SIZE;
2950        break;
2951    
2952        case OP_PLUSI:
2953        case OP_MINPLUSI:
2954        case OP_POSPLUSI:
2955        caseless = 1;
2956        cc++;
2957        break;
2958    
2959        case OP_EXACTI:
2960        caseless = 1;
2961        cc += 1 + IMM2_SIZE;
2962        break;
2963    
2964        default:
2965        must_stop = 2;
2966        break;
2967        }
2968    
2969      if (must_stop == 2)
2970          break;
2971    
2972      len = 1;
2973    #ifdef SUPPORT_UTF
2974      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2975    #endif
2976    
2977      if (caseless && char_has_othercase(common, cc))
2978        {
2979        caseless = char_get_othercase_bit(common, cc);
2980        if (caseless == 0)
2981          return FALSE;
2982    #ifdef COMPILE_PCRE8
2983        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2984    #else
2985        if ((caseless & 0x100) != 0)
2986          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2987        else
2988          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2989    #endif
2990        }
2991      else
2992        caseless = 0;
2993    
2994      while (len > 0 && location < MAX_N_CHARS * 2)
2995        {
2996        c = *cc;
2997        bit = 0;
2998        if (len == (caseless & 0xff))
2999          {
3000          bit = caseless >> 8;
3001          c |= bit;
3002          }
3003    
3004        chars[location] = c;
3005        chars[location + 1] = bit;
3006    
3007        len--;
3008        location += 2;
3009        cc++;
3010        }
3011    
3012      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
3013        break;
3014      }
3015    
3016    /* At least two characters are required. */
3017    if (location < 2 * 2)
3018        return FALSE;
3019    
3020    if (firstline)
3021    {    {
3022    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    SLJIT_ASSERT(common->first_line_end != 0);
3023    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3024    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   JUMPHERE(singlechar);  
3025    }    }
3026  #endif  else
3027  JUMPHERE(start);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3028    
3029  if (newlinecheck)  start = LABEL();
3030    {  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3031    JUMPHERE(end);  
3032    JUMPHERE(nl);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3033    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3034    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3035    if (chars[1] != 0)
3036      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3037    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3038    if (location > 2 * 2)
3039      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3040    if (chars[3] != 0)
3041      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
3042    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
3043    if (location > 2 * 2)
3044      {
3045      if (chars[5] != 0)
3046        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
3047      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
3048    }    }
3049    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3050    
3051  return mainloop;  JUMPHERE(quit);
3052    
3053    if (firstline)
3054      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3055    else
3056      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3057    return TRUE;
3058  }  }
3059    
3060    #undef MAX_N_CHARS
3061    
3062  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
3063  {  {
3064  DEFINE_COMPILER;  DEFINE_COMPILER;
3065  struct sljit_label *start;  struct sljit_label *start;
3066  struct sljit_jump *leave;  struct sljit_jump *quit;
3067  struct sljit_jump *found;  struct sljit_jump *found;
3068  pcre_uchar oc, bit;  pcre_uchar oc, bit;
3069    
3070  if (firstline)  if (firstline)
3071    {    {
3072    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
3073      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3074    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3075    }    }
3076    
3077  start = LABEL();  start = LABEL();
3078  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3079  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3080    
3081  oc = first_char;  oc = first_char;
# Line 2120  if (first_char == oc) Line 3092  if (first_char == oc)
3092  else  else
3093    {    {
3094    bit = first_char ^ oc;    bit = first_char ^ oc;
3095    if (ispowerof2(bit))    if (is_powerof2(bit))
3096      {      {
3097      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
3098      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 2128  else Line 3100  else
3100    else    else
3101      {      {
3102      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
3103      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3104      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);
3105      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);
3106      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
3107      }      }
3108    }    }
3109    
3110  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
3111  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3112  JUMPHERE(found);  JUMPHERE(found);
3113  JUMPHERE(leave);  JUMPHERE(quit);
3114    
3115  if (firstline)  if (firstline)
3116    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3117  }  }
3118    
3119  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 2169  DEFINE_COMPILER; Line 3122  DEFINE_COMPILER;
3122  struct sljit_label *loop;  struct sljit_label *loop;
3123  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
3124  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
3125  struct sljit_jump *leave;  struct sljit_jump *quit;
3126  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
3127  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
3128  jump_list *newline = NULL;  jump_list *newline = NULL;
3129    
3130  if (firstline)  if (firstline)
3131    {    {
3132    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
3133      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3134    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3135    }    }
3136    
# Line 2190  if (common->nltype == NLTYPE_FIXED && co Line 3144  if (common->nltype == NLTYPE_FIXED && co
3144    
3145    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
3146    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);
3147    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
3148  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3149    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
3150  #endif  #endif
3151    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3152    
3153    loop = LABEL();    loop = LABEL();
3154    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3155    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3156    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3157    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3158    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);
3159    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);
3160    
3161    JUMPHERE(leave);    JUMPHERE(quit);
3162    JUMPHERE(firstchar);    JUMPHERE(firstchar);
3163    JUMPHERE(lastchar);    JUMPHERE(lastchar);
3164    
# Line 2228  set_jumps(newline, loop); Line 3182  set_jumps(newline, loop);
3182    
3183  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
3184    {    {
3185    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
3186    JUMPHERE(foundcr);    JUMPHERE(foundcr);
3187    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3188    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3189    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);
3190    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3191  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3192    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3193  #endif  #endif
3194    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3195    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
3196    JUMPHERE(leave);    JUMPHERE(quit);
3197    }    }
3198  JUMPHERE(lastchar);  JUMPHERE(lastchar);
3199  JUMPHERE(firstchar);  JUMPHERE(firstchar);
3200    
3201  if (firstline)  if (firstline)
3202    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3203  }  }
3204    
3205    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3206    
3207  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)
3208  {  {
3209  DEFINE_COMPILER;  DEFINE_COMPILER;
3210  struct sljit_label *start;  struct sljit_label *start;
3211  struct sljit_jump *leave;  struct sljit_jump *quit;
3212  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3213    jump_list *matches = NULL;
3214    pcre_uint8 inverted_start_bits[32];
3215    int i;
3216  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3217  struct sljit_jump *jump;  struct sljit_jump *jump;
3218  #endif  #endif
3219    
3220    for (i = 0; i < 32; ++i)
3221      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3222    
3223  if (firstline)  if (firstline)
3224    {    {
3225    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
3226      OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
3227    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
3228    }    }
3229    
3230  start = LABEL();  start = LABEL();
3231  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3232  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3233  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3234  if (common->utf)  if (common->utf)
3235    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3236  #endif  #endif
3237    
3238    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3239      {
3240  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3241  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3242  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3243  JUMPHERE(jump);    JUMPHERE(jump);
3244  #endif  #endif
3245  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3246  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3247  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3248  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3249  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3250  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
3251      }
3252    
3253  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3254  if (common->utf)  if (common->utf)
3255    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3256  #endif  #endif
3257  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3258  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
3259    #if defined COMPILE_PCRE8
3260  if (common->utf)  if (common->utf)
3261    {    {
3262    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
3263    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
3264    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3265    }    }
3266  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
3267  if (common->utf)  if (common->utf)
3268    {    {
3269    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
3270    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3271    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3272    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3273    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3274    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3275    }    }
3276  #endif  #endif /* COMPILE_PCRE[8|16] */
3277    #endif /* SUPPORT_UTF */
3278  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3279  JUMPHERE(found);  if (found != NULL)
3280  JUMPHERE(leave);    JUMPHERE(found);
3281    if (matches != NULL)
3282      set_jumps(matches, LABEL());
3283    JUMPHERE(quit);
3284    
3285  if (firstline)  if (firstline)
3286    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
3287  }  }
3288    
3289  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2324  struct sljit_jump *alreadyfound; Line 3295  struct sljit_jump *alreadyfound;
3295  struct sljit_jump *found;  struct sljit_jump *found;
3296  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
3297  struct sljit_jump *notfound;  struct sljit_jump *notfound;
3298  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
3299    
3300  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
3301  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2355  if (req_char == oc) Line 3326  if (req_char == oc)
3326  else  else
3327    {    {
3328    bit = req_char ^ oc;    bit = req_char ^ oc;
3329    if (ispowerof2(bit))    if (is_powerof2(bit))
3330      {      {
3331      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3332      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 2384  DEFINE_COMPILER; Line 3355  DEFINE_COMPILER;
3355  struct sljit_jump *jump;  struct sljit_jump *jump;
3356  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3357    
3358  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3359  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3360    GET_LOCAL_BASE(TMP3, 0, 0);
3361    
3362  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3363  mainloop = LABEL();  mainloop = LABEL();
3364  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3365  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);
3366  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3367  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
3368  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);
3369  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));
3370    OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3371    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 3 * sizeof(sljit_sw));
3372  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3373    
3374  JUMPHERE(jump);  JUMPHERE(jump);
3375  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3376  /* End of dropping frames. */  /* End of dropping frames. */
3377  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3378    
3379  JUMPHERE(jump);  JUMPHERE(jump);
3380  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3381  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3382  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3383  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);  
 if (common->mark_ptr != 0)  
   {  
   jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
   JUMPTO(SLJIT_JUMP, mainloop);  
   
   JUMPHERE(jump);  
   }  
   
 /* Unknown command. */  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
3384  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3385  }  }
3386    
# Line 2431  static void check_wordboundary(compiler_ Line 3388  static void check_wordboundary(compiler_
3388  {  {
3389  DEFINE_COMPILER;  DEFINE_COMPILER;
3390  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3391    jump_list *skipread_list = NULL;
3392  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3393  struct sljit_jump *jump;  struct sljit_jump *jump;
3394  #endif  #endif
3395    
3396  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3397    
3398  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);
3399  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3400  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3401  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));
# Line 2456  if (common->use_ucp) Line 3414  if (common->use_ucp)
3414    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3415    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3416    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);
3417    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3418    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);
3419    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);
3420    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3421    JUMPHERE(jump);    JUMPHERE(jump);
3422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3423    }    }
# Line 2488  else Line 3446  else
3446  JUMPHERE(skipread);  JUMPHERE(skipread);
3447    
3448  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3449  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3450  peek_char(common);  peek_char(common);
3451    
3452  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 2500  if (common->use_ucp) Line 3458  if (common->use_ucp)
3458    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3459    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3460    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);
3461    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3462    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);
3463    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);
3464    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3465    JUMPHERE(jump);    JUMPHERE(jump);
3466    }    }
3467  else  else
# Line 2529  else Line 3487  else
3487      JUMPHERE(jump);      JUMPHERE(jump);
3488  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3489    }    }
3490  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3491    
3492  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3493  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3494  }  }
3495    
3496    /*
3497      range format:
3498    
3499      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3500      ranges[1] = first bit (0 or 1)
3501      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3502    */
3503    
3504    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3505    {
3506    DEFINE_COMPILER;
3507    struct sljit_jump *jump;
3508    
3509    if (ranges[0] < 0)
3510      return FALSE;
3511    
3512    switch(ranges[0])
3513      {
3514      case 1:
3515      if (readch)
3516        read_char(common);
3517      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3518      return TRUE;
3519    
3520      case 2:
3521      if (readch)
3522        read_char(common);
3523      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3524      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3525      return TRUE;
3526    
3527      case 4:
3528      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3529        {
3530        if (readch)
3531          read_char(common);
3532        if (ranges[1] != 0)
3533          {
3534          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3535          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3536          }
3537        else
3538          {
3539          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3540          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3541          JUMPHERE(jump);
3542          }
3543        return TRUE;
3544        }
3545      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3546        {
3547        if (readch)
3548          read_char(common);
3549        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3550        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3551        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3552        return TRUE;
3553        }
3554      return FALSE;
3555    
3556      default:
3557      return FALSE;
3558      }
3559    }
3560    
3561    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3562    {
3563    int i, bit, length;
3564    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3565    
3566    bit = ctypes[0] & flag;
3567    ranges[0] = -1;
3568    ranges[1] = bit != 0 ? 1 : 0;
3569    length = 0;
3570    
3571    for (i = 1; i < 256; i++)
3572      if ((ctypes[i] & flag) != bit)
3573        {
3574        if (length >= MAX_RANGE_SIZE)
3575          return;
3576        ranges[2 + length] = i;
3577        length++;
3578        bit ^= flag;
3579        }
3580    
3581    if (bit != 0)
3582      {
3583      if (length >= MAX_RANGE_SIZE)
3584        return;
3585      ranges[2 + length] = 256;
3586      length++;
3587      }
3588    ranges[0] = length;
3589    }
3590    
3591    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3592    {
3593    int ranges[2 + MAX_RANGE_SIZE];
3594    pcre_uint8 bit, cbit, all;
3595    int i, byte, length = 0;
3596    
3597    bit = bits[0] & 0x1;
3598    ranges[1] = bit;
3599    /* Can be 0 or 255. */
3600    all = -bit;
3601    
3602    for (i = 0; i < 256; )
3603      {
3604      byte = i >> 3;
3605      if ((i & 0x7) == 0 && bits[byte] == all)
3606        i += 8;
3607      else
3608        {
3609        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3610        if (cbit != bit)
3611          {
3612          if (length >= MAX_RANGE_SIZE)
3613            return FALSE;
3614          ranges[2 + length] = i;
3615          length++;
3616          bit = cbit;
3617          all = -cbit;
3618          }
3619        i++;
3620        }
3621      }
3622    
3623    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3624      {
3625      if (length >= MAX_RANGE_SIZE)
3626        return FALSE;
3627      ranges[2 + length] = 256;
3628      length++;
3629      }
3630    ranges[0] = length;
3631    
3632    return check_ranges(common, ranges, backtracks, FALSE);
3633    }
3634    
3635  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3636  {  {
3637  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3638  DEFINE_COMPILER;  DEFINE_COMPILER;
3639    
3640  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3641    
3642  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3643  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3644  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3645  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3646  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3647  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3648  if (common->utf)  if (common->utf)
3649    {    {
3650  #endif  #endif
3651    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3652    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3653    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3654  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3655    }    }
3656  #endif  #endif
3657  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3658  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);
3659  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3660  }  }
3661    
# Line 2567  static void check_hspace(compiler_common Line 3664  static void check_hspace(compiler_common
3664  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3665  DEFINE_COMPILER;  DEFINE_COMPILER;
3666    
3667  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3668    
3669  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x09);
3670  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3671  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
3672  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3673  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
3674  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3675  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3676  if (common->utf)  if (common->utf)
3677    {    {
3678  #endif  #endif
3679    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3680    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x1680);
3681    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3682    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
3683    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3684    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3685    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
3686    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3687    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
3688    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3689    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x205f - 0x2000);
3690    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3691    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x3000 - 0x2000);
3692  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3693    }    }
3694  #endif  #endif
3695  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3696  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);
3697    
3698  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3699  }  }
# Line 2606  static void check_vspace(compiler_common Line 3703  static void check_vspace(compiler_common
3703  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3704  DEFINE_COMPILER;  DEFINE_COMPILER;
3705    
3706  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3707    
3708  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3709  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x0d - 0x0a);
3710  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3711  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x85 - 0x0a);
3712  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3713  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3714  if (common->utf)  if (common->utf)
3715    {    {
3716  #endif  #endif
3717    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);
3718    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3719    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x2029 - 0x0a);
3720  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3721    }    }
3722  #endif  #endif
3723  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3724  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);
3725    
3726  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3727  }  }
# Line 2638  DEFINE_COMPILER; Line 3735  DEFINE_COMPILER;
3735  struct sljit_jump *jump;  struct sljit_jump *jump;
3736  struct sljit_label *label;  struct sljit_label *label;
3737    
3738  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3739  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3740  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3741  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2667  DEFINE_COMPILER; Line 3764  DEFINE_COMPILER;
3764  struct sljit_jump *jump;  struct sljit_jump *jump;
3765  struct sljit_label *label;  struct sljit_label *label;
3766    
3767  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3768  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3769    
3770  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2710  sljit_emit_fast_return(compiler, RETURN_ Line 3807  sljit_emit_fast_return(compiler, RETURN_
3807    
3808  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3809    
3810  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3811  {  {
3812  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3813  int c1, c2;  pcre_uint32 c1, c2;
3814  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3815  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3816    const ucd_record *ur;
3817    const pcre_uint32 *pp;
3818    
3819  while (src1 < end1)  while (src1 < end1)
3820    {    {
# Line 2723  while (src1 < end1) Line 3822  while (src1 < end1)
3822      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3823    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3824    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3825    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3826      if (c1 != c2 && c1 != c2 + ur->other_case)
3827        {
3828        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3829        for (;;)
3830          {
3831          if (c1 < *pp) return NULL;
3832          if (c1 == *pp++) break;
3833          }
3834        }
3835    }    }
3836  return src2;  return src2;
3837  }  }
# Line 2731  return src2; Line 3839  return src2;
3839  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3840    
3841  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
3842      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3843  {  {
3844  DEFINE_COMPILER;  DEFINE_COMPILER;
3845  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2745  if (caseless && char_has_othercase(commo Line 3853  if (caseless && char_has_othercase(commo
3853    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3854    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3855    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3856  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3857    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3858    othercasebit &= 0xff;    othercasebit &= 0xff;
3859  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3860  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3861      ever are characters outside the BMP whose othercase differs in only one
3862      bit from itself (there currently are none), this code will need to be
3863      revised for COMPILE_PCRE32. */
3864    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3865    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3866      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3867    else    else
3868      othercasebit &= 0xff;      othercasebit &= 0xff;
3869  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3870    }    }
3871    
3872  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3873    {    {
3874  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3875  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3876    if (context->length >= 4)    if (context->length >= 4)
3877      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 2770  if (context->sourcereg == -1) Line 3880  if (context->sourcereg == -1)
3880    else    else
3881  #endif  #endif
3882      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3883  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3884  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3885    if (context->length >= 4)    if (context->length >= 4)
3886      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3887    else    else
3888  #endif  #endif
3889      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3890  #endif  #elif defined COMPILE_PCRE32
3891  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3892    #endif /* COMPILE_PCRE[8|16|32] */
3893    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3894    }    }
3895    
# Line 2793  do Line 3903  do
3903  #endif  #endif
3904    
3905    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3906  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3907    
3908    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3909    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 2808  do Line 3918  do
3918      }      }
3919    context->ucharptr++;    context->ucharptr++;
3920    
3921  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3922    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3923  #else  #else
3924    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
# Line 2816  do Line 3926  do
3926      {      {
3927      if (context->length >= 4)      if (context->length >= 4)
3928        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
 #ifdef COMPILE_PCRE8  
3929      else if (context->length >= 2)      else if (context->length >= 2)
3930        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3931    #if defined COMPILE_PCRE8
3932      else if (context->length >= 1)      else if (context->length >= 1)
3933        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3934  #else  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3935      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3936    
3937      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2832  do Line 3939  do
3939        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3940        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3941          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
3942        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
3943        break;        break;
3944