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

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

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

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