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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 726 by zherczeg, Sun Oct 9 18:53:25 2011 UTC revision 993 by zherczeg, Tue Jul 10 04:33:00 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 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
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 on the stack. Fast, but limited size. */
# Line 79  The code generator follows the recursive Line 82  The code generator follows the recursive
82  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
83  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
84  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
85  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
86    
87    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
88    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  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.
92  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the try path (expected path), and the other is called as
93  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
94  branches on the hot path.  branches on the try path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Hot path: match happens.     Try path: match happens.
98     Fallback path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Hot path: no need to perform a match.     Try path: no need to perform a match.
101     Fallback path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
104  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 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A hot path   A try path
112   '(' hot path (pushing arguments to the stack)   '(' try path (pushing arguments to the stack)
113   B hot path   B try path
114   ')' hot path (pushing arguments to the stack)   ')' try path (pushing arguments to the stack)
115   D hot path   D try path
116   return with successful match   return with successful match
117    
118   D fallback path   D backtrack path
119   ')' 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")
120   B fallback path   B backtrack path
121   C expected path   C expected path
122   jump to D hot path   jump to D try path
123   C fallback path   C backtrack path
124   A fallback path   A backtrack path
125    
126   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
127   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
128   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
129   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
130   the hot path eventually. Otherwise it needs to clear out its own stack   the try path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
134  /*  /*
135  Saved stack frames:  Saved stack frames:
136    
137  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of local variables
138  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the locals
139  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
140  mechanism.  mechanism.
141    
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
160    uschar notbol;    pcre_uint8 notbol;
161    uschar noteol;    pcre_uint8 noteol;
162    uschar notempty;    pcre_uint8 notempty;
163    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    pcre_jit_callback callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171    } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 176  typedef struct stub_list { Line 181  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
182    int data;    int data;
183    struct sljit_jump *start;    struct sljit_jump *start;
184    struct sljit_label *leave;    struct sljit_label *quit;
185    struct stub_list *next;    struct stub_list *next;
186  } stub_list;  } stub_list;
187    
188  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
189    
190  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
191  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_trypath, and contains
192  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackpath. Must be the first member
193  of its descendants. */  of its descendants. */
194  typedef struct fallback_common {  typedef struct backtrack_common {
195    /* Concatenation stack. */    /* Concatenation stack. */
196    struct fallback_common *prev;    struct backtrack_common *prev;
197    jump_list *nextfallbacks;    jump_list *nextbacktracks;
198    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
199    struct fallback_common *top;    struct backtrack_common *top;
200    jump_list *topfallbacks;    jump_list *topbacktracks;
201    /* Opcode pointer. */    /* Opcode pointer. */
202    uschar *cc;    pcre_uchar *cc;
203  } fallback_common;  } backtrack_common;
204    
205  typedef struct assert_fallback {  typedef struct assert_backtrack {
206    fallback_common common;    backtrack_common common;
207    jump_list *condfailed;    jump_list *condfailed;
208    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
209    int framesize;    int framesize;
210    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
211    int localptr;    int localptr;
212    /* For iterators. */    /* For iterators. */
213    struct sljit_label *hotpath;    struct sljit_label *trypath;
214  } assert_fallback;  } assert_backtrack;
215    
216  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
217    fallback_common common;    backtrack_common common;
218    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
219    struct sljit_label *althotpath;    struct sljit_label *alttrypath;
220    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
221    struct sljit_label *recursivehotpath;    struct sljit_label *recursivetrypath;
222    /* For greedy ? operator. */    /* For greedy ? operator. */
223    struct sljit_label *zerohotpath;    struct sljit_label *zerotrypath;
224    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
225    union {    union {
226      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
227      jump_list *condfailed;      jump_list *condfailed;
228      assert_fallback *assert;      assert_backtrack *assert;
229      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
230      int framesize;      int framesize;
231    } u;    } u;
232    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
233    int localptr;    int localptr;
234  } bracket_fallback;  } bracket_backtrack;
235    
236  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
237    fallback_common common;    backtrack_common common;
238    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
239    int localptr;    int localptr;
240    /* Reverting stack is needed. */    /* Reverting stack is needed. */
241    int framesize;    int framesize;
242    /* Allocated stack size. */    /* Allocated stack size. */
243    int stacksize;    int stacksize;
244  } bracketpos_fallback;  } bracketpos_backtrack;
245    
246  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
247    fallback_common common;    backtrack_common common;
248    struct sljit_label *hotpath;    struct sljit_label *trypath;
249  } braminzero_fallback;  } braminzero_backtrack;
250    
251  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
252    fallback_common common;    backtrack_common common;
253    /* Next iteration. */    /* Next iteration. */
254    struct sljit_label *hotpath;    struct sljit_label *trypath;
255  } iterator_fallback;  } iterator_backtrack;
256    
257  typedef struct recurse_entry {  typedef struct recurse_entry {
258    struct recurse_entry *next;    struct recurse_entry *next;
# Line 259  typedef struct recurse_entry { Line 264  typedef struct recurse_entry {
264    int start;    int start;
265  } recurse_entry;  } recurse_entry;
266    
267  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
268    fallback_common common;    backtrack_common common;
269  } recurse_fallback;  } recurse_backtrack;
270    
271    #define MAX_RANGE_SIZE 6
272    
273  typedef struct compiler_common {  typedef struct compiler_common {
274    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
275    uschar *start;    pcre_uchar *start;
276    int localsize;  
277      /* Opcode local area direct map. */
278    int *localptrs;    int *localptrs;
   const uschar *fcc;  
   sljit_w lcc;  
279    int cbraptr;    int cbraptr;
280      /* OVector starting point. Must be divisible by 2. */
281      int ovector_start;
282      /* Last known position of the requested byte. */
283      int req_char_ptr;
284      /* Head of the last recursion. */
285      int recursive_head;
286      /* First inspected character for partial matching. */
287      int start_used_ptr;
288      /* Starting pointer for partial soft matches. */
289      int hit_start;
290      /* End pointer of the first line. */
291      int first_line_end;
292      /* Points to the marked string. */
293      int mark_ptr;
294    
295      /* Flipped and lower case tables. */
296      const pcre_uint8 *fcc;
297      sljit_w lcc;
298      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
299      int mode;
300      /* Newline control. */
301    int nltype;    int nltype;
302    int newline;    int newline;
303    int bsr_nltype;    int bsr_nltype;
304      /* Dollar endonly. */
305    int endonly;    int endonly;
306      BOOL has_set_som;
307      /* Tables. */
308    sljit_w ctypes;    sljit_w ctypes;
309      int digits[2 + MAX_RANGE_SIZE];
310      /* Named capturing brackets. */
311      sljit_uw name_table;
312      sljit_w name_count;
313      sljit_w name_entry_size;
314    
315      /* Labels and jump lists. */
316      struct sljit_label *partialmatchlabel;
317      struct sljit_label *quitlabel;
318    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
319    stub_list *stubs;    stub_list *stubs;
320    recurse_entry *entries;    recurse_entry *entries;
321    recurse_entry *currententry;    recurse_entry *currententry;
322      jump_list *partialmatch;
323      jump_list *quit;
324    jump_list *accept;    jump_list *accept;
325    jump_list *calllimit;    jump_list *calllimit;
326    jump_list *stackalloc;    jump_list *stackalloc;
# Line 291  typedef struct compiler_common { Line 332  typedef struct compiler_common {
332    jump_list *casefulcmp;    jump_list *casefulcmp;
333    jump_list *caselesscmp;    jump_list *caselesscmp;
334    BOOL jscript_compat;    BOOL jscript_compat;
335  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
336    BOOL utf8;    BOOL utf;
337  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
338    BOOL useucp;    BOOL use_ucp;
339  #endif  #endif
340    jump_list *utf8readchar;    jump_list *utfreadchar;
341    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
342      jump_list *utfreadtype8;
343  #endif  #endif
344    #endif /* SUPPORT_UTF */
345  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
346    jump_list *getucd;    jump_list *getucd;
347  #endif  #endif
# Line 310  typedef struct compare_context { Line 353  typedef struct compare_context {
353    int length;    int length;
354    int sourcereg;    int sourcereg;
355  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
356    int byteptr;    int ucharptr;
357    union {    union {
358      int asint;      sljit_i asint;
359      short asshort;      sljit_uh asushort;
360    #ifdef COMPILE_PCRE8
361      sljit_ub asbyte;      sljit_ub asbyte;
362      sljit_ub asbytes[4];      sljit_ub asuchars[4];
363    #else
364    #ifdef COMPILE_PCRE16
365        sljit_uh asuchars[2];
366    #endif
367    #endif
368    } c;    } c;
369    union {    union {
370      int asint;      sljit_i asint;
371      short asshort;      sljit_uh asushort;
372    #ifdef COMPILE_PCRE8
373      sljit_ub asbyte;      sljit_ub asbyte;
374      sljit_ub asbytes[4];      sljit_ub asuchars[4];
375    #else
376    #ifdef COMPILE_PCRE16
377        sljit_uh asuchars[2];
378    #endif
379    #endif
380    } oc;    } oc;
381  #endif  #endif
382  } compare_context;  } compare_context;
383    
384  enum {  enum {
385    frame_end = 0,    frame_end = 0,
386    frame_setstrbegin = -1    frame_setstrbegin = -1,
387      frame_setmark = -2
388  };  };
389    
390    /* Undefine sljit macros. */
391    #undef CMP
392    
393  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
394  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
395    
396  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
397  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
398  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
399  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
400  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
401  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
402  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
403  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
404  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
405  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
406    
407  /* Locals layout. */  /* Locals layout. */
# Line 352  enum { Line 411  enum {
411  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
412  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
413  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
414  /* Max limit of recursions. */  /* Max limit of recursions. */
415  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
416  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
417  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
418  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
419  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. */
420  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
421  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
422  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
423  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
424    
425    #ifdef COMPILE_PCRE8
426    #define MOV_UCHAR  SLJIT_MOV_UB
427    #define MOVU_UCHAR SLJIT_MOVU_UB
428    #else
429    #ifdef COMPILE_PCRE16
430    #define MOV_UCHAR  SLJIT_MOV_UH
431    #define MOVU_UCHAR SLJIT_MOVU_UH
432    #else
433    #error Unsupported compiling mode
434    #endif
435    #endif
436    
437  /* Shortcuts. */  /* Shortcuts. */
438  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 390  the start pointers when the end of the c Line 455  the start pointers when the end of the c
455    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))
456  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
457    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
458    #define GET_LOCAL_BASE(dst, dstw, offset) \
459      sljit_get_local_base(compiler, (dst), (dstw), (offset))
460    
461  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
462  {  {
463  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));
464  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 408  return cc; Line 475  return cc;
475   init_frame   init_frame
476   get_localsize   get_localsize
477   copy_locals   copy_locals
478   compile_hotpath   compile_trypath
479   compile_fallbackpath   compile_backtrackpath
480  */  */
481    
482  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
483  {  {
484  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
485  switch(*cc)  switch(*cc)
# Line 461  switch(*cc) Line 528  switch(*cc)
528    case OP_BRAZERO:    case OP_BRAZERO:
529    case OP_BRAMINZERO:    case OP_BRAMINZERO:
530    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
531      case OP_COMMIT:
532    case OP_FAIL:    case OP_FAIL:
533    case OP_ACCEPT:    case OP_ACCEPT:
534    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
535    case OP_SKIPZERO:    case OP_SKIPZERO:
536    return cc + 1;    return cc + 1;
537    
538      case OP_ANYBYTE:
539    #ifdef SUPPORT_UTF
540      if (common->utf) return NULL;
541    #endif
542      return cc + 1;
543    
544    case OP_CHAR:    case OP_CHAR:
545    case OP_CHARI:    case OP_CHARI:
546    case OP_NOT:    case OP_NOT:
547    case OP_NOTI:    case OP_NOTI:
   
548    case OP_STAR:    case OP_STAR:
549    case OP_MINSTAR:    case OP_MINSTAR:
550    case OP_PLUS:    case OP_PLUS:
# Line 509  switch(*cc) Line 582  switch(*cc)
582    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
583    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
584    cc += 2;    cc += 2;
585  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
586    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]);
587  #endif  #endif
588    return cc;    return cc;
589    
# Line 530  switch(*cc) Line 603  switch(*cc)
603    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
604    case OP_NOTEXACTI:    case OP_NOTEXACTI:
605    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
606    cc += 4;    cc += 2 + IMM2_SIZE;
607  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
608    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]);
609  #endif  #endif
610    return cc;    return cc;
611    
612    case OP_NOTPROP:    case OP_NOTPROP:
613    case OP_PROP:    case OP_PROP:
614      return cc + 1 + 2;
615    
616    case OP_TYPEUPTO:    case OP_TYPEUPTO:
617    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
618    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 545  switch(*cc) Line 620  switch(*cc)
620    case OP_REF:    case OP_REF:
621    case OP_REFI:    case OP_REFI:
622    case OP_CREF:    case OP_CREF:
623      case OP_NCREF:
624      case OP_RREF:
625      case OP_NRREF:
626    case OP_CLOSE:    case OP_CLOSE:
627    cc += 3;    cc += 1 + IMM2_SIZE;
628    return cc;    return cc;
629    
630    case OP_CRRANGE:    case OP_CRRANGE:
631    case OP_CRMINRANGE:    case OP_CRMINRANGE:
632    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
633    
634    case OP_CLASS:    case OP_CLASS:
635    case OP_NCLASS:    case OP_NCLASS:
636    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
637    
638  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
639    case OP_XCLASS:    case OP_XCLASS:
640    return cc + GET(cc, 1);    return cc + GET(cc, 1);
641  #endif  #endif
# Line 587  switch(*cc) Line 665  switch(*cc)
665    case OP_CBRAPOS:    case OP_CBRAPOS:
666    case OP_SCBRA:    case OP_SCBRA:
667    case OP_SCBRAPOS:    case OP_SCBRAPOS:
668    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
669    
670      case OP_MARK:
671      return cc + 1 + 2 + cc[1];
672    
673    default:    default:
674    return NULL;    return NULL;
675    }    }
676  }  }
677    
678  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  #define CASE_ITERATOR_LOCAL1 \
679        case OP_MINSTAR: \
680        case OP_MINPLUS: \
681        case OP_QUERY: \
682        case OP_MINQUERY: \
683        case OP_MINSTARI: \
684        case OP_MINPLUSI: \
685        case OP_QUERYI: \
686        case OP_MINQUERYI: \
687        case OP_NOTMINSTAR: \
688        case OP_NOTMINPLUS: \
689        case OP_NOTQUERY: \
690        case OP_NOTMINQUERY: \
691        case OP_NOTMINSTARI: \
692        case OP_NOTMINPLUSI: \
693        case OP_NOTQUERYI: \
694        case OP_NOTMINQUERYI:
695    
696    #define CASE_ITERATOR_LOCAL2A \
697        case OP_STAR: \
698        case OP_PLUS: \
699        case OP_STARI: \
700        case OP_PLUSI: \
701        case OP_NOTSTAR: \
702        case OP_NOTPLUS: \
703        case OP_NOTSTARI: \
704        case OP_NOTPLUSI:
705    
706    #define CASE_ITERATOR_LOCAL2B \
707        case OP_UPTO: \
708        case OP_MINUPTO: \
709        case OP_UPTOI: \
710        case OP_MINUPTOI: \
711        case OP_NOTUPTO: \
712        case OP_NOTMINUPTO: \
713        case OP_NOTUPTOI: \
714        case OP_NOTMINUPTOI:
715    
716    #define CASE_ITERATOR_TYPE_LOCAL1 \
717        case OP_TYPEMINSTAR: \
718        case OP_TYPEMINPLUS: \
719        case OP_TYPEQUERY: \
720        case OP_TYPEMINQUERY:
721    
722    #define CASE_ITERATOR_TYPE_LOCAL2A \
723        case OP_TYPESTAR: \
724        case OP_TYPEPLUS:
725    
726    #define CASE_ITERATOR_TYPE_LOCAL2B \
727        case OP_TYPEUPTO: \
728        case OP_TYPEMINUPTO:
729    
730    static int get_class_iterator_size(pcre_uchar *cc)
731    {
732    switch(*cc)
733      {
734      case OP_CRSTAR:
735      case OP_CRPLUS:
736      return 2;
737    
738      case OP_CRMINSTAR:
739      case OP_CRMINPLUS:
740      case OP_CRQUERY:
741      case OP_CRMINQUERY:
742      return 1;
743    
744      case OP_CRRANGE:
745      case OP_CRMINRANGE:
746      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
747        return 0;
748      return 2;
749    
750      default:
751      return 0;
752      }
753    }
754    
755    static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
756  {  {
757  int localspace = 0;  int localspace = 0;
758  uschar *alternative;  pcre_uchar *alternative;
759    pcre_uchar *end = NULL;
760    int space, size, bracketlen;
761    
762  /* 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. */
763  while (cc < ccend)  while (cc < ccend)
764    {    {
765      space = 0;
766      size = 0;
767      bracketlen = 0;
768    switch(*cc)    switch(*cc)
769      {      {
770        case OP_SET_SOM:
771        common->has_set_som = TRUE;
772        cc += 1;
773        break;
774    
775      case OP_ASSERT:      case OP_ASSERT:
776      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
777      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 614  while (cc < ccend) Line 783  while (cc < ccend)
783      case OP_SBRAPOS:      case OP_SBRAPOS:
784      case OP_SCOND:      case OP_SCOND:
785      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
786      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
787      break;      break;
788    
789      case OP_CBRAPOS:      case OP_CBRAPOS:
790      case OP_SCBRAPOS:      case OP_SCBRAPOS:
791      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
792      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
793      break;      break;
794    
795      case OP_COND:      case OP_COND:
# Line 628  while (cc < ccend) Line 797  while (cc < ccend)
797      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
798      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
799        localspace += sizeof(sljit_w);        localspace += sizeof(sljit_w);
800        bracketlen = 1 + LINK_SIZE;
801        break;
802    
803        case OP_BRA:
804        bracketlen = 1 + LINK_SIZE;
805        break;
806    
807        case OP_CBRA:
808        case OP_SCBRA:
809        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
810        break;
811    
812        CASE_ITERATOR_LOCAL1
813        space = 1;
814        size = -2;
815        break;
816    
817        CASE_ITERATOR_LOCAL2A
818        space = 2;
819        size = -2;
820        break;
821    
822        CASE_ITERATOR_LOCAL2B
823        space = 2;
824        size = -(2 + IMM2_SIZE);
825        break;
826    
827        CASE_ITERATOR_TYPE_LOCAL1
828        space = 1;
829        size = 1;
830        break;
831    
832        CASE_ITERATOR_TYPE_LOCAL2A
833        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
834          space = 2;
835        size = 1;
836        break;
837    
838        CASE_ITERATOR_TYPE_LOCAL2B
839        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
840          space = 2;
841        size = 1 + IMM2_SIZE;
842        break;
843    
844        case OP_CLASS:
845        case OP_NCLASS:
846        size += 1 + 32 / sizeof(pcre_uchar);
847        space = get_class_iterator_size(cc + size);
848        break;
849    
850    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
851        case OP_XCLASS:
852        size = GET(cc, 1);
853        space = get_class_iterator_size(cc + size);
854        break;
855    #endif
856    
857        case OP_RECURSE:
858        /* Set its value only once. */
859        if (common->recursive_head == 0)
860          {
861          common->recursive_head = common->ovector_start;
862          common->ovector_start += sizeof(sljit_w);
863          }
864      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
865      break;      break;
866    
867        case OP_MARK:
868        if (common->mark_ptr == 0)
869          {
870          common->mark_ptr = common->ovector_start;
871          common->ovector_start += sizeof(sljit_w);
872          }
873        cc += 1 + 2 + cc[1];
874        break;
875    
876      default:      default:
877      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
878      if (cc == NULL)      if (cc == NULL)
879        return -1;        return -1;
880      break;      break;
881      }      }
882    
883      if (space > 0 && cc >= end)
884        localspace += sizeof(sljit_w) * space;
885    
886      if (size != 0)
887        {
888        if (size < 0)
889          {
890          cc += -size;
891    #ifdef SUPPORT_UTF
892          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
893    #endif
894          }
895        else
896          cc += size;
897        }
898    
899      if (bracketlen > 0)
900        {
901        if (cc >= end)
902          {
903          end = bracketend(cc);
904          if (end[-1 - LINK_SIZE] == OP_KET)
905            end = NULL;
906          }
907        cc += bracketlen;
908        }
909    }    }
910  return localspace;  return localspace;
911  }  }
912    
913  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
914  {  {
915  uschar *cc = common->start;  pcre_uchar *cc = common->start;
916  uschar *alternative;  pcre_uchar *alternative;
917    pcre_uchar *end = NULL;
918    int space, size, bracketlen;
919    
920  while (cc < ccend)  while (cc < ccend)
921    {    {
922      space = 0;
923      size = 0;
924      bracketlen = 0;
925    switch(*cc)    switch(*cc)
926      {      {
927      case OP_ASSERT:      case OP_ASSERT:
# Line 661  while (cc < ccend) Line 936  while (cc < ccend)
936      case OP_SCOND:      case OP_SCOND:
937      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
938      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
939      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
940      break;      break;
941    
942      case OP_CBRAPOS:      case OP_CBRAPOS:
943      case OP_SCBRAPOS:      case OP_SCBRAPOS:
944      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
945      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
946      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      case OP_COND:      case OP_COND:
# Line 679  while (cc < ccend) Line 954  while (cc < ccend)
954        common->localptrs[cc - common->start] = localptr;        common->localptrs[cc - common->start] = localptr;
955        localptr += sizeof(sljit_w);        localptr += sizeof(sljit_w);
956        }        }
957      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
958        break;
959    
960        case OP_BRA:
961        bracketlen = 1 + LINK_SIZE;
962        break;
963    
964        case OP_CBRA:
965        case OP_SCBRA:
966        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
967        break;
968    
969        CASE_ITERATOR_LOCAL1
970        space = 1;
971        size = -2;
972        break;
973    
974        CASE_ITERATOR_LOCAL2A
975        space = 2;
976        size = -2;
977        break;
978    
979        CASE_ITERATOR_LOCAL2B
980        space = 2;
981        size = -(2 + IMM2_SIZE);
982        break;
983    
984        CASE_ITERATOR_TYPE_LOCAL1
985        space = 1;
986        size = 1;
987        break;
988    
989        CASE_ITERATOR_TYPE_LOCAL2A
990        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
991          space = 2;
992        size = 1;
993        break;
994    
995        CASE_ITERATOR_TYPE_LOCAL2B
996        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
997          space = 2;
998        size = 1 + IMM2_SIZE;
999        break;
1000    
1001        case OP_CLASS:
1002        case OP_NCLASS:
1003        size += 1 + 32 / sizeof(pcre_uchar);
1004        space = get_class_iterator_size(cc + size);
1005        break;
1006    
1007    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1008        case OP_XCLASS:
1009        size = GET(cc, 1);
1010        space = get_class_iterator_size(cc + size);
1011      break;      break;
1012    #endif
1013    
1014      default:      default:
1015      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1016      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1017      break;      break;
1018      }      }
1019    
1020      if (space > 0 && cc >= end)
1021        {
1022        common->localptrs[cc - common->start] = localptr;
1023        localptr += sizeof(sljit_w) * space;
1024        }
1025    
1026      if (size != 0)
1027        {
1028        if (size < 0)
1029          {
1030          cc += -size;
1031    #ifdef SUPPORT_UTF
1032          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1033    #endif
1034          }
1035        else
1036          cc += size;
1037        }
1038    
1039      if (bracketlen > 0)
1040        {
1041        if (cc >= end)
1042          {
1043          end = bracketend(cc);
1044          if (end[-1 - LINK_SIZE] == OP_KET)
1045            end = NULL;
1046          }
1047        cc += bracketlen;
1048        }
1049    }    }
1050  }  }
1051    
1052  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
1053  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1054  {  {
1055  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1056  int length = 0;  int length = 0;
1057  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1058  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1059    BOOL setmark_found = recursive;
1060    
1061  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1062    {    {
# Line 710  while (cc < ccend) Line 1070  while (cc < ccend)
1070    switch(*cc)    switch(*cc)
1071      {      {
1072      case OP_SET_SOM:      case OP_SET_SOM:
1073      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1074      if (!setsom_found)      if (!setsom_found)
1075        {        {
1076        length += 2;        length += 2;
1077        setsom_found = TRUE;        setsom_found = TRUE;
1078        }        }
1079      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1080        break;
1081    
1082        case OP_MARK:
1083        SLJIT_ASSERT(common->mark_ptr != 0);
1084        if (!setmark_found)
1085          {
1086          length += 2;
1087          setmark_found = TRUE;
1088          }
1089        cc += 1 + 2 + cc[1];
1090        break;
1091    
1092        case OP_RECURSE:
1093        if (common->has_set_som && !setsom_found)
1094          {
1095          length += 2;
1096          setsom_found = TRUE;
1097          }
1098        if (common->mark_ptr != 0 && !setmark_found)
1099          {
1100          length += 2;
1101          setmark_found = TRUE;
1102          }
1103        cc += 1 + LINK_SIZE;
1104      break;      break;
1105    
1106      case OP_CBRA:      case OP_CBRA:
# Line 724  while (cc < ccend) Line 1108  while (cc < ccend)
1108      case OP_SCBRA:      case OP_SCBRA:
1109      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1110      length += 3;      length += 3;
1111      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1112      break;      break;
1113    
1114      default:      default:
# Line 742  if (length > 0) Line 1126  if (length > 0)
1126  return -1;  return -1;
1127  }  }
1128    
1129  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)
1130  {  {
1131  DEFINE_COMPILER;  DEFINE_COMPILER;
1132  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1133  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1134    BOOL setmark_found = recursive;
1135  int offset;  int offset;
1136    
1137  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1138    SLJIT_UNUSED_ARG(stacktop);
1139  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1140    
1141  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 760  while (cc < ccend) Line 1146  while (cc < ccend)
1146    switch(*cc)    switch(*cc)
1147      {      {
1148      case OP_SET_SOM:      case OP_SET_SOM:
1149      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1150      if (!setsom_found)      if (!setsom_found)
1151        {        {
1152        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 770  while (cc < ccend) Line 1156  while (cc < ccend)
1156        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1157        setsom_found = TRUE;        setsom_found = TRUE;
1158        }        }
1159      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1160        break;
1161    
1162        case OP_MARK:
1163        SLJIT_ASSERT(common->mark_ptr != 0);
1164        if (!setmark_found)
1165          {
1166          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1167          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1168          stackpos += (int)sizeof(sljit_w);
1169          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1170          stackpos += (int)sizeof(sljit_w);
1171          setmark_found = TRUE;
1172          }
1173        cc += 1 + 2 + cc[1];
1174        break;
1175    
1176        case OP_RECURSE:
1177        if (common->has_set_som && !setsom_found)
1178          {
1179          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1180          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1181          stackpos += (int)sizeof(sljit_w);
1182          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1183          stackpos += (int)sizeof(sljit_w);
1184          setsom_found = TRUE;
1185          }
1186        if (common->mark_ptr != 0 && !setmark_found)
1187          {
1188          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1189          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1190          stackpos += (int)sizeof(sljit_w);
1191          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1192          stackpos += (int)sizeof(sljit_w);
1193          setmark_found = TRUE;
1194          }
1195        cc += 1 + LINK_SIZE;
1196      break;      break;
1197    
1198      case OP_CBRA:      case OP_CBRA:
# Line 787  while (cc < ccend) Line 1209  while (cc < ccend)
1209      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1210      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
1211    
1212      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1213      break;      break;
1214    
1215      default:      default:
# Line 800  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1222  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1222  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1223  }  }
1224    
1225  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1226  {  {
1227  int localsize = 2;  int localsize = 2;
1228  uschar *alternative;  int size;
1229    pcre_uchar *alternative;
1230  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
1231  while (cc < ccend)  while (cc < ccend)
1232    {    {
1233      size = 0;
1234    switch(*cc)    switch(*cc)
1235      {      {
1236      case OP_ASSERT:      case OP_ASSERT:
# Line 826  while (cc < ccend) Line 1250  while (cc < ccend)
1250      case OP_CBRA:      case OP_CBRA:
1251      case OP_SCBRA:      case OP_SCBRA:
1252      localsize++;      localsize++;
1253      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1254      break;      break;
1255    
1256      case OP_CBRAPOS:      case OP_CBRAPOS:
1257      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1258      localsize += 2;      localsize += 2;
1259      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1260      break;      break;
1261    
1262      case OP_COND:      case OP_COND:
# Line 843  while (cc < ccend) Line 1267  while (cc < ccend)
1267      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1268      break;      break;
1269    
1270        CASE_ITERATOR_LOCAL1
1271        if (PRIV_DATA(cc))
1272          localsize++;
1273        cc += 2;
1274    #ifdef SUPPORT_UTF
1275        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1276    #endif
1277        break;
1278    
1279        CASE_ITERATOR_LOCAL2A
1280        if (PRIV_DATA(cc))
1281          localsize += 2;
1282        cc += 2;
1283    #ifdef SUPPORT_UTF
1284        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1285    #endif
1286        break;
1287    
1288        CASE_ITERATOR_LOCAL2B
1289        if (PRIV_DATA(cc))
1290          localsize += 2;
1291        cc += 2 + IMM2_SIZE;
1292    #ifdef SUPPORT_UTF
1293        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1294    #endif
1295        break;
1296    
1297        CASE_ITERATOR_TYPE_LOCAL1
1298        if (PRIV_DATA(cc))
1299          localsize++;
1300        cc += 1;
1301        break;
1302    
1303        CASE_ITERATOR_TYPE_LOCAL2A
1304        if (PRIV_DATA(cc))
1305          localsize += 2;
1306        cc += 1;
1307        break;
1308    
1309        CASE_ITERATOR_TYPE_LOCAL2B
1310        if (PRIV_DATA(cc))
1311          localsize += 2;
1312        cc += 1 + IMM2_SIZE;
1313        break;
1314    
1315        case OP_CLASS:
1316        case OP_NCLASS:
1317    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1318        case OP_XCLASS:
1319        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1320    #else
1321        size = 1 + 32 / (int)sizeof(pcre_uchar);
1322    #endif
1323        if (PRIV_DATA(cc))
1324          localsize += get_class_iterator_size(cc + size);
1325        cc += size;
1326        break;
1327    
1328      default:      default:
1329      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1330      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 853  SLJIT_ASSERT(cc == ccend); Line 1335  SLJIT_ASSERT(cc == ccend);
1335  return localsize;  return localsize;
1336  }  }
1337    
1338  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1339    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1340  {  {
1341  DEFINE_COMPILER;  DEFINE_COMPILER;
1342  int srcw[2];  int srcw[2];
1343  int count;  int count, size;
1344  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1345  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1346  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1347  uschar *alternative;  pcre_uchar *alternative;
1348  enum {  enum {
1349    start,    start,
1350    loop,    loop,
# Line 897  while (status != end) Line 1379  while (status != end)
1379    switch(status)    switch(status)
1380      {      {
1381      case start:      case start:
1382      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1383      count = 1;      count = 1;
1384      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1385      status = loop;      status = loop;
1386      break;      break;
1387    
# Line 923  while (status != end) Line 1405  while (status != end)
1405        case OP_SBRAPOS:        case OP_SBRAPOS:
1406        case OP_SCOND:        case OP_SCOND:
1407        count = 1;        count = 1;
1408        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1409        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1410        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1411        break;        break;
# Line 932  while (status != end) Line 1414  while (status != end)
1414        case OP_SCBRA:        case OP_SCBRA:
1415        count = 1;        count = 1;
1416        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1417        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1418        break;        break;
1419    
1420        case OP_CBRAPOS:        case OP_CBRAPOS:
1421        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1422        count = 2;        count = 2;
1423        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1424        srcw[0] = PRIV(cc);        srcw[1] = PRIV_DATA(cc);
1425        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1426        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1427        break;        break;
1428    
1429        case OP_COND:        case OP_COND:
# Line 950  while (status != end) Line 1432  while (status != end)
1432        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1433          {          {
1434          count = 1;          count = 1;
1435          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1436          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1437          }          }
1438        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1439        break;        break;
1440    
1441        default:        CASE_ITERATOR_LOCAL1
1442        cc = next_opcode(common, cc);        if (PRIV_DATA(cc))
1443        SLJIT_ASSERT(cc != NULL);          {
1444            count = 1;
1445            srcw[0] = PRIV_DATA(cc);
1446            }
1447          cc += 2;
1448    #ifdef SUPPORT_UTF
1449          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1450    #endif
1451        break;        break;
       }  
     break;  
1452    
1453      case end:        CASE_ITERATOR_LOCAL2A
1454      SLJIT_ASSERT_STOP();        if (PRIV_DATA(cc))
1455      break;          {
1456      }          count = 2;
1457            srcw[0] = PRIV_DATA(cc);
1458            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1459            }
1460          cc += 2;
1461    #ifdef SUPPORT_UTF
1462          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1463    #endif
1464          break;
1465    
1466    while (count > 0)        CASE_ITERATOR_LOCAL2B
1467      {        if (PRIV_DATA(cc))
     count--;  
     if (save)  
       {  
       if (tmp1next)  
1468          {          {
1469          if (!tmp1empty)          count = 2;
1470            {          srcw[0] = PRIV_DATA(cc);
1471            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1472            }
1473          cc += 2 + IMM2_SIZE;
1474    #ifdef SUPPORT_UTF
1475          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1476    #endif
1477          break;
1478    
1479          CASE_ITERATOR_TYPE_LOCAL1
1480          if (PRIV_DATA(cc))
1481            {
1482            count = 1;
1483            srcw[0] = PRIV_DATA(cc);
1484            }
1485          cc += 1;
1486          break;
1487    
1488          CASE_ITERATOR_TYPE_LOCAL2A
1489          if (PRIV_DATA(cc))
1490            {
1491            count = 2;
1492            srcw[0] = PRIV_DATA(cc);
1493            srcw[1] = srcw[0] + sizeof(sljit_w);
1494            }
1495          cc += 1;
1496          break;
1497    
1498          CASE_ITERATOR_TYPE_LOCAL2B
1499          if (PRIV_DATA(cc))
1500            {
1501            count = 2;
1502            srcw[0] = PRIV_DATA(cc);
1503            srcw[1] = srcw[0] + sizeof(sljit_w);
1504            }
1505          cc += 1 + IMM2_SIZE;
1506          break;
1507    
1508          case OP_CLASS:
1509          case OP_NCLASS:
1510    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1511          case OP_XCLASS:
1512          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1513    #else
1514          size = 1 + 32 / (int)sizeof(pcre_uchar);
1515    #endif
1516          if (PRIV_DATA(cc))
1517            switch(get_class_iterator_size(cc + size))
1518              {
1519              case 1:
1520              count = 1;
1521              srcw[0] = PRIV_DATA(cc);
1522              break;
1523    
1524              case 2:
1525              count = 2;
1526              srcw[0] = PRIV_DATA(cc);
1527              srcw[1] = srcw[0] + sizeof(sljit_w);
1528              break;
1529    
1530              default:
1531              SLJIT_ASSERT_STOP();
1532              break;
1533              }
1534          cc += size;
1535          break;
1536    
1537          default:
1538          cc = next_opcode(common, cc);
1539          SLJIT_ASSERT(cc != NULL);
1540          break;
1541          }
1542        break;
1543    
1544        case end:
1545        SLJIT_ASSERT_STOP();
1546        break;
1547        }
1548    
1549      while (count > 0)
1550        {
1551        count--;
1552        if (save)
1553          {
1554          if (tmp1next)
1555            {
1556            if (!tmp1empty)
1557              {
1558              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1559            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_w);
1560            }            }
1561          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
# Line 1058  if (save) Line 1636  if (save)
1636  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1637  }  }
1638    
1639    #undef CASE_ITERATOR_LOCAL1
1640    #undef CASE_ITERATOR_LOCAL2A
1641    #undef CASE_ITERATOR_LOCAL2B
1642    #undef CASE_ITERATOR_TYPE_LOCAL1
1643    #undef CASE_ITERATOR_TYPE_LOCAL2A
1644    #undef CASE_ITERATOR_TYPE_LOCAL2B
1645    
1646  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1647  {  {
1648  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1095  if (list_item) Line 1680  if (list_item)
1680    list_item->type = type;    list_item->type = type;
1681    list_item->data = data;    list_item->data = data;
1682    list_item->start = start;    list_item->start = start;
1683    list_item->leave = LABEL();    list_item->quit = LABEL();
1684    list_item->next = common->stubs;    list_item->next = common->stubs;
1685    common->stubs = list_item;    common->stubs = list_item;
1686    }    }
# Line 1115  while (list_item) Line 1700  while (list_item)
1700      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1701      break;      break;
1702      }      }
1703    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1704    list_item = list_item->next;    list_item = list_item->next;
1705    }    }
1706  common->stubs = NULL;  common->stubs = NULL;
# Line 1158  struct sljit_label *loop; Line 1743  struct sljit_label *loop;
1743  int i;  int i;
1744  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1745  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1746  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));
1747  if (length < 8)  if (length < 8)
1748    {    {
1749    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1166  if (length < 8) Line 1751  if (length < 8)
1751    }    }
1752  else  else
1753    {    {
1754    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));
1755    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1756    loop = LABEL();    loop = LABEL();
1757    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 1182  struct sljit_label *loop; Line 1767  struct sljit_label *loop;
1767  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1768    
1769  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1770  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));
1771  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);
1772    
1773  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1774    if (common->mark_ptr != 0)
1775      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1776  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));
1777    if (common->mark_ptr != 0)
1778      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1779  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));
1780  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));
1781  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1782  /* Unlikely, but possible */  /* Unlikely, but possible */
1783  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1784  loop = LABEL();  loop = LABEL();
1785  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);
1786  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));
1787  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1788  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1789    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1790    #endif
1791    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1792  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);
1793  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1794  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1204  JUMPHERE(earlyexit); Line 1796  JUMPHERE(earlyexit);
1796  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1797  if (topbracket > 1)  if (topbracket > 1)
1798    {    {
1799    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));
1800    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1801    
1802    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1803    loop = LABEL();    loop = LABEL();
1804    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)));
1805    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);
1806    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);
1807    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1808    }    }
1809  else  else
1810    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1811  }  }
1812    
1813  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)
1814    {
1815    DEFINE_COMPILER;
1816    
1817    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1818    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1819    
1820    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1821    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1822    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1823    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);
1824    
1825    /* Store match begin and end. */
1826    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1827    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1828    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);
1829    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1830    #ifdef COMPILE_PCRE16
1831    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1832    #endif
1833    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1834    
1835    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1836    #ifdef COMPILE_PCRE16
1837    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1838    #endif
1839    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1840    
1841    JUMPTO(SLJIT_JUMP, quit);
1842    }
1843    
1844    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1845    {
1846    /* May destroy TMP1. */
1847    DEFINE_COMPILER;
1848    struct sljit_jump *jump;
1849    
1850    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1851      {
1852      /* The value of -1 must be kept for start_used_ptr! */
1853      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1854      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1855      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1856      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1857      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1858      JUMPHERE(jump);
1859      }
1860    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1861      {
1862      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1863      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1864      JUMPHERE(jump);
1865      }
1866    }
1867    
1868    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1869  {  {
1870  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1871  unsigned int c;  unsigned int c;
1872    
1873  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1874  if (common->utf8)  if (common->utf)
1875    {    {
1876    GETCHAR(c, cc);    GETCHAR(c, cc);
1877    if (c > 127)    if (c > 127)
# Line 1235  if (common->utf8) Line 1882  if (common->utf8)
1882      return FALSE;      return FALSE;
1883  #endif  #endif
1884      }      }
1885    #ifndef COMPILE_PCRE8
1886      return common->fcc[c] != c;
1887    #endif
1888    }    }
1889  else  else
1890  #endif  #endif
1891    c = *cc;    c = *cc;
1892  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1893  }  }
1894    
1895  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)
1896  {  {
1897  /* Returns with the othercase. */  /* Returns with the othercase. */
1898  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1899  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1900    {    {
1901  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1902    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1255  if (common->utf8 && c > 127) Line 1905  if (common->utf8 && c > 127)
1905  #endif  #endif
1906    }    }
1907  #endif  #endif
1908  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1909  }  }
1910    
1911  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)
1912  {  {
1913  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1914  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1915  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1916  int n;  int n;
1917  #endif  #endif
1918    
1919  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1920  if (common->utf8)  if (common->utf)
1921    {    {
1922    GETCHAR(c, cc);    GETCHAR(c, cc);
1923    if (c <= 127)    if (c <= 127)
# Line 1284  if (common->utf8) Line 1934  if (common->utf8)
1934  else  else
1935    {    {
1936    c = *cc;    c = *cc;
1937    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1938    }    }
1939  #else  #else
1940  c = *cc;  c = *cc;
1941  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1942  #endif  #endif
1943    
1944  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1302  if (c <= 127 && bit == 0x20) Line 1952  if (c <= 127 && bit == 0x20)
1952  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1953    return 0;    return 0;
1954    
1955  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1956  if (common->utf8 && c > 127)  
1957    #ifdef SUPPORT_UTF
1958    if (common->utf && c > 127)
1959    {    {
1960    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1961    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1962      {      {
1963      n--;      n--;
# Line 1313  if (common->utf8 && c > 127) Line 1965  if (common->utf8 && c > 127)
1965      }      }
1966    return (n << 8) | bit;    return (n << 8) | bit;
1967    }    }
1968  #endif  #endif /* SUPPORT_UTF */
1969  return (0 << 8) | bit;  return (0 << 8) | bit;
1970    
1971    #else /* COMPILE_PCRE8 */
1972    
1973    #ifdef COMPILE_PCRE16
1974    #ifdef SUPPORT_UTF
1975    if (common->utf && c > 65535)
1976      {
1977      if (bit >= (1 << 10))
1978        bit >>= 10;
1979      else
1980        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1981      }
1982    #endif /* SUPPORT_UTF */
1983    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1984    #endif /* COMPILE_PCRE16 */
1985    
1986    #endif /* COMPILE_PCRE8 */
1987  }  }
1988    
1989  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
1990  {  {
1991    /* Checks whether a partial matching is occured. Does not modify registers. */
1992  DEFINE_COMPILER;  DEFINE_COMPILER;
1993  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump = NULL;
1994    
1995    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1996    
1997    if (common->mode == JIT_COMPILE)
1998      return;
1999    
2000    if (!force)
2001      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2002    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2003      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2004    
2005    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2006      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2007    else
2008      {
2009      if (common->partialmatchlabel != NULL)
2010        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2011      else
2012        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2013      }
2014    
2015    if (jump != NULL)
2016      JUMPHERE(jump);
2017    }
2018    
2019    static struct sljit_jump *check_str_end(compiler_common *common)
2020    {
2021    /* Does not affect registers. Usually used in a tight spot. */
2022    DEFINE_COMPILER;
2023    struct sljit_jump *jump;
2024    struct sljit_jump *nohit;
2025    struct sljit_jump *return_value;
2026    
2027    if (common->mode == JIT_COMPILE)
2028      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2029    
2030    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2031    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2032      {
2033      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2034      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2035      JUMPHERE(nohit);
2036      return_value = JUMP(SLJIT_JUMP);
2037      }
2038    else
2039      {
2040      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2041      if (common->partialmatchlabel != NULL)
2042        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2043      else
2044        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2045      }
2046    JUMPHERE(jump);
2047    return return_value;
2048    }
2049    
2050    static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2051    {
2052    DEFINE_COMPILER;
2053    struct sljit_jump *jump;
2054    
2055    if (common->mode == JIT_COMPILE)
2056      {
2057      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2058      return;
2059      }
2060    
2061    /* Partial matching mode. */
2062    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2063    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2064    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2065      {
2066      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2067      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2068      }
2069    else
2070      {
2071      if (common->partialmatchlabel != NULL)
2072        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2073      else
2074        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2075      }
2076    JUMPHERE(jump);
2077  }  }
2078    
2079  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1328  static void read_char(compiler_common *c Line 2081  static void read_char(compiler_common *c
2081  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2082  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2083  DEFINE_COMPILER;  DEFINE_COMPILER;
2084  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2085  struct sljit_jump *jump;  struct sljit_jump *jump;
2086  #endif  #endif
2087    
2088  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2089  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2090  if (common->utf8)  if (common->utf)
2091    {    {
2092    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
2093    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2094    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2095    #ifdef COMPILE_PCRE16
2096      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2097    #endif
2098    #endif /* COMPILE_PCRE8 */
2099      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2100    JUMPHERE(jump);    JUMPHERE(jump);
2101    }    }
2102  #endif  #endif
2103  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));
2104  }  }
2105    
2106  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1350  static void peek_char(compiler_common *c Line 2108  static void peek_char(compiler_common *c
2108  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2109  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2110  DEFINE_COMPILER;  DEFINE_COMPILER;
2111  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2112  struct sljit_jump *jump;  struct sljit_jump *jump;
2113  #endif  #endif
2114    
2115  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2116  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2117  if (common->utf8)  if (common->utf)
2118    {    {
2119    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
2120    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2121    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2122    #ifdef COMPILE_PCRE16
2123      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2124    #endif
2125    #endif /* COMPILE_PCRE8 */
2126      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2127    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2128    JUMPHERE(jump);    JUMPHERE(jump);
2129    }    }
# Line 1371  static void read_char8_type(compiler_com Line 2134  static void read_char8_type(compiler_com
2134  {  {
2135  /* 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. */
2136  DEFINE_COMPILER;  DEFINE_COMPILER;
2137  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2138  struct sljit_jump *jump;  struct sljit_jump *jump;
2139  #endif  #endif
2140    
2141  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2142  if (common->utf8)  if (common->utf)
2143    {    {
2144    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2145    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));
2146    #ifdef COMPILE_PCRE8
2147    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2148    it is a clever early read in most cases. */    it is needed in most cases. */
2149    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2150    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2151    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  
2152    JUMPHERE(jump);    JUMPHERE(jump);
2153    #else
2154    #ifdef COMPILE_PCRE16
2155      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2156      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2157      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2158      JUMPHERE(jump);
2159      /* Skip low surrogate if necessary. */
2160      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2161      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2162      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2163      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2164      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2165    #endif
2166    #endif /* COMPILE_PCRE8 */
2167    return;    return;
2168    }    }
2169  #endif  #endif
2170  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2171  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));
2172  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
2173    /* The ctypes array contains only 256 values. */
2174    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2175    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2176    #endif
2177    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2178    #ifdef COMPILE_PCRE16
2179    JUMPHERE(jump);
2180    #endif
2181  }  }
2182    
2183  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2184  {  {
2185  /* 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. */
2186  DEFINE_COMPILER;  DEFINE_COMPILER;
2187  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2188  struct sljit_label *label;  struct sljit_label *label;
2189    
2190  if (common->utf8)  if (common->utf)
2191    {    {
2192    label = LABEL();    label = LABEL();
2193    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2194    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));
2195    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2196    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2197    return;    return;
2198    }    }
2199  #endif  #endif
2200  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2201    if (common->utf)
2202      {
2203      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2204      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2205      /* Skip low surrogate if necessary. */
2206      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2207      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2208      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2209      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2210      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2211      return;
2212      }
2213    #endif
2214    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2215  }  }
2216    
2217  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)
2218  {  {
2219  /* 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. */
2220  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1423  DEFINE_COMPILER; Line 2222  DEFINE_COMPILER;
2222  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2223    {    {
2224    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2225    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));
2226    }    }
2227  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2228    {    {
# Line 1431  else if (nltype == NLTYPE_ANYCRLF) Line 2230  else if (nltype == NLTYPE_ANYCRLF)
2230    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2231    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);
2232    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2233    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));
2234    }    }
2235  else  else
2236    {    {
2237    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2238    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));
2239    }    }
2240  }  }
2241    
2242  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2243  static void do_utf8readchar(compiler_common *common)  
2244    #ifdef COMPILE_PCRE8
2245    static void do_utfreadchar(compiler_common *common)
2246  {  {
2247  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2248  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. */
2249  DEFINE_COMPILER;  DEFINE_COMPILER;
2250  struct sljit_jump *jump;  struct sljit_jump *jump;
2251    
2252  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2253  /* Searching for the first zero. */  /* Searching for the first zero. */
2254  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);
2255  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2256  /* 2 byte sequence */  /* Two byte sequence. */
2257  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2258  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));
2259  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2260  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2261  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2262  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2263  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2264  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2265  JUMPHERE(jump);  JUMPHERE(jump);
2266    
2267  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);
2268  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2269  /* 3 byte sequence */  /* Three byte sequence. */
2270  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2271  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2272  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2273  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2274  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2275  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2276  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2277  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));
2278  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2279  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2280  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2281  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2282  JUMPHERE(jump);  JUMPHERE(jump);
2283    
2284  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2285  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);  
2286  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2287  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2288  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2289  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2290  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2291  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2292  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2293  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2294  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2295  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2296  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
2297  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2298  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2299  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  
2300  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2301  }  }
2302    
2303  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2304  {  {
2305  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2306  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2307  DEFINE_COMPILER;  DEFINE_COMPILER;
2308  struct sljit_jump *jump;  struct sljit_jump *jump;
2309  struct sljit_jump *compare;  struct sljit_jump *compare;
2310    
2311  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2312    
2313  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);
2314  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2315  /* 2 byte sequence */  /* Two byte sequence. */
2316  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2317  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));
2318  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2319  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2320  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1553  sljit_emit_fast_return(compiler, RETURN_ Line 2329  sljit_emit_fast_return(compiler, RETURN_
2329  JUMPHERE(jump);  JUMPHERE(jump);
2330    
2331  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2332  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);  
2333  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2334  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2335  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2336  }  }
2337    
2338  #endif  #else /* COMPILE_PCRE8 */
2339    
2340    #ifdef COMPILE_PCRE16
2341    static void do_utfreadchar(compiler_common *common)
2342    {
2343    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2344    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2345    DEFINE_COMPILER;
2346    struct sljit_jump *jump;
2347    
2348    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2349    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2350    /* Do nothing, only return. */
2351    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2352    
2353    JUMPHERE(jump);
2354    /* Combine two 16 bit characters. */
2355    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2356    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2357    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2358    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2359    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2360    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2361    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2362    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2363    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2364    }
2365    #endif /* COMPILE_PCRE16 */
2366    
2367    #endif /* COMPILE_PCRE8 */
2368    
2369    #endif /* SUPPORT_UTF */
2370    
2371  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2372    
# Line 1576  DEFINE_COMPILER; Line 2382  DEFINE_COMPILER;
2382    
2383  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2384    
2385  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2386  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2387  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));
2388  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2389  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2390  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2391  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
2392  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2393  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));
2394  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2395  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2396  }  }
# Line 1598  struct sljit_label *newlinelabel = NULL; Line 2404  struct sljit_label *newlinelabel = NULL;
2404  struct sljit_jump *start;  struct sljit_jump *start;
2405  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2406  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2407    #ifdef SUPPORT_UTF
2408    struct sljit_jump *singlechar;
2409    #endif
2410  jump_list *newline = NULL;  jump_list *newline = NULL;
2411  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
2412  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
2413    
2414  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2415      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1609  if (!(hascrorlf || firstline) && (common Line 2418  if (!(hascrorlf || firstline) && (common
2418  if (firstline)  if (firstline)
2419    {    {
2420    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2421    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2422    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2423      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
2424    
2425    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2426      {      {
2427      mainloop = LABEL();      mainloop = LABEL();
2428      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));
2429      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2430      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2431      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2432      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);
2433      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);
2434      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2435      }      }
2436    else    else
2437      {      {
2438      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2439      mainloop = LABEL();      mainloop = LABEL();
2440      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2441      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);
2442      read_char(common);      read_char(common);
2443      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2444      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2445      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);
2446      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2447      }      }
2448    
2449    JUMPHERE(end);    JUMPHERE(end);
2450    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
2451    }    }
2452    
2453  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1645  start = JUMP(SLJIT_JUMP); Line 2455  start = JUMP(SLJIT_JUMP);
2455  if (newlinecheck)  if (newlinecheck)
2456    {    {
2457    newlinelabel = LABEL();    newlinelabel = LABEL();
2458    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));
2459    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2460    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2461    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);
2462    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2463    #ifdef COMPILE_PCRE16
2464      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2465    #endif
2466    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2467    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2468    }    }
# Line 1657  if (newlinecheck) Line 2470  if (newlinecheck)
2470  mainloop = LABEL();  mainloop = LABEL();
2471    
2472  /* 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. */
2473  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2474  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2475  #endif  #endif
2476  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2477    
2478  if (readbyte)  if (readuchar)
2479    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2480    
2481  if (newlinecheck)  if (newlinecheck)
2482    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);
2483    
2484  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2485  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2486    if (common->utf)
2487    {    {
2488    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);
2489      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2490    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2491      JUMPHERE(singlechar);
2492      }
2493    #endif
2494    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2495    if (common->utf)
2496      {
2497      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2498      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2499      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2500      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2501      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2502      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2503      JUMPHERE(singlechar);
2504    }    }
 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);  
2505  #endif  #endif
2506  JUMPHERE(start);  JUMPHERE(start);
2507    
# Line 1690  if (newlinecheck) Line 2514  if (newlinecheck)
2514  return mainloop;  return mainloop;
2515  }  }
2516    
2517  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2518    {
2519    DEFINE_COMPILER;
2520    struct sljit_label *start;
2521    struct sljit_jump *quit;
2522    struct sljit_jump *found;
2523    pcre_int32 chars[4];
2524    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2525    int location = 0;
2526    pcre_int32 len, c, bit, caseless;
2527    BOOL must_end;
2528    
2529    #ifdef COMPILE_PCRE8
2530    union {
2531        sljit_uh ascombined;
2532        sljit_ub asuchars[2];
2533    } pair;
2534    #else
2535    union {
2536        sljit_ui ascombined;
2537        sljit_uh asuchars[2];
2538    } pair;
2539    #endif
2540    
2541    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2542      return FALSE;
2543    
2544    while (TRUE)
2545      {
2546      caseless = 0;
2547      must_end = TRUE;
2548      switch(*cc)
2549        {
2550        case OP_CHAR:
2551        must_end = FALSE;
2552        cc++;
2553        break;
2554    
2555        case OP_CHARI:
2556        caseless = 1;
2557        must_end = FALSE;
2558        cc++;
2559        break;
2560    
2561        case OP_SOD:
2562        case OP_SOM:
2563        case OP_SET_SOM:
2564        case OP_NOT_WORD_BOUNDARY:
2565        case OP_WORD_BOUNDARY:
2566        case OP_EODN:
2567        case OP_EOD:
2568        case OP_CIRC:
2569        case OP_CIRCM:
2570        case OP_DOLL:
2571        case OP_DOLLM:
2572        /* Zero width assertions. */
2573        cc++;
2574        continue;
2575    
2576        case OP_PLUS:
2577        case OP_MINPLUS:
2578        case OP_POSPLUS:
2579        cc++;
2580        break;
2581    
2582        case OP_EXACT:
2583        cc += 1 + IMM2_SIZE;
2584        break;
2585    
2586        case OP_PLUSI:
2587        case OP_MINPLUSI:
2588        case OP_POSPLUSI:
2589        caseless = 1;
2590        cc++;
2591        break;
2592    
2593        case OP_EXACTI:
2594        caseless = 1;
2595        cc += 1 + IMM2_SIZE;
2596        break;
2597    
2598        default:
2599        return FALSE;
2600        }
2601    
2602      len = 1;
2603    #ifdef SUPPORT_UTF
2604      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2605    #endif
2606    
2607      if (caseless && char_has_othercase(common, cc))
2608        {
2609        caseless = char_get_othercase_bit(common, cc);
2610        if (caseless == 0)
2611          return FALSE;
2612    #ifdef COMPILE_PCRE8
2613        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2614    #else
2615        if ((caseless & 0x100) != 0)
2616          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2617        else
2618          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2619    #endif
2620        }
2621      else
2622        caseless = 0;
2623    
2624      while (len > 0 && location < 2 * 2)
2625        {
2626        c = *cc;
2627        bit = 0;
2628        if (len == (caseless & 0xff))
2629          {
2630          bit = caseless >> 8;
2631          c |= bit;
2632          }
2633    
2634        chars[location] = c;
2635        chars[location + 1] = bit;
2636    
2637        len--;
2638        location += 2;
2639        cc++;
2640        }
2641    
2642      if (location == 2 * 2)
2643        break;
2644      else if (must_end)
2645        return FALSE;
2646      }
2647    
2648    if (firstline)
2649      {
2650      SLJIT_ASSERT(common->first_line_end != 0);
2651      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2652      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2653      }
2654    else
2655      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2656    
2657    start = LABEL();
2658    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2659    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2660    #ifdef COMPILE_PCRE8
2661    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2662    #else /* COMPILE_PCRE8 */
2663    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2664    #endif
2665    
2666    #else /* SLJIT_UNALIGNED */
2667    
2668    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2669    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2670    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2671    #else /* SLJIT_BIG_ENDIAN */
2672    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2673    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2674    #endif /* SLJIT_BIG_ENDIAN */
2675    
2676    #ifdef COMPILE_PCRE8
2677    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2678    #else /* COMPILE_PCRE8 */
2679    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2680    #endif
2681    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2682    
2683    #endif
2684    
2685    if (chars[1] != 0 || chars[3] != 0)
2686      {
2687      pair.asuchars[0] = chars[1];
2688      pair.asuchars[1] = chars[3];
2689      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2690      }
2691    
2692    pair.asuchars[0] = chars[0];
2693    pair.asuchars[1] = chars[2];
2694    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2695    
2696    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2697    JUMPTO(SLJIT_JUMP, start);
2698    JUMPHERE(found);
2699    JUMPHERE(quit);
2700    
2701    if (firstline)
2702      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2703    else
2704      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2705    return TRUE;
2706    }
2707    
2708    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2709  {  {
2710  DEFINE_COMPILER;  DEFINE_COMPILER;
2711  struct sljit_label *start;  struct sljit_label *start;
2712  struct sljit_jump *leave;  struct sljit_jump *quit;
2713  struct sljit_jump *found;  struct sljit_jump *found;
2714  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2715    
2716  if (firstline)  if (firstline)
2717    {    {
2718    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2719    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2720      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2721    }    }
2722    
2723  start = LABEL();  start = LABEL();
2724  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2725  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2726    
2727  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2728    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2729      {
2730      oc = TABLE_GET(first_char, common->fcc, first_char);
2731    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2732      if (first_char > 127 && common->utf)
2733        oc = UCD_OTHERCASE(first_char);
2734    #endif
2735      }
2736    if (first_char == oc)
2737      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2738  else  else
2739    {    {
2740    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2741    if (ispowerof2(bit))    if (ispowerof2(bit))
2742      {      {
2743      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2744      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2745      }      }
2746    else    else
2747      {      {
2748      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);
2749      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2750      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);
2751      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2752      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
2753      }      }
2754    }    }
2755    
2756  #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  
2757  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2758  JUMPHERE(found);  JUMPHERE(found);
2759  JUMPHERE(leave);  JUMPHERE(quit);
2760    
2761  if (firstline)  if (firstline)
2762    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2763  }  }
2764    
2765  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 1755  DEFINE_COMPILER; Line 2768  DEFINE_COMPILER;
2768  struct sljit_label *loop;  struct sljit_label *loop;
2769  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2770  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2771  struct sljit_jump *leave;  struct sljit_jump *quit;
2772  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2773  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2774  jump_list *newline = NULL;  jump_list *newline = NULL;
2775    
2776  if (firstline)  if (firstline)
2777    {    {
2778    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2779    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2780      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2781    }    }
2782    
2783  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1774  if (common->nltype == NLTYPE_FIXED && co Line 2788  if (common->nltype == NLTYPE_FIXED && co
2788    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));
2789    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2790    
2791    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2792    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);
2793    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2794    #ifdef COMPILE_PCRE16
2795      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2796    #endif
2797    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2798    
2799    loop = LABEL();    loop = LABEL();
2800    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));
2801    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2802    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2803    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2804    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);
2805    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);
2806    
2807    JUMPHERE(leave);    JUMPHERE(quit);
2808    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2809    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2810    
# Line 1811  set_jumps(newline, loop); Line 2828  set_jumps(newline, loop);
2828    
2829  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2830    {    {
2831    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2832    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2833    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2834    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2835    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);
2836    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2837    #ifdef COMPILE_PCRE16
2838      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2839    #endif
2840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2841    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2842    JUMPHERE(leave);    JUMPHERE(quit);
2843    }    }
2844  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2845  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2846    
2847  if (firstline)  if (firstline)
2848    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2849  }  }
2850    
2851  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)
2852  {  {
2853  DEFINE_COMPILER;  DEFINE_COMPILER;
2854  struct sljit_label *start;  struct sljit_label *start;
2855  struct sljit_jump *leave;  struct sljit_jump *quit;
2856  struct sljit_jump *found;  struct sljit_jump *found;
2857    #ifndef COMPILE_PCRE8
2858    struct sljit_jump *jump;
2859    #endif
2860    
2861  if (firstline)  if (firstline)
2862    {    {
2863    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2864    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2865      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2866    }    }
2867    
2868  start = LABEL();  start = LABEL();
2869  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2870  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2871  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2872  if (common->utf8)  if (common->utf)
2873    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2874    #endif
2875    #ifndef COMPILE_PCRE8
2876    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2877    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2878    JUMPHERE(jump);
2879  #endif  #endif
2880  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2881  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1855  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2884  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2884  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);
2885  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2886    
2887  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2888  if (common->utf8)  if (common->utf)
2889    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2890  else  #endif
2891    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));
2892  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2893  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2894      {
2895      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2896      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2897      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2898      }
2899    #endif
2900    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2901    if (common->utf)
2902      {
2903      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2904      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2905      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2906      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2907      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2908      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2909      }
2910  #endif  #endif
2911  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2912  JUMPHERE(found);  JUMPHERE(found);
2913  JUMPHERE(leave);  JUMPHERE(quit);
2914    
2915  if (firstline)  if (firstline)
2916    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2917  }  }
2918    
2919  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)
2920  {  {
2921  DEFINE_COMPILER;  DEFINE_COMPILER;
2922  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1880  struct sljit_jump *alreadyfound; Line 2925  struct sljit_jump *alreadyfound;
2925  struct sljit_jump *found;  struct sljit_jump *found;
2926  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2927  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2928  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2929    
2930  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2931    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2932  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);
2933  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2934  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2935    
2936  if (has_firstbyte)  if (has_firstchar)
2937    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2938  else  else
2939    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2940    
2941  loop = LABEL();  loop = LABEL();
2942  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2943    
2944  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2945  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2946    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2947      {
2948      oc = TABLE_GET(req_char, common->fcc, req_char);
2949    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2950      if (req_char > 127 && common->utf)
2951        oc = UCD_OTHERCASE(req_char);
2952    #endif
2953      }
2954    if (req_char == oc)
2955      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2956  else  else
2957    {    {
2958    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2959    if (ispowerof2(bit))    if (ispowerof2(bit))
2960      {      {
2961      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2962      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2963      }      }
2964    else    else
2965      {      {
2966      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2967      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2968      }      }
2969    }    }
2970  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2971  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2972    
2973  JUMPHERE(found);  JUMPHERE(found);
2974  if (foundoc)  if (foundoc)
2975    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2976  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);
2977  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2978  JUMPHERE(toolong);  JUMPHERE(toolong);
2979  return notfound;  return notfound;
# Line 1932  DEFINE_COMPILER; Line 2985  DEFINE_COMPILER;
2985  struct sljit_jump *jump;  struct sljit_jump *jump;
2986  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2987    
2988  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2989  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2990    GET_LOCAL_BASE(TMP3, 0, 0);
2991    
2992  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2993  mainloop = LABEL();  mainloop = LABEL();
2994  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2995  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);
2996  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2997  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));
2998  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));
2999  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 1959  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 3013  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
3013  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3014    
3015  JUMPHERE(jump);  JUMPHERE(jump);
3016    if (common->mark_ptr != 0)
3017      {
3018      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3019      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3020      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3021      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3022      JUMPTO(SLJIT_JUMP, mainloop);
3023    
3024      JUMPHERE(jump);
3025      }
3026    
3027  /* Unknown command. */  /* Unknown command. */
3028  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));
3029  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 1967  JUMPTO(SLJIT_JUMP, mainloop); Line 3032  JUMPTO(SLJIT_JUMP, mainloop);
3032  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3033  {  {
3034  DEFINE_COMPILER;  DEFINE_COMPILER;
3035  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3036  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3037  struct sljit_jump *jump;  struct sljit_jump *jump;
3038  #endif  #endif
3039    
3040  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3041    
3042  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);
3043  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3044  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3045  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));
3046  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3047  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3048  skip_char_back(common);  skip_char_back(common);
3049    check_start_used_ptr(common);
3050  read_char(common);  read_char(common);
3051    
3052  /* Testing char type. */  /* Testing char type. */
3053  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3054  if (common->useucp)  if (common->use_ucp)
3055    {    {
3056    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3057    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2002  if (common->useucp) Line 3068  if (common->useucp)
3068  else  else
3069  #endif  #endif
3070    {    {
3071  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3072      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3073    #elif defined SUPPORT_UTF
3074    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3075    jump = NULL;    jump = NULL;
3076    if (common->utf8)    if (common->utf)
3077      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3078  #endif  #endif /* COMPILE_PCRE8 */
3079    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3080    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3081    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3082    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3083  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3084      JUMPHERE(jump);
3085    #elif defined SUPPORT_UTF
3086    if (jump != NULL)    if (jump != NULL)
3087      JUMPHERE(jump);      JUMPHERE(jump);
3088  #endif  #endif /* COMPILE_PCRE8 */
3089    }    }
3090  JUMPHERE(beginend);  JUMPHERE(skipread);
3091    
3092  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3093  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3094  peek_char(common);  peek_char(common);
3095    
3096  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3097  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3098  if (common->useucp)  if (common->use_ucp)
3099    {    {
3100    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3101    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2041  if (common->useucp) Line 3111  if (common->useucp)
3111  else  else
3112  #endif  #endif
3113    {    {
3114  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3115      /* TMP2 may be destroyed by peek_char. */
3116      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3117      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3118    #elif defined SUPPORT_UTF
3119    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3120    jump = NULL;    jump = NULL;
3121    if (common->utf8)    if (common->utf)
3122      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3123  #endif  #endif
3124    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3125    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3126    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3127  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3128      JUMPHERE(jump);
3129    #elif defined SUPPORT_UTF
3130    if (jump != NULL)    if (jump != NULL)
3131      JUMPHERE(jump);      JUMPHERE(jump);
3132  #endif  #endif /* COMPILE_PCRE8 */
3133    }    }
3134  JUMPHERE(beginend);  JUMPHERE(skipread);
3135    
3136  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);
3137  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3138  }  }
3139    
3140    /*
3141      range format:
3142    
3143      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3144      ranges[1] = first bit (0 or 1)
3145      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3146    */
3147    
3148    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3149    {
3150    DEFINE_COMPILER;
3151    struct sljit_jump *jump;
3152    
3153    if (ranges[0] < 0)
3154      return FALSE;
3155    
3156    switch(ranges[0])
3157      {
3158      case 1:
3159      if (readch)
3160        read_char(common);
3161      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3162      return TRUE;
3163    
3164      case 2:
3165      if (readch)
3166        read_char(common);
3167      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3168      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3169      return TRUE;
3170    
3171      case 4:
3172      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3173        {
3174        if (readch)
3175          read_char(common);
3176        if (ranges[1] != 0)
3177          {
3178          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3179          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3180          }
3181        else
3182          {
3183          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3184          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3185          JUMPHERE(jump);
3186          }
3187        return TRUE;
3188        }
3189      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))
3190        {
3191        if (readch)
3192          read_char(common);
3193        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3194        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3195        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3196        return TRUE;
3197        }
3198      return FALSE;
3199    
3200      default:
3201      return FALSE;
3202      }
3203    }
3204    
3205    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3206    {
3207    int i, bit, length;
3208    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3209    
3210    bit = ctypes[0] & flag;
3211    ranges[0] = -1;
3212    ranges[1] = bit != 0 ? 1 : 0;
3213    length = 0;
3214    
3215    for (i = 1; i < 256; i++)
3216      if ((ctypes[i] & flag) != bit)
3217        {
3218        if (length >= MAX_RANGE_SIZE)
3219          return;
3220        ranges[2 + length] = i;
3221        length++;
3222        bit ^= flag;
3223        }
3224    
3225    if (bit != 0)
3226      {
3227      if (length >= MAX_RANGE_SIZE)
3228        return;
3229      ranges[2 + length] = 256;
3230      length++;
3231      }
3232    ranges[0] = length;
3233    }
3234    
3235    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3236    {
3237    int ranges[2 + MAX_RANGE_SIZE];
3238    pcre_uint8 bit, cbit, all;
3239    int i, byte, length = 0;
3240    
3241    bit = bits[0] & 0x1;
3242    ranges[1] = bit;
3243    /* Can be 0 or 255. */
3244    all = -bit;
3245    
3246    for (i = 0; i < 256; )
3247      {
3248      byte = i >> 3;
3249      if ((i & 0x7) == 0 && bits[byte] == all)
3250        i += 8;
3251      else
3252        {
3253        cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3254        if (cbit != bit)
3255          {
3256          if (length >= MAX_RANGE_SIZE)
3257            return FALSE;
3258          ranges[2 + length] = i;
3259          length++;
3260          bit = cbit;
3261          all = -cbit;
3262          }
3263        i++;
3264        }
3265      }
3266    
3267    if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3268      {
3269      if (length >= MAX_RANGE_SIZE)
3270        return FALSE;
3271      ranges[2 + length] = 256;
3272      length++;
3273      }
3274    ranges[0] = length;
3275    
3276    return check_ranges(common, ranges, backtracks, FALSE);
3277    }
3278    
3279  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
3280  {  {
3281  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3282  DEFINE_COMPILER;  DEFINE_COMPILER;
3283    
3284  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3285    
3286  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3287  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);
3288  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3289  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);
3290  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3291  if (common->utf8)  #ifdef COMPILE_PCRE8
3292    if (common->utf)
3293    {    {
3294    #endif
3295    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3296    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3297    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);
3298    #ifdef COMPILE_PCRE8
3299    }    }
3300  #endif  #endif
3301    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3302  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3303  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3304  }  }
# Line 2089  static void check_hspace(compiler_common Line 3308  static void check_hspace(compiler_common
3308  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3309  DEFINE_COMPILER;  DEFINE_COMPILER;
3310    
3311  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3312    
3313  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);
3314  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3315  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);
3316  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3317  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);
3318  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
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_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);
3325    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2112  if (common->utf8) Line 3333  if (common->utf8)
3333    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);
3334    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3335    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);
3336    #ifdef COMPILE_PCRE8
3337    }    }
3338  #endif  #endif
3339    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3340  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3341    
3342  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2124  static void check_vspace(compiler_common Line 3347  static void check_vspace(compiler_common
3347  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3348  DEFINE_COMPILER;  DEFINE_COMPILER;
3349    
3350  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3351    
3352  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3353  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);
3354  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3355  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);
3356  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3357  if (common->utf8)  #ifdef COMPILE_PCRE8
3358    if (common->utf)
3359    {    {
3360    #endif
3361    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3362    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3363    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);
3364    #ifdef COMPILE_PCRE8
3365    }    }
3366  #endif  #endif
3367    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
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 2152  DEFINE_COMPILER; Line 3379  DEFINE_COMPILER;
3379  struct sljit_jump *jump;  struct sljit_jump *jump;
3380  struct sljit_label *label;  struct sljit_label *label;
3381    
3382  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3383  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3384  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3385  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3386  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3387  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));
3388    
3389  label = LABEL();  label = LABEL();
3390  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3391  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3392  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3393  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));
3394  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3395    
3396  JUMPHERE(jump);  JUMPHERE(jump);
3397  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));
3398  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3399  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3400  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2181  DEFINE_COMPILER; Line 3408  DEFINE_COMPILER;
3408  struct sljit_jump *jump;  struct sljit_jump *jump;
3409  struct sljit_label *label;  struct sljit_label *label;
3410    
3411  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3412  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3413    
3414  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3415  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3416  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3417  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3418  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3419  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));
3420    
3421  label = LABEL();  label = LABEL();
3422  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3423  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3424    #ifndef COMPILE_PCRE8
3425    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3426    #endif
3427  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3428    #ifndef COMPILE_PCRE8
3429    JUMPHERE(jump);
3430    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3431    #endif
3432  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3433    #ifndef COMPILE_PCRE8
3434    JUMPHERE(jump);
3435    #endif
3436  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3437  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));
3438  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3439    
3440  JUMPHERE(jump);  JUMPHERE(jump);
3441  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));
3442  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3443  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3444  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2212  sljit_emit_fast_return(compiler, RETURN_ Line 3449  sljit_emit_fast_return(compiler, RETURN_
3449  #undef CHAR1  #undef CHAR1
3450  #undef CHAR2  #undef CHAR2
3451    
3452  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3453    
3454  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)
3455  {  {
3456  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3457  int c1, c2;  int c1, c2;
3458  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3459  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3460    
3461  while (src1 < end1)  while (src1 < end1)
3462    {    {
3463    if (src2 >= end2)    if (src2 >= end2)
3464      return 0;      return (pcre_uchar*)1;
3465    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3466    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3467    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
3468    }    }
3469  return src2;  return src2;
3470  }  }
3471    
3472  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3473    
3474  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,
3475      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3476  {  {
3477  DEFINE_COMPILER;  DEFINE_COMPILER;
3478  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3479  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3480  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3481  int utf8length;  int utflength;
3482  #endif  #endif
3483    
3484  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2251  if (caseless && char_has_othercase(commo Line 3486  if (caseless && char_has_othercase(commo
3486    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3487    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3488    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3489    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
3490      othercasechar = cc + (othercasebit >> 8);
3491    othercasebit &= 0xff;    othercasebit &= 0xff;
3492    #else
3493    #ifdef COMPILE_PCRE16
3494      othercasechar = cc + (othercasebit >> 9);
3495      if ((othercasebit & 0x100) != 0)
3496        othercasebit = (othercasebit & 0xff) << 8;
3497      else
3498        othercasebit &= 0xff;
3499    #endif
3500    #endif
3501    }    }
3502    
3503  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3504    {    {
3505    #ifdef COMPILE_PCRE8
3506  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3507    if (context->length >= 4)    if (context->length >= 4)
3508      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3509    else if (context->length >= 2)    else if (context->length >= 2)
3510      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3511    else    else
3512  #endif  #endif
3513      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3514    #else
3515    #ifdef COMPILE_PCRE16
3516    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3517      if (context->length >= 4)
3518        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3519      else
3520    #endif
3521        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3522    #endif
3523    #endif /* COMPILE_PCRE8 */
3524    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3525    }    }
3526    
3527  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3528  utf8length = 1;  utflength = 1;
3529  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3530    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3531    
3532  do  do
3533    {    {
3534  #endif  #endif
3535    
3536    context->length--;    context->length -= IN_UCHARS(1);
3537  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3538    
3539    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3540    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3541      {      {
3542      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3543      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3544      }      }
3545    else    else
3546      {      {
3547      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3548      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3549      }      }
3550    context->byteptr++;    context->ucharptr++;
3551    
3552    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
3553      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3554    #else
3555      if (context->ucharptr >= 2 || context->length == 0)
3556    #endif
3557      {      {
3558      if (context->length >= 4)      if (context->length >= 4)
3559        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);
3560    #ifdef COMPILE_PCRE8
3561      else if (context->length >= 2)      else if (context->length >= 2)
3562        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);
3563      else if (context->length >= 1)      else if (context->length >= 1)
3564        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);
3565    #else
3566        else if (context->length >= 2)
3567          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3568    #endif
3569      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3570    
3571      switch(context->byteptr)      switch(context->ucharptr)
3572        {        {
3573        case 4:        case 4 / sizeof(pcre_uchar):
3574        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3575          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);
3576        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));
3577        break;        break;
3578    
3579        case 2:        case 2 / sizeof(pcre_uchar):
3580        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3581          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asshort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
3582        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asshort | context->oc.asshort));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
3583        break;        break;
3584    
3585    #ifdef COMPILE_PCRE8
3586        case 1:        case 1:
3587        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3588          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);
3589        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));
3590        break;        break;
3591    #endif
3592    
3593        default:        default:
3594        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3595        break;        break;
3596        }        }
3597      context->byteptr = 0;      context->ucharptr = 0;
3598      }      }
3599    
3600  #else  #else
3601    
3602    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
3603    #ifdef COMPILE_PCRE8
3604    if (context->length > 0)    if (context->length > 0)
3605      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);
3606    #else
3607      if (context->length > 0)
3608        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3609    #endif
3610    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3611    
3612    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3613      {      {
3614      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3615      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));
3616      }      }
3617    else    else
3618      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));
3619    
3620  #endif  #endif
3621    
3622    cc++;    cc++;
3623  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3624    utf8length--;    utflength--;
3625    }    }
3626  while (utf8length > 0);  while (utflength > 0);
3627  #endif  #endif
3628    
3629  return cc;  return cc;
3630  }  }
3631    
3632  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3633    
3634  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
3635    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2379  return cc; Line 3651  return cc;
3651      } \      } \
3652    charoffset = (value);    charoffset = (value);
3653    
3654  static void compile_xclass_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks)  static void compile_xclass_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3655  {  {
3656  DEFINE_COMPILER;  DEFINE_COMPILER;
3657  jump_list *found = NULL;  jump_list *found = NULL;
3658  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3659  unsigned int c;  unsigned int c;
3660  int compares;  int compares;
3661  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3662  uschar *ccbegin;  pcre_uchar *ccbegin;
3663  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3664  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3665  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2397  unsigned int typeoffset; Line 3669  unsigned int typeoffset;
3669  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3670  unsigned int charoffset;  unsigned int charoffset;
3671    
3672  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF must be defined, we are
3673  check_input_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3674    detect_partial_match(common, backtracks);
3675  read_char(common);  read_char(common);
3676    
3677  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
3678    {    {
3679    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3680    if (common->utf8)  #ifndef COMPILE_PCRE8
3681      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3682    #elif defined SUPPORT_UTF
3683      if (common->utf)
3684      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3685    #endif
3686    
3687    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3688    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3689    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3690    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3691    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);
3692    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3693        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3694        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3695        }
3696    
3697    if (common->utf8)  #ifndef COMPILE_PCRE8
3698      JUMPHERE(jump);
3699    #elif defined SUPPORT_UTF
3700      if (common->utf)
3701      JUMPHERE(jump);      JUMPHERE(jump);
3702    #endif
3703    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3704  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3705    charsaved = TRUE;    charsaved = TRUE;
3706  #endif  #endif
3707    cc += 32;    cc += 32 / sizeof(pcre_uchar);
3708    }    }
3709    
3710  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2432  while (*cc != XCL_END) Line 3716  while (*cc != XCL_END)
3716    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3717      {      {
3718      cc += 2;      cc += 2;
3719  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3720      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]);
3721  #endif  #endif
3722  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3723      needschar = TRUE;      needschar = TRUE;
# Line 2442  while (*cc != XCL_END) Line 3726  while (*cc != XCL_END)
3726    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3727      {      {
3728      cc += 2;      cc += 2;
3729  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3730      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]);
3731  #endif  #endif
3732      cc++;      cc++;
3733  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3734      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]);
3735  #endif  #endif
3736  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3737      needschar = TRUE;      needschar = TRUE;
# Line 2517  if (needstype || needsscript) Line 3801  if (needstype || needsscript)
3801      {      {
3802      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3803        {        {
3804        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));
3805        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3806        }        }
3807      else      else
3808        {        {
3809        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3810        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));
3811        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3812        }        }
3813      }      }
# Line 2541  typeoffset = 0; Line 3825  typeoffset = 0;
3825  while (*cc != XCL_END)  while (*cc != XCL_END)
3826    {    {
3827    compares--;    compares--;
3828    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3829    jump = NULL;    jump = NULL;
3830    
3831    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3832      {      {
3833      cc ++;      cc ++;
3834  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3835      if (common->utf8)      if (common->utf)
3836        {        {
3837        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3838        }        }
# Line 2578  while (*cc != XCL_END) Line 3862  while (*cc != XCL_END)
3862    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3863      {      {
3864      cc ++;      cc ++;
3865  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3866      if (common->utf8)      if (common->utf)
3867        {        {
3868        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3869        }        }
# Line 2587  while (*cc != XCL_END) Line 3871  while (*cc != XCL_END)
3871  #endif  #endif
3872        c = *cc++;        c = *cc++;
3873      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3874  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3875      if (common->utf8)      if (common->utf)
3876        {        {
3877        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3878        }        }
# Line 2623  while (*cc != XCL_END) Line 3907  while (*cc != XCL_END)
3907      switch(*cc)      switch(*cc)
3908        {        {
3909        case PT_ANY:        case PT_ANY:
3910        if (list != fallbacks)        if (list != backtracks)
3911          {          {
3912          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))          if ((cc[-1] == XCL_NOTPROP && compares > 0) || (cc[-1] == XCL_PROP && compares == 0))
3913            continue;            continue;
# Line 2644  while (*cc != XCL_END) Line 3928  while (*cc != XCL_END)
3928        break;        break;
3929    
3930        case PT_GC:        case PT_GC:
3931        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3932        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3933        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, _pcre_ucp_typerange[(int)cc[1] * 2 + 1] - c);        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
3934        break;        break;
3935    
3936        case PT_PC:        case PT_PC:
# Line 2696  while (*cc != XCL_END) Line 3980  while (*cc != XCL_END)
3980  #endif  #endif
3981    
3982    if (jump != NULL)    if (jump != NULL)
3983      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3984    }    }
3985    
3986  if (found != NULL)  if (found != NULL)
# Line 2708  if (found != NULL) Line 3992  if (found != NULL)
3992    
3993  #endif  #endif
3994    
3995  static uschar *compile_char1_hotpath(compiler_common *common, uschar type, uschar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_trypath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
3996  {  {
3997  DEFINE_COMPILER;  DEFINE_COMPILER;
3998  int length;  int length;
3999  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4000  compare_context context;  compare_context context;
4001  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4002  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4003  struct sljit_label *label;  struct sljit_label *label;
4004  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4005  uschar propdata[5];  pcre_uchar propdata[5];
4006  #endif  #endif
4007  #endif  #endif
4008    
# Line 2727  switch(type) Line 4011  switch(type)
4011    case OP_SOD:    case OP_SOD:
4012    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4013    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));
4014    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4015    return cc;    return cc;
4016    
4017    case OP_SOM:    case OP_SOM:
4018    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4019    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
4020    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, TMP1, 0));
4021    return cc;    return cc;
4022    
4023    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4024    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4025    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4026    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4027    return cc;    return cc;
4028    
4029    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4030    case OP_DIGIT:    case OP_DIGIT:
4031    check_input_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4032    read_char8_type(common);    if (common->digits[0] == -2)
4033    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4034    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4035      /* Flip the starting bit in the negative case. */
4036      if (type == OP_NOT_DIGIT)
4037        common->digits[1] ^= 1;
4038      if (!check_ranges(common, common->digits, backtracks, TRUE))
4039        {
4040        read_char8_type(common);
4041        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4042        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4043        }
4044      if (type == OP_NOT_DIGIT)
4045        common->digits[1] ^= 1;
4046    return cc;    return cc;
4047    
4048    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4049    case OP_WHITESPACE:    case OP_WHITESPACE:
4050    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4051    read_char8_type(common);    read_char8_type(common);
4052    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
4053    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4054    return cc;    return cc;
4055    
4056    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4057    case OP_WORDCHAR:    case OP_WORDCHAR:
4058    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4059    read_char8_type(common);    read_char8_type(common);
4060    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
4061    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4062    return cc;    return cc;
4063    
4064    case OP_ANY:    case OP_ANY:
4065    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4066    read_char(common);    read_char(common);
4067    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4068      {      {
4069      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4070      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4071      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4072      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      else
4073      JUMPHERE(jump[1]);        jump[1] = check_str_end(common);
4074    
4075        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4076        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4077        if (jump[1] != NULL)
4078          JUMPHERE(jump[1]);
4079      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4080      }      }
4081    else    else
4082      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4083    return cc;    return cc;
4084    
4085    case OP_ALLANY:    case OP_ALLANY:
4086    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4087  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4088    if (common->utf8)    if (common->utf)
4089      {      {
4090      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4091      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4092    #ifdef COMPILE_PCRE8
4093        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4094        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
4095        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4096    #else /* COMPILE_PCRE8 */
4097    #ifdef COMPILE_PCRE16
4098        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4099        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4100        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4101        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
4102        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4103      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4104    #endif /* COMPILE_PCRE16 */
4105    #endif /* COMPILE_PCRE8 */
4106        JUMPHERE(jump[0]);
4107      return cc;      return cc;
4108      }      }
4109  #endif  #endif
4110    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));
4111      return cc;
4112    
4113      case OP_ANYBYTE: