/[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 792 by ph10, Wed Dec 7 16:44:48 2011 UTC revision 974 by zherczeg, Sat Jun 2 05:56:58 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) (pcre_malloc)(size)  #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56  #define SLJIT_FREE(ptr) (pcre_free)(ptr)  #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 62  system files. */ Line 62  system files. */
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 82  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 108  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 148  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    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171  } executable_function;  } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 187  typedef struct stub_list { Line 188  typedef struct stub_list {
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 263  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  typedef struct compiler_common {  typedef struct compiler_common {
272    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
273    uschar *start;    pcre_uchar *start;
274    int localsize;  
275      /* Opcode local area direct map. */
276    int *localptrs;    int *localptrs;
   const uschar *fcc;  
   sljit_w lcc;  
277    int cbraptr;    int cbraptr;
278      /* OVector starting point. Must be divisible by 2. */
279      int ovector_start;
280      /* Last known position of the requested byte. */
281      int req_char_ptr;
282      /* Head of the last recursion. */
283      int recursive_head;
284      /* First inspected character for partial matching. */
285      int start_used_ptr;
286      /* Starting pointer for partial soft matches. */
287      int hit_start;
288      /* End pointer of the first line. */
289      int first_line_end;
290      /* Points to the marked string. */
291      int mark_ptr;
292    
293      /* Other  */
294      const pcre_uint8 *fcc;
295      sljit_w lcc;
296      int mode;
297    int nltype;    int nltype;
298    int newline;    int newline;
299    int bsr_nltype;    int bsr_nltype;
300    int endonly;    int endonly;
301      BOOL has_set_som;
302    sljit_w ctypes;    sljit_w ctypes;
303    sljit_uw name_table;    sljit_uw name_table;
304    sljit_w name_count;    sljit_w name_count;
305    sljit_w name_entry_size;    sljit_w name_entry_size;
306    
307      /* Labels and jump lists. */
308      struct sljit_label *partialmatchlabel;
309      struct sljit_label *leavelabel;
310    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
311    stub_list *stubs;    stub_list *stubs;
312    recurse_entry *entries;    recurse_entry *entries;
313    recurse_entry *currententry;    recurse_entry *currententry;
314      jump_list *partialmatch;
315      jump_list *leave;
316    jump_list *accept;    jump_list *accept;
317    jump_list *calllimit;    jump_list *calllimit;
318    jump_list *stackalloc;    jump_list *stackalloc;
# Line 298  typedef struct compiler_common { Line 324  typedef struct compiler_common {
324    jump_list *casefulcmp;    jump_list *casefulcmp;
325    jump_list *caselesscmp;    jump_list *caselesscmp;
326    BOOL jscript_compat;    BOOL jscript_compat;
327  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
328    BOOL utf8;    BOOL utf;
329  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
330    BOOL useucp;    BOOL use_ucp;
331  #endif  #endif
332    jump_list *utf8readchar;    jump_list *utfreadchar;
333    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
334      jump_list *utfreadtype8;
335  #endif  #endif
336    #endif /* SUPPORT_UTF */
337  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
338    jump_list *getucd;    jump_list *getucd;
339  #endif  #endif
# Line 317  typedef struct compare_context { Line 345  typedef struct compare_context {
345    int length;    int length;
346    int sourcereg;    int sourcereg;
347  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
348    int byteptr;    int ucharptr;
349    union {    union {
350      int asint;      sljit_i asint;
351      short asshort;      sljit_uh asushort;
352    #ifdef COMPILE_PCRE8
353      sljit_ub asbyte;      sljit_ub asbyte;
354      sljit_ub asbytes[4];      sljit_ub asuchars[4];
355    #else
356    #ifdef COMPILE_PCRE16
357        sljit_uh asuchars[2];
358    #endif
359    #endif
360    } c;    } c;
361    union {    union {
362      int asint;      sljit_i asint;
363      short asshort;      sljit_uh asushort;
364    #ifdef COMPILE_PCRE8
365      sljit_ub asbyte;      sljit_ub asbyte;
366      sljit_ub asbytes[4];      sljit_ub asuchars[4];
367    #else
368    #ifdef COMPILE_PCRE16
369        sljit_uh asuchars[2];
370    #endif
371    #endif
372    } oc;    } oc;
373  #endif  #endif
374  } compare_context;  } compare_context;
375    
376  enum {  enum {
377    frame_end = 0,    frame_end = 0,
378    frame_setstrbegin = -1    frame_setstrbegin = -1,
379      frame_setmark = -2
380  };  };
381    
382    /* Undefine sljit macros. */
383    #undef CMP
384    
385  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
386  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
387    
388  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
389  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
390  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
391  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
392  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
393  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
394  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
395  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
396  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
397  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
398    
399  /* Locals layout. */  /* Locals layout. */
# Line 359  enum { Line 403  enum {
403  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
404  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
405  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
406  /* Max limit of recursions. */  /* Max limit of recursions. */
407  #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))  
408  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
409  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
410  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
411  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. */
412  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
413  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
414  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
415  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
416    
417    #ifdef COMPILE_PCRE8
418    #define MOV_UCHAR  SLJIT_MOV_UB
419    #define MOVU_UCHAR SLJIT_MOVU_UB
420    #else
421    #ifdef COMPILE_PCRE16
422    #define MOV_UCHAR  SLJIT_MOV_UH
423    #define MOVU_UCHAR SLJIT_MOVU_UH
424    #else
425    #error Unsupported compiling mode
426    #endif
427    #endif
428    
429  /* Shortcuts. */  /* Shortcuts. */
430  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 397  the start pointers when the end of the c Line 447  the start pointers when the end of the c
447    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))
448  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
449    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
450    #define GET_LOCAL_BASE(dst, dstw, offset) \
451      sljit_get_local_base(compiler, (dst), (dstw), (offset))
452    
453  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
454  {  {
455  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));
456  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 415  return cc; Line 467  return cc;
467   init_frame   init_frame
468   get_localsize   get_localsize
469   copy_locals   copy_locals
470   compile_hotpath   compile_trypath
471   compile_fallbackpath   compile_backtrackpath
472  */  */
473    
474  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
475  {  {
476  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
477  switch(*cc)  switch(*cc)
# Line 468  switch(*cc) Line 520  switch(*cc)
520    case OP_BRAZERO:    case OP_BRAZERO:
521    case OP_BRAMINZERO:    case OP_BRAMINZERO:
522    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
523      case OP_COMMIT:
524    case OP_FAIL:    case OP_FAIL:
525    case OP_ACCEPT:    case OP_ACCEPT:
526    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 475  switch(*cc) Line 528  switch(*cc)
528    return cc + 1;    return cc + 1;
529    
530    case OP_ANYBYTE:    case OP_ANYBYTE:
531  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
532    if (common->utf8) return NULL;    if (common->utf) return NULL;
533  #endif  #endif
534    return cc + 1;    return cc + 1;
535    
# Line 484  switch(*cc) Line 537  switch(*cc)
537    case OP_CHARI:    case OP_CHARI:
538    case OP_NOT:    case OP_NOT:
539    case OP_NOTI:    case OP_NOTI:
   
540    case OP_STAR:    case OP_STAR:
541    case OP_MINSTAR:    case OP_MINSTAR:
542    case OP_PLUS:    case OP_PLUS:
# Line 522  switch(*cc) Line 574  switch(*cc)
574    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
575    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
576    cc += 2;    cc += 2;
577  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
578    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]);
579  #endif  #endif
580    return cc;    return cc;
581    
# Line 543  switch(*cc) Line 595  switch(*cc)
595    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
596    case OP_NOTEXACTI:    case OP_NOTEXACTI:
597    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
598    cc += 4;    cc += 2 + IMM2_SIZE;
599  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
600    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]);
601  #endif  #endif
602    return cc;    return cc;
603    
604    case OP_NOTPROP:    case OP_NOTPROP:
605    case OP_PROP:    case OP_PROP:
606      return cc + 1 + 2;
607    
608    case OP_TYPEUPTO:    case OP_TYPEUPTO:
609    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
610    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 562  switch(*cc) Line 616  switch(*cc)
616    case OP_RREF:    case OP_RREF:
617    case OP_NRREF:    case OP_NRREF:
618    case OP_CLOSE:    case OP_CLOSE:
619    cc += 3;    cc += 1 + IMM2_SIZE;
620    return cc;    return cc;
621    
622    case OP_CRRANGE:    case OP_CRRANGE:
623    case OP_CRMINRANGE:    case OP_CRMINRANGE:
624    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
625    
626    case OP_CLASS:    case OP_CLASS:
627    case OP_NCLASS:    case OP_NCLASS:
628    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
629    
630  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
631    case OP_XCLASS:    case OP_XCLASS:
632    return cc + GET(cc, 1);    return cc + GET(cc, 1);
633  #endif  #endif
# Line 603  switch(*cc) Line 657  switch(*cc)
657    case OP_CBRAPOS:    case OP_CBRAPOS:
658    case OP_SCBRA:    case OP_SCBRA:
659    case OP_SCBRAPOS:    case OP_SCBRAPOS:
660    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
661    
662      case OP_MARK:
663      return cc + 1 + 2 + cc[1];
664    
665    default:    default:
666    return NULL;    return NULL;
667    }    }
668  }  }
669    
670  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
671  {  {
672  int localspace = 0;  int localspace = 0;
673  uschar *alternative;  pcre_uchar *alternative;
674  /* 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. */
675  while (cc < ccend)  while (cc < ccend)
676    {    {
677    switch(*cc)    switch(*cc)
678      {      {
679        case OP_SET_SOM:
680        common->has_set_som = TRUE;
681        cc += 1;
682        break;
683    
684      case OP_ASSERT:      case OP_ASSERT:
685      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
686      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 636  while (cc < ccend) Line 698  while (cc < ccend)
698      case OP_CBRAPOS:      case OP_CBRAPOS:
699      case OP_SCBRAPOS:      case OP_SCBRAPOS:
700      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
701      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
702      break;      break;
703    
704      case OP_COND:      case OP_COND:
# Line 647  while (cc < ccend) Line 709  while (cc < ccend)
709      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
710      break;      break;
711    
712        case OP_RECURSE:
713        /* Set its value only once. */
714        if (common->recursive_head == 0)
715          {
716          common->recursive_head = common->ovector_start;
717          common->ovector_start += sizeof(sljit_w);
718          }
719        cc += 1 + LINK_SIZE;
720        break;
721    
722        case OP_MARK:
723        if (common->mark_ptr == 0)
724          {
725          common->mark_ptr = common->ovector_start;
726          common->ovector_start += sizeof(sljit_w);
727          }
728        cc += 1 + 2 + cc[1];
729        break;
730    
731      default:      default:
732      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
733      if (cc == NULL)      if (cc == NULL)
# Line 657  while (cc < ccend) Line 738  while (cc < ccend)
738  return localspace;  return localspace;
739  }  }
740    
741  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
742  {  {
743  uschar *cc = common->start;  pcre_uchar *cc = common->start;
744  uschar *alternative;  pcre_uchar *alternative;
745  while (cc < ccend)  while (cc < ccend)
746    {    {
747    switch(*cc)    switch(*cc)
# Line 684  while (cc < ccend) Line 765  while (cc < ccend)
765      case OP_SCBRAPOS:      case OP_SCBRAPOS:
766      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
767      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
768      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
769      break;      break;
770    
771      case OP_COND:      case OP_COND:
# Line 707  while (cc < ccend) Line 788  while (cc < ccend)
788  }  }
789    
790  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
791  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
792  {  {
793  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
794  int length = 0;  int length = 0;
795  BOOL possessive = FALSE;  BOOL possessive = FALSE;
796  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
797    BOOL setmark_found = recursive;
798    
799  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
800    {    {
# Line 726  while (cc < ccend) Line 808  while (cc < ccend)
808    switch(*cc)    switch(*cc)
809      {      {
810      case OP_SET_SOM:      case OP_SET_SOM:
811      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
812      if (!setsom_found)      if (!setsom_found)
813        {        {
814        length += 2;        length += 2;
815        setsom_found = TRUE;        setsom_found = TRUE;
816        }        }
817      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
818        break;
819    
820        case OP_MARK:
821        SLJIT_ASSERT(common->mark_ptr != 0);
822        if (!setmark_found)
823          {
824          length += 2;
825          setmark_found = TRUE;
826          }
827        cc += 1 + 2 + cc[1];
828        break;
829    
830        case OP_RECURSE:
831        if (common->has_set_som && !setsom_found)
832          {
833          length += 2;
834          setsom_found = TRUE;
835          }
836        if (common->mark_ptr != 0 && !setmark_found)
837          {
838          length += 2;
839          setmark_found = TRUE;
840          }
841        cc += 1 + LINK_SIZE;
842      break;      break;
843    
844      case OP_CBRA:      case OP_CBRA:
# Line 740  while (cc < ccend) Line 846  while (cc < ccend)
846      case OP_SCBRA:      case OP_SCBRA:
847      case OP_SCBRAPOS:      case OP_SCBRAPOS:
848      length += 3;      length += 3;
849      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
850      break;      break;
851    
852      default:      default:
# Line 758  if (length > 0) Line 864  if (length > 0)
864  return -1;  return -1;
865  }  }
866    
867  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)
868  {  {
869  DEFINE_COMPILER;  DEFINE_COMPILER;
870  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
871  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
872    BOOL setmark_found = recursive;
873  int offset;  int offset;
874    
875  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
876    SLJIT_UNUSED_ARG(stacktop);
877  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
878    
879  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 776  while (cc < ccend) Line 884  while (cc < ccend)
884    switch(*cc)    switch(*cc)
885      {      {
886      case OP_SET_SOM:      case OP_SET_SOM:
887      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
888      if (!setsom_found)      if (!setsom_found)
889        {        {
890        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 786  while (cc < ccend) Line 894  while (cc < ccend)
894        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
895        setsom_found = TRUE;        setsom_found = TRUE;
896        }        }
897      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
898        break;
899    
900        case OP_MARK:
901        SLJIT_ASSERT(common->mark_ptr != 0);
902        if (!setmark_found)
903          {
904          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
905          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
906          stackpos += (int)sizeof(sljit_w);
907          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
908          stackpos += (int)sizeof(sljit_w);
909          setmark_found = TRUE;
910          }
911        cc += 1 + 2 + cc[1];
912        break;
913    
914        case OP_RECURSE:
915        if (common->has_set_som && !setsom_found)
916          {
917          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
918          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
919          stackpos += (int)sizeof(sljit_w);
920          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
921          stackpos += (int)sizeof(sljit_w);
922          setsom_found = TRUE;
923          }
924        if (common->mark_ptr != 0 && !setmark_found)
925          {
926          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
927          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
928          stackpos += (int)sizeof(sljit_w);
929          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
930          stackpos += (int)sizeof(sljit_w);
931          setmark_found = TRUE;
932          }
933        cc += 1 + LINK_SIZE;
934      break;      break;
935    
936      case OP_CBRA:      case OP_CBRA:
# Line 803  while (cc < ccend) Line 947  while (cc < ccend)
947      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
948      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
949    
950      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
951      break;      break;
952    
953      default:      default:
# Line 816  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 960  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
960  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
961  }  }
962    
963  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)
964  {  {
965  int localsize = 2;  int localsize = 2;
966  uschar *alternative;  pcre_uchar *alternative;
967  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
968  while (cc < ccend)  while (cc < ccend)
969    {    {
# Line 842  while (cc < ccend) Line 986  while (cc < ccend)
986      case OP_CBRA:      case OP_CBRA:
987      case OP_SCBRA:      case OP_SCBRA:
988      localsize++;      localsize++;
989      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
990      break;      break;
991    
992      case OP_CBRAPOS:      case OP_CBRAPOS:
993      case OP_SCBRAPOS:      case OP_SCBRAPOS:
994      localsize += 2;      localsize += 2;
995      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
996      break;      break;
997    
998      case OP_COND:      case OP_COND:
# Line 869  SLJIT_ASSERT(cc == ccend); Line 1013  SLJIT_ASSERT(cc == ccend);
1013  return localsize;  return localsize;
1014  }  }
1015    
1016  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1017    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1018  {  {
1019  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 878  int count; Line 1022  int count;
1022  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1023  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1024  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1025  uschar *alternative;  pcre_uchar *alternative;
1026  enum {  enum {
1027    start,    start,
1028    loop,    loop,
# Line 913  while (status != end) Line 1057  while (status != end)
1057    switch(status)    switch(status)
1058      {      {
1059      case start:      case start:
1060      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1061      count = 1;      count = 1;
1062      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1063      status = loop;      status = loop;
1064      break;      break;
1065    
# Line 939  while (status != end) Line 1083  while (status != end)
1083        case OP_SBRAPOS:        case OP_SBRAPOS:
1084        case OP_SCOND:        case OP_SCOND:
1085        count = 1;        count = 1;
1086        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1087        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1088        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1089        break;        break;
# Line 948  while (status != end) Line 1092  while (status != end)
1092        case OP_SCBRA:        case OP_SCBRA:
1093        count = 1;        count = 1;
1094        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1095        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1096        break;        break;
1097    
1098        case OP_CBRAPOS:        case OP_CBRAPOS:
1099        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1100        count = 2;        count = 2;
1101        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1102        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1103        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1104        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1105        break;        break;
1106    
1107        case OP_COND:        case OP_COND:
# Line 966  while (status != end) Line 1110  while (status != end)
1110        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1111          {          {
1112          count = 1;          count = 1;
1113          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1114          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1115          }          }
1116        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1174  struct sljit_label *loop; Line 1318  struct sljit_label *loop;
1318  int i;  int i;
1319  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1320  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1321  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));
1322  if (length < 8)  if (length < 8)
1323    {    {
1324    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1182  if (length < 8) Line 1326  if (length < 8)
1326    }    }
1327  else  else
1328    {    {
1329    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));
1330    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1331    loop = LABEL();    loop = LABEL();
1332    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 1198  struct sljit_label *loop; Line 1342  struct sljit_label *loop;
1342  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1343    
1344  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1345  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));
1346  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);
1347    
1348  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1349    if (common->mark_ptr != 0)
1350      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1351  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));
1352    if (common->mark_ptr != 0)
1353      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1354  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));
1355  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));
1356  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1357  /* Unlikely, but possible */  /* Unlikely, but possible */
1358  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1359  loop = LABEL();  loop = LABEL();
1360  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);
1361  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));
1362  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1363  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1364    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1365    #endif
1366    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1367  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);
1368  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1369  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1220  JUMPHERE(earlyexit); Line 1371  JUMPHERE(earlyexit);
1371  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1372  if (topbracket > 1)  if (topbracket > 1)
1373    {    {
1374    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));
1375    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1376    
1377    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1378    loop = LABEL();    loop = LABEL();
1379    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)));
1380    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);
1381    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);
1382    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1383    }    }
1384  else  else
1385    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1386  }  }
1387    
1388  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 *leave)
1389    {
1390    DEFINE_COMPILER;
1391    
1392    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1393    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1394    
1395    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1396    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1397    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1398    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1399    
1400    /* Store match begin and end. */
1401    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1402    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1403    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);
1404    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1405    #ifdef COMPILE_PCRE16
1406    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1407    #endif
1408    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1409    
1410    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1411    #ifdef COMPILE_PCRE16
1412    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1413    #endif
1414    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1415    
1416    JUMPTO(SLJIT_JUMP, leave);
1417    }
1418    
1419    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1420    {
1421    /* May destroy TMP1. */
1422    DEFINE_COMPILER;
1423    struct sljit_jump *jump;
1424    
1425    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1426      {
1427      /* The value of -1 must be kept for start_used_ptr! */
1428      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1429      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1430      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1431      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1432      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1433      JUMPHERE(jump);
1434      }
1435    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1436      {
1437      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1438      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1439      JUMPHERE(jump);
1440      }
1441    }
1442    
1443    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1444  {  {
1445  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1446  unsigned int c;  unsigned int c;
1447    
1448  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1449  if (common->utf8)  if (common->utf)
1450    {    {
1451    GETCHAR(c, cc);    GETCHAR(c, cc);
1452    if (c > 127)    if (c > 127)
# Line 1251  if (common->utf8) Line 1457  if (common->utf8)
1457      return FALSE;      return FALSE;
1458  #endif  #endif
1459      }      }
1460    #ifndef COMPILE_PCRE8
1461      return common->fcc[c] != c;
1462    #endif
1463    }    }
1464  else  else
1465  #endif  #endif
1466    c = *cc;    c = *cc;
1467  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1468  }  }
1469    
1470  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)
1471  {  {
1472  /* Returns with the othercase. */  /* Returns with the othercase. */
1473  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1474  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1475    {    {
1476  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1477    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1271  if (common->utf8 && c > 127) Line 1480  if (common->utf8 && c > 127)
1480  #endif  #endif
1481    }    }
1482  #endif  #endif
1483  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1484  }  }
1485    
1486  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)
1487  {  {
1488  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1489  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1490  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1491  int n;  int n;
1492  #endif  #endif
1493    
1494  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1495  if (common->utf8)  if (common->utf)
1496    {    {
1497    GETCHAR(c, cc);    GETCHAR(c, cc);
1498    if (c <= 127)    if (c <= 127)
# Line 1300  if (common->utf8) Line 1509  if (common->utf8)
1509  else  else
1510    {    {
1511    c = *cc;    c = *cc;
1512    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1513    }    }
1514  #else  #else
1515  c = *cc;  c = *cc;
1516  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1517  #endif  #endif
1518    
1519  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1318  if (c <= 127 && bit == 0x20) Line 1527  if (c <= 127 && bit == 0x20)
1527  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1528    return 0;    return 0;
1529    
1530  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1531  if (common->utf8 && c > 127)  
1532    #ifdef SUPPORT_UTF
1533    if (common->utf && c > 127)
1534    {    {
1535    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1536    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1537      {      {
1538      n--;      n--;
# Line 1329  if (common->utf8 && c > 127) Line 1540  if (common->utf8 && c > 127)
1540      }      }
1541    return (n << 8) | bit;    return (n << 8) | bit;
1542    }    }
1543  #endif  #endif /* SUPPORT_UTF */
1544  return (0 << 8) | bit;  return (0 << 8) | bit;
1545    
1546    #else /* COMPILE_PCRE8 */
1547    
1548    #ifdef COMPILE_PCRE16
1549    #ifdef SUPPORT_UTF
1550    if (common->utf && c > 65535)
1551      {
1552      if (bit >= (1 << 10))
1553        bit >>= 10;
1554      else
1555        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1556      }
1557    #endif /* SUPPORT_UTF */
1558    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1559    #endif /* COMPILE_PCRE16 */
1560    
1561    #endif /* COMPILE_PCRE8 */
1562  }  }
1563    
1564  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common, BOOL force)
1565  {  {
1566    /* Checks whether a partial matching is occured. Does not modify registers. */
1567  DEFINE_COMPILER;  DEFINE_COMPILER;
1568  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump = NULL;
1569    
1570    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1571    
1572    if (common->mode == JIT_COMPILE)
1573      return;
1574    
1575    if (!force)
1576      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1577    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1578      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1579    
1580    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1581      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1582    else
1583      {
1584      if (common->partialmatchlabel != NULL)
1585        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1586      else
1587        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1588      }
1589    
1590    if (jump != NULL)
1591      JUMPHERE(jump);
1592    }
1593    
1594    static struct sljit_jump *check_str_end(compiler_common *common)
1595    {
1596    /* Does not affect registers. Usually used in a tight spot. */
1597    DEFINE_COMPILER;
1598    struct sljit_jump *jump;
1599    struct sljit_jump *nohit;
1600    struct sljit_jump *return_value;
1601    
1602    if (common->mode == JIT_COMPILE)
1603      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1604    
1605    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1606    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1607      {
1608      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1609      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1610      JUMPHERE(nohit);
1611      return_value = JUMP(SLJIT_JUMP);
1612      }
1613    else
1614      {
1615      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1616      if (common->partialmatchlabel != NULL)
1617        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1618      else
1619        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1620      }
1621    JUMPHERE(jump);
1622    return return_value;
1623    }
1624    
1625    static void detect_partial_match(compiler_common *common, jump_list **backtracks)
1626    {
1627    DEFINE_COMPILER;
1628    struct sljit_jump *jump;
1629    
1630    if (common->mode == JIT_COMPILE)
1631      {
1632      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1633      return;
1634      }
1635    
1636    /* Partial matching mode. */
1637    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1638    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1639    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1640      {
1641      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1642      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
1643      }
1644    else
1645      {
1646      if (common->partialmatchlabel != NULL)
1647        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1648      else
1649        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1650      }
1651    JUMPHERE(jump);
1652  }  }
1653    
1654  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1344  static void read_char(compiler_common *c Line 1656  static void read_char(compiler_common *c
1656  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1657  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1658  DEFINE_COMPILER;  DEFINE_COMPILER;
1659  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1660  struct sljit_jump *jump;  struct sljit_jump *jump;
1661  #endif  #endif
1662    
1663  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1664  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1665  if (common->utf8)  if (common->utf)
1666    {    {
1667    #ifdef COMPILE_PCRE8
1668    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1669    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1670    #ifdef COMPILE_PCRE16
1671      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1672    #endif
1673    #endif /* COMPILE_PCRE8 */
1674      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1675    JUMPHERE(jump);    JUMPHERE(jump);
1676    }    }
1677  #endif  #endif
1678  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));
1679  }  }
1680    
1681  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1365  static void peek_char(compiler_common *c Line 1683  static void peek_char(compiler_common *c
1683  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1684  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1685  DEFINE_COMPILER;  DEFINE_COMPILER;
1686  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1687  struct sljit_jump *jump;  struct sljit_jump *jump;
1688  #endif  #endif
1689    
1690  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1691  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1692  if (common->utf8)  if (common->utf)
1693    {    {
1694    #ifdef COMPILE_PCRE8
1695    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1696    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1697    #ifdef COMPILE_PCRE16
1698      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1699    #endif
1700    #endif /* COMPILE_PCRE8 */
1701      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1702    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1703    JUMPHERE(jump);    JUMPHERE(jump);
1704    }    }
# Line 1385  static void read_char8_type(compiler_com Line 1709  static void read_char8_type(compiler_com
1709  {  {
1710  /* 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. */
1711  DEFINE_COMPILER;  DEFINE_COMPILER;
1712  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1713  struct sljit_jump *jump;  struct sljit_jump *jump;
1714  #endif  #endif
1715    
1716  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1717  if (common->utf8)  if (common->utf)
1718    {    {
1719    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1720    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));
1721    #ifdef COMPILE_PCRE8
1722    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1723    it is a clever early read in most cases. */    it is needed in most cases. */
1724    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1725    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1726    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1727    JUMPHERE(jump);    JUMPHERE(jump);
1728    #else
1729    #ifdef COMPILE_PCRE16
1730      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1731      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1732      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1733      JUMPHERE(jump);
1734      /* Skip low surrogate if necessary. */
1735      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1736      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1737      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1738      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1739      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1740    #endif
1741    #endif /* COMPILE_PCRE8 */
1742    return;    return;
1743    }    }
1744  #endif  #endif
1745  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1746  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));
1747  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1748    /* The ctypes array contains only 256 values. */
1749    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1750    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1751    #endif
1752    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1753    #ifdef COMPILE_PCRE16
1754    JUMPHERE(jump);
1755    #endif
1756  }  }
1757    
1758  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1759  {  {
1760  /* 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. */
1761  DEFINE_COMPILER;  DEFINE_COMPILER;
1762  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1763  struct sljit_label *label;  struct sljit_label *label;
1764    
1765  if (common->utf8)  if (common->utf)
1766    {    {
1767    label = LABEL();    label = LABEL();
1768    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1769    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));
1770    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1771    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1772    return;    return;
1773    }    }
1774  #endif  #endif
1775  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1776    if (common->utf)
1777      {
1778      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1779      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1780      /* Skip low surrogate if necessary. */
1781      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1782      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1783      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1784      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1785      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1786      return;
1787      }
1788    #endif
1789    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1790  }  }
1791    
1792  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)
1793  {  {
1794  /* 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. */
1795  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1436  DEFINE_COMPILER; Line 1797  DEFINE_COMPILER;
1797  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
1798    {    {
1799    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
1800    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));
1801    }    }
1802  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
1803    {    {
# Line 1444  else if (nltype == NLTYPE_ANYCRLF) Line 1805  else if (nltype == NLTYPE_ANYCRLF)
1805    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1806    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);
1807    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
1808    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));
1809    }    }
1810  else  else
1811    {    {
1812    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1813    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));
1814    }    }
1815  }  }
1816    
1817  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1818  static void do_utf8readchar(compiler_common *common)  
1819    #ifdef COMPILE_PCRE8
1820    static void do_utfreadchar(compiler_common *common)
1821  {  {
1822  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1823  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
1824  DEFINE_COMPILER;  DEFINE_COMPILER;
1825  struct sljit_jump *jump;  struct sljit_jump *jump;
1826    
1827  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1828  /* Searching for the first zero. */  /* Searching for the first zero. */
1829  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);
1830  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1831  /* 2 byte sequence */  /* Two byte sequence. */
1832  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1833  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));
1834  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1835  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1836  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1837  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1838  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1839  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1840  JUMPHERE(jump);  JUMPHERE(jump);
1841    
1842  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);
1843  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1844  /* 3 byte sequence */  /* Three byte sequence. */
1845  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1846  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1847  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1848  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1849  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1850  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1851  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1852  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));
1853  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1854  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1855  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1856  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1857  JUMPHERE(jump);  JUMPHERE(jump);
1858    
1859  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1860  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);  
1861  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1862  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1863  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1864  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1865  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1866  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
1867  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1868  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1869  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1870  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1871  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1872  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1873  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1874  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1875  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1876  }  }
1877    
1878  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1879  {  {
1880  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1881  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1882  DEFINE_COMPILER;  DEFINE_COMPILER;
1883  struct sljit_jump *jump;  struct sljit_jump *jump;
1884  struct sljit_jump *compare;  struct sljit_jump *compare;
1885    
1886  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1887    
1888  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);
1889  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1890  /* 2 byte sequence */  /* Two byte sequence. */
1891  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1892  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));
1893  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1894  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1895  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1566  sljit_emit_fast_return(compiler, RETURN_ Line 1904  sljit_emit_fast_return(compiler, RETURN_
1904  JUMPHERE(jump);  JUMPHERE(jump);
1905    
1906  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1907  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
1908  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1909  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1910  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1911  }  }
1912    
1913  #endif  #else /* COMPILE_PCRE8 */
1914    
1915    #ifdef COMPILE_PCRE16
1916    static void do_utfreadchar(compiler_common *common)
1917    {
1918    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1919    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1920    DEFINE_COMPILER;
1921    struct sljit_jump *jump;
1922    
1923    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1924    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1925    /* Do nothing, only return. */
1926    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1927    
1928    JUMPHERE(jump);
1929    /* Combine two 16 bit characters. */
1930    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1931    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1932    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1933    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1934    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1935    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1936    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1937    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1938    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1939    }
1940    #endif /* COMPILE_PCRE16 */
1941    
1942    #endif /* COMPILE_PCRE8 */
1943    
1944    #endif /* SUPPORT_UTF */
1945    
1946  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1947    
# Line 1588  DEFINE_COMPILER; Line 1957  DEFINE_COMPILER;
1957    
1958  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
1959    
1960  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
1961  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1962  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));
1963  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1964  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1965  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1966  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1967  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1968  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));
1969  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1970  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1971  }  }
# Line 1610  struct sljit_label *newlinelabel = NULL; Line 1979  struct sljit_label *newlinelabel = NULL;
1979  struct sljit_jump *start;  struct sljit_jump *start;
1980  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1981  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1982  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1983  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
1984  #endif  #endif
1985  jump_list *newline = NULL;  jump_list *newline = NULL;
1986  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1987  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1988    
1989  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1990      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1624  if (!(hascrorlf || firstline) && (common Line 1993  if (!(hascrorlf || firstline) && (common
1993  if (firstline)  if (firstline)
1994    {    {
1995    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1996      SLJIT_ASSERT(common->first_line_end != 0);
1997    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1998    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
1999    
2000    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2001      {      {
2002      mainloop = LABEL();      mainloop = LABEL();
2003      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));
2004      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2005      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2006      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2007      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);
2008      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);
2009      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));
2010      }      }
2011    else    else
2012      {      {
2013      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2014      mainloop = LABEL();      mainloop = LABEL();
2015      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2016      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);
2017      read_char(common);      read_char(common);
2018      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2019      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2020      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);
2021      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2022      }      }
2023    
# Line 1660  start = JUMP(SLJIT_JUMP); Line 2030  start = JUMP(SLJIT_JUMP);
2030  if (newlinecheck)  if (newlinecheck)
2031    {    {
2032    newlinelabel = LABEL();    newlinelabel = LABEL();
2033    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));
2034    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2035    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2036    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);
2037    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2038    #ifdef COMPILE_PCRE16
2039      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2040    #endif
2041    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2042    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2043    }    }
# Line 1672  if (newlinecheck) Line 2045  if (newlinecheck)
2045  mainloop = LABEL();  mainloop = LABEL();
2046    
2047  /* 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. */
2048  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2049  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2050  #endif  #endif
2051  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2052    
2053  if (readbyte)  if (readuchar)
2054    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2055    
2056  if (newlinecheck)  if (newlinecheck)
2057    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);
2058    
2059  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));
2060  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2061  if (common->utf8)  if (common->utf)
2062      {
2063      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2064      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2065      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2066      JUMPHERE(singlechar);
2067      }
2068    #endif
2069    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2070    if (common->utf)
2071    {    {
2072    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2073    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2074      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2075      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2076      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2077    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2078    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
2079    }    }
2080  #endif  #endif
2081  JUMPHERE(start);  JUMPHERE(start);
# Line 1704  if (newlinecheck) Line 2089  if (newlinecheck)
2089  return mainloop;  return mainloop;
2090  }  }
2091    
2092  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2093  {  {
2094  DEFINE_COMPILER;  DEFINE_COMPILER;
2095  struct sljit_label *start;  struct sljit_label *start;
2096  struct sljit_jump *leave;  struct sljit_jump *leave;
2097  struct sljit_jump *found;  struct sljit_jump *found;
2098  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2099    
2100  if (firstline)  if (firstline)
2101    {    {
2102    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2103    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2104    }    }
2105    
2106  start = LABEL();  start = LABEL();
2107  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2108  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2109    
2110  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2111    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2112      {
2113      oc = TABLE_GET(first_char, common->fcc, first_char);
2114    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2115      if (first_char > 127 && common->utf)
2116        oc = UCD_OTHERCASE(first_char);
2117    #endif
2118      }
2119    if (first_char == oc)
2120      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2121  else  else
2122    {    {
2123    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2124    if (ispowerof2(bit))    if (ispowerof2(bit))
2125      {      {
2126      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2127      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2128      }      }
2129    else    else
2130      {      {
2131      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);
2132      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2133      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);
2134      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1744  else Line 2136  else
2136      }      }
2137    }    }
2138    
2139  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));
2140  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2141  if (common->utf8)  if (common->utf)
2142    {    {
2143    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2144    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2145      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2146      }
2147    #endif
2148    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2149    if (common->utf)
2150      {
2151      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2152      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2153      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2154      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2155      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2156    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2157    }    }
2158  #endif  #endif
# Line 1775  jump_list *newline = NULL; Line 2178  jump_list *newline = NULL;
2178  if (firstline)  if (firstline)
2179    {    {
2180    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2181    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2182    }    }
2183    
2184  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1786  if (common->nltype == NLTYPE_FIXED && co Line 2189  if (common->nltype == NLTYPE_FIXED && co
2189    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));
2190    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2191    
2192    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2193    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);
2194    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2195    #ifdef COMPILE_PCRE16
2196      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2197    #endif
2198    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2199    
2200    loop = LABEL();    loop = LABEL();
2201    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));
2202    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2203    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2204    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2205    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);
2206    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);
2207    
# Line 1826  if (common->nltype == NLTYPE_ANY || comm Line 2232  if (common->nltype == NLTYPE_ANY || comm
2232    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2233    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2234    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2235    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2236    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);
2237    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2238    #ifdef COMPILE_PCRE16
2239      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2240    #endif
2241    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2242    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2243    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1846  DEFINE_COMPILER; Line 2255  DEFINE_COMPILER;
2255  struct sljit_label *start;  struct sljit_label *start;
2256  struct sljit_jump *leave;  struct sljit_jump *leave;
2257  struct sljit_jump *found;  struct sljit_jump *found;
2258    #ifndef COMPILE_PCRE8
2259    struct sljit_jump *jump;
2260    #endif
2261    
2262  if (firstline)  if (firstline)
2263    {    {
2264    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2265    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2266    }    }
2267    
2268  start = LABEL();  start = LABEL();
2269  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2270  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2271  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2272  if (common->utf8)  if (common->utf)
2273    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2274  #endif  #endif
2275    #ifndef COMPILE_PCRE8
2276    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2277    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2278    JUMPHERE(jump);
2279    #endif
2280  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2281  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2282  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1867  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2284  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2284  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);
2285  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2286    
2287  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2288  if (common->utf8)  if (common->utf)
2289    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2290  #endif  #endif
2291  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));
2292  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2293  if (common->utf8)  if (common->utf)
2294    {    {
2295    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2296    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2297      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2298      }
2299    #endif
2300    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2301    if (common->utf)
2302      {
2303      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2304      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2305      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2306      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2307      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2308    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2309    }    }
2310  #endif  #endif
# Line 1888  if (firstline) Line 2316  if (firstline)
2316    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2317  }  }
2318    
2319  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)
2320  {  {
2321  DEFINE_COMPILER;  DEFINE_COMPILER;
2322  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1897  struct sljit_jump *alreadyfound; Line 2325  struct sljit_jump *alreadyfound;
2325  struct sljit_jump *found;  struct sljit_jump *found;
2326  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2327  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2328  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2329    
2330  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2331    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2332  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);
2333  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2334  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2335    
2336  if (has_firstbyte)  if (has_firstchar)
2337    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2338  else  else
2339    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2340    
2341  loop = LABEL();  loop = LABEL();
2342  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2343    
2344  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2345  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2346    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2347      {
2348      oc = TABLE_GET(req_char, common->fcc, req_char);
2349    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2350      if (req_char > 127 && common->utf)
2351        oc = UCD_OTHERCASE(req_char);
2352    #endif
2353      }
2354    if (req_char == oc)
2355      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2356  else  else
2357    {    {
2358    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2359    if (ispowerof2(bit))    if (ispowerof2(bit))
2360      {      {
2361      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2362      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2363      }      }
2364    else    else
2365      {      {
2366      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2367      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2368      }      }
2369    }    }
2370  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2371  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2372    
2373  JUMPHERE(found);  JUMPHERE(found);
2374  if (foundoc)  if (foundoc)
2375    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2376  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);
2377  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2378  JUMPHERE(toolong);  JUMPHERE(toolong);
2379  return notfound;  return notfound;
# Line 1949  DEFINE_COMPILER; Line 2385  DEFINE_COMPILER;
2385  struct sljit_jump *jump;  struct sljit_jump *jump;
2386  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2387    
2388  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2389  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2390    GET_LOCAL_BASE(TMP3, 0, 0);
2391    
2392  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2393  mainloop = LABEL();  mainloop = LABEL();
2394  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2395  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);
2396  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2397  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));
2398  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));
2399  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 1976  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2413  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2413  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2414    
2415  JUMPHERE(jump);  JUMPHERE(jump);
2416    if (common->mark_ptr != 0)
2417      {
2418      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2419      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2420      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2421      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2422      JUMPTO(SLJIT_JUMP, mainloop);
2423    
2424      JUMPHERE(jump);
2425      }
2426    
2427  /* Unknown command. */  /* Unknown command. */
2428  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));
2429  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 1984  JUMPTO(SLJIT_JUMP, mainloop); Line 2432  JUMPTO(SLJIT_JUMP, mainloop);
2432  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2433  {  {
2434  DEFINE_COMPILER;  DEFINE_COMPILER;
2435  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2436  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2437  struct sljit_jump *jump;  struct sljit_jump *jump;
2438  #endif  #endif
2439    
2440  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2441    
2442  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);
2443  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2444  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2445  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));
2446  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2447  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2448  skip_char_back(common);  skip_char_back(common);
2449    check_start_used_ptr(common);
2450  read_char(common);  read_char(common);
2451    
2452  /* Testing char type. */  /* Testing char type. */
2453  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2454  if (common->useucp)  if (common->use_ucp)
2455    {    {
2456    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2457    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2019  if (common->useucp) Line 2468  if (common->useucp)
2468  else  else
2469  #endif  #endif
2470    {    {
2471  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2472      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2473    #elif defined SUPPORT_UTF
2474    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2475    jump = NULL;    jump = NULL;
2476    if (common->utf8)    if (common->utf)
2477      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2478  #endif  #endif /* COMPILE_PCRE8 */
2479    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2480    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2481    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2482    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2483  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2484      JUMPHERE(jump);
2485    #elif defined SUPPORT_UTF
2486    if (jump != NULL)    if (jump != NULL)
2487      JUMPHERE(jump);      JUMPHERE(jump);
2488  #endif  #endif /* COMPILE_PCRE8 */
2489    }    }
2490  JUMPHERE(beginend);  JUMPHERE(skipread);
2491    
2492  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2493  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2494  peek_char(common);  peek_char(common);
2495    
2496  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2497  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2498  if (common->useucp)  if (common->use_ucp)
2499    {    {
2500    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2501    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2058  if (common->useucp) Line 2511  if (common->useucp)
2511  else  else
2512  #endif  #endif
2513    {    {
2514  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2515      /* TMP2 may be destroyed by peek_char. */
2516      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2517      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2518    #elif defined SUPPORT_UTF
2519    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2520    jump = NULL;    jump = NULL;
2521    if (common->utf8)    if (common->utf)
2522      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2523  #endif  #endif
2524    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2525    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2526    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2527  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2528      JUMPHERE(jump);
2529    #elif defined SUPPORT_UTF
2530    if (jump != NULL)    if (jump != NULL)
2531      JUMPHERE(jump);      JUMPHERE(jump);
2532  #endif  #endif /* COMPILE_PCRE8 */
2533    }    }
2534  JUMPHERE(beginend);  JUMPHERE(skipread);
2535    
2536  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);
2537  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2083  static void check_anynewline(compiler_co Line 2542  static void check_anynewline(compiler_co
2542  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2543  DEFINE_COMPILER;  DEFINE_COMPILER;
2544    
2545  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2546    
2547  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2548  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);
2549  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2550  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);
2551  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2552  if (common->utf8)  #ifdef COMPILE_PCRE8
2553    if (common->utf)
2554    {    {
2555    #endif
2556    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2557    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2558    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);
2559    #ifdef COMPILE_PCRE8
2560    }    }
2561  #endif  #endif
2562    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2563  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2564  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2565  }  }
# Line 2106  static void check_hspace(compiler_common Line 2569  static void check_hspace(compiler_common
2569  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2570  DEFINE_COMPILER;  DEFINE_COMPILER;
2571    
2572  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2573    
2574  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);
2575  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2576  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);
2577  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2578  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);
2579  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2580  if (common->utf8)  #ifdef COMPILE_PCRE8
2581    if (common->utf)
2582    {    {
2583    #endif
2584    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2585    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);
2586    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2129  if (common->utf8) Line 2594  if (common->utf8)
2594    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);
2595    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2596    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);
2597    #ifdef COMPILE_PCRE8
2598    }    }
2599  #endif  #endif
2600    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2601  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2602    
2603  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2141  static void check_vspace(compiler_common Line 2608  static void check_vspace(compiler_common
2608  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
2609  DEFINE_COMPILER;  DEFINE_COMPILER;
2610    
2611  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2612    
2613  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
2614  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);
2615  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2616  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);
2617  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2618  if (common->utf8)  #ifdef COMPILE_PCRE8
2619    if (common->utf)
2620    {    {
2621    #endif
2622    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2623    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2624    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);
2625    #ifdef COMPILE_PCRE8
2626    }    }
2627  #endif  #endif
2628    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2629  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2630    
2631  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2169  DEFINE_COMPILER; Line 2640  DEFINE_COMPILER;
2640  struct sljit_jump *jump;  struct sljit_jump *jump;
2641  struct sljit_label *label;  struct sljit_label *label;
2642    
2643  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2644  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2645  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2646  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2647  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2648  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));
2649    
2650  label = LABEL();  label = LABEL();
2651  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2652  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2653  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2654  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));
2655  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2656    
2657  JUMPHERE(jump);  JUMPHERE(jump);
2658  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));
2659  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2660  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2661  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2198  DEFINE_COMPILER; Line 2669  DEFINE_COMPILER;
2669  struct sljit_jump *jump;  struct sljit_jump *jump;
2670  struct sljit_label *label;  struct sljit_label *label;
2671    
2672  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2673  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2674    
2675  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2676  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2677  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2678  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2679  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2680  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));
2681    
2682  label = LABEL();  label = LABEL();
2683  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2684  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2685    #ifndef COMPILE_PCRE8
2686    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2687    #endif
2688  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2689    #ifndef COMPILE_PCRE8
2690    JUMPHERE(jump);
2691    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2692    #endif
2693  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2694    #ifndef COMPILE_PCRE8
2695    JUMPHERE(jump);
2696    #endif
2697  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2698  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));
2699  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2700    
2701  JUMPHERE(jump);  JUMPHERE(jump);
2702  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));
2703  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2704  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2705  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2229  sljit_emit_fast_return(compiler, RETURN_ Line 2710  sljit_emit_fast_return(compiler, RETURN_
2710  #undef CHAR1  #undef CHAR1
2711  #undef CHAR2  #undef CHAR2
2712    
2713  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2714    
2715  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)
2716  {  {
2717  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2718  int c1, c2;  int c1, c2;
2719  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2720  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2721    
2722  while (src1 < end1)  while (src1 < end1)
2723    {    {
2724    if (src2 >= end2)    if (src2 >= end2)
2725      return 0;      return (pcre_uchar*)1;
2726    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2727    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2728    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2729    }    }
2730  return src2;  return src2;
2731  }  }
2732    
2733  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2734    
2735  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,
2736      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
2737  {  {
2738  DEFINE_COMPILER;  DEFINE_COMPILER;
2739  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2740  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2741  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2742  int utf8length;  int utflength;
2743  #endif  #endif
2744    
2745  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2268  if (caseless && char_has_othercase(commo Line 2747  if (caseless && char_has_othercase(commo
2747    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2748    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2749    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2750    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2751      othercasechar = cc + (othercasebit >> 8);
2752    othercasebit &= 0xff;    othercasebit &= 0xff;
2753    #else
2754    #ifdef COMPILE_PCRE16
2755      othercasechar = cc + (othercasebit >> 9);
2756      if ((othercasebit & 0x100) != 0)
2757        othercasebit = (othercasebit & 0xff) << 8;
2758      else
2759        othercasebit &= 0xff;
2760    #endif
2761    #endif
2762    }    }
2763    
2764  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2765    {    {
2766    #ifdef COMPILE_PCRE8
2767  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2768    if (context->length >= 4)    if (context->length >= 4)
2769      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2770    else if (context->length >= 2)    else if (context->length >= 2)
2771      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2772    else    else
2773  #endif  #endif
2774      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2775    #else
2776    #ifdef COMPILE_PCRE16
2777    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2778      if (context->length >= 4)
2779        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2780      else
2781    #endif
2782        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2783    #endif
2784    #endif /* COMPILE_PCRE8 */
2785    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2786    }    }
2787    
2788  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2789  utf8length = 1;  utflength = 1;
2790  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2791    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2792    
2793  do  do
2794    {    {
2795  #endif  #endif
2796    
2797    context->length--;    context->length -= IN_UCHARS(1);
2798  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2799    
2800    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2801    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2802      {      {
2803      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2804      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2805      }      }
2806    else    else
2807      {      {
2808      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2809      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2810      }      }
2811    context->byteptr++;    context->ucharptr++;
2812    
2813    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2814      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2815    #else
2816      if (context->ucharptr >= 2 || context->length == 0)
2817    #endif
2818      {      {
2819      if (context->length >= 4)      if (context->length >= 4)
2820        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);
2821    #ifdef COMPILE_PCRE8
2822      else if (context->length >= 2)      else if (context->length >= 2)
2823        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);
2824      else if (context->length >= 1)      else if (context->length >= 1)
2825        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);
2826    #else
2827        else if (context->length >= 2)
2828          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2829    #endif
2830      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2831    
2832      switch(context->byteptr)      switch(context->ucharptr)
2833        {        {
2834        case 4:        case 4 / sizeof(pcre_uchar):
2835        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2836          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);
2837        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));
2838        break;        break;
2839    
2840        case 2:        case 2 / sizeof(pcre_uchar):
2841        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2842          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);
2843        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));
2844        break;        break;
2845    
2846    #ifdef COMPILE_PCRE8
2847        case 1:        case 1:
2848        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2849          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);
2850        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));
2851        break;        break;
2852    #endif
2853    
2854        default:        default:
2855        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2856        break;        break;
2857        }        }
2858      context->byteptr = 0;      context->ucharptr = 0;
2859      }      }
2860    
2861  #else  #else
2862    
2863    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2864    #ifdef COMPILE_PCRE8
2865    if (context->length > 0)    if (context->length > 0)
2866      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);
2867    #else
2868      if (context->length > 0)
2869        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2870    #endif
2871    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2872    
2873    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2874      {      {
2875      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2876      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));
2877      }      }
2878    else    else
2879      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));
2880    
2881  #endif  #endif
2882    
2883    cc++;    cc++;
2884  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2885    utf8length--;    utflength--;
2886    }    }
2887  while (utf8length > 0);  while (utflength > 0);
2888  #endif  #endif
2889    
2890  return cc;  return cc;
2891  }  }
2892    
2893  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2894    
2895  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2896    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2396  return cc; Line 2912  return cc;
2912      } \      } \
2913    charoffset = (value);    charoffset = (value);
2914    
2915  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)
2916  {  {
2917  DEFINE_COMPILER;  DEFINE_COMPILER;
2918  jump_list *found = NULL;  jump_list *found = NULL;
2919  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
2920  unsigned int c;  unsigned int c;
2921  int compares;  int compares;
2922  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2923  uschar *ccbegin;  pcre_uchar *ccbegin;
2924  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2925  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2926  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2414  unsigned int typeoffset; Line 2930  unsigned int typeoffset;
2930  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2931  unsigned int charoffset;  unsigned int charoffset;
2932    
2933  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2934  check_input_end(common, fallbacks);  detect_partial_match(common, backtracks);
2935  read_char(common);  read_char(common);
2936    
2937  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2938    {    {
2939    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2940    if (common->utf8)  #ifndef COMPILE_PCRE8
2941      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2942    #elif defined SUPPORT_UTF
2943      if (common->utf)
2944      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2945    #endif
2946    
2947    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2948    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2431  if ((*cc++ & XCL_MAP) != 0) Line 2951  if ((*cc++ & XCL_MAP) != 0)
2951    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);
2952    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2953    
2954    if (common->utf8)  #ifndef COMPILE_PCRE8
2955      JUMPHERE(jump);
2956    #elif defined SUPPORT_UTF
2957      if (common->utf)
2958      JUMPHERE(jump);      JUMPHERE(jump);
2959    #endif
2960    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2961  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2962    charsaved = TRUE;    charsaved = TRUE;
2963  #endif  #endif
2964    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2965    }    }
2966    
2967  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2449  while (*cc != XCL_END) Line 2973  while (*cc != XCL_END)
2973    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2974      {      {
2975      cc += 2;      cc += 2;
2976  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2977      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]);
2978  #endif  #endif
2979  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2980      needschar = TRUE;      needschar = TRUE;
# Line 2459  while (*cc != XCL_END) Line 2983  while (*cc != XCL_END)
2983    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2984      {      {
2985      cc += 2;      cc += 2;
2986  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2987      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]);
2988  #endif  #endif
2989      cc++;      cc++;
2990  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2991      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]);
2992  #endif  #endif
2993  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2994      needschar = TRUE;      needschar = TRUE;
# Line 2534  if (needstype || needsscript) Line 3058  if (needstype || needsscript)
3058      {      {
3059      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3060        {        {
3061        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));
3062        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3063        }        }
3064      else      else
3065        {        {
3066        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3067        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));
3068        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3069        }        }
3070      }      }
# Line 2558  typeoffset = 0; Line 3082  typeoffset = 0;
3082  while (*cc != XCL_END)  while (*cc != XCL_END)
3083    {    {
3084    compares--;    compares--;
3085    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3086    jump = NULL;    jump = NULL;
3087    
3088    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3089      {      {
3090      cc ++;      cc ++;
3091  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3092      if (common->utf8)      if (common->utf)
3093        {        {
3094        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3095        }        }
# Line 2595  while (*cc != XCL_END) Line 3119  while (*cc != XCL_END)
3119    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3120      {      {
3121      cc ++;      cc ++;
3122  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3123      if (common->utf8)      if (common->utf)
3124        {        {
3125        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3126        }        }
# Line 2604  while (*cc != XCL_END) Line 3128  while (*cc != XCL_END)
3128  #endif  #endif
3129        c = *cc++;        c = *cc++;
3130      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3131  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3132      if (common->utf8)      if (common->utf)
3133        {        {
3134        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3135        }        }
# Line 2640  while (*cc != XCL_END) Line 3164  while (*cc != XCL_END)
3164      switch(*cc)      switch(*cc)
3165        {        {
3166        case PT_ANY:        case PT_ANY:
3167        if (list != fallbacks)        if (list != backtracks)
3168          {          {
3169          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))
3170            continue;            continue;
# Line 2661  while (*cc != XCL_END) Line 3185  while (*cc != XCL_END)
3185        break;        break;
3186    
3187        case PT_GC:        case PT_GC:
3188        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3189        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3190        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);
3191        break;        break;
3192    
3193        case PT_PC:        case PT_PC:
# Line 2713  while (*cc != XCL_END) Line 3237  while (*cc != XCL_END)
3237  #endif  #endif
3238    
3239    if (jump != NULL)    if (jump != NULL)
3240      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3241    }    }
3242    
3243  if (found != NULL)  if (found != NULL)
# Line 2725  if (found != NULL) Line 3249  if (found != NULL)
3249    
3250  #endif  #endif
3251    
3252  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)
3253  {  {
3254  DEFINE_COMPILER;  DEFINE_COMPILER;
3255  int length;  int length;
3256  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3257  compare_context context;  compare_context context;
3258  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3259  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3260  struct sljit_label *label;  struct sljit_label *label;
3261  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3262  uschar propdata[5];  pcre_uchar propdata[5];
3263  #endif  #endif
3264  #endif  #endif
3265    
# Line 2744  switch(type) Line 3268  switch(type)
3268    case OP_SOD:    case OP_SOD:
3269    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3270    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));
3271    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));
3272    return cc;    return cc;
3273    
3274    case OP_SOM:    case OP_SOM:
3275    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3276    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));
3277    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));
3278    return cc;    return cc;
3279    
3280    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
3281    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
3282    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3283    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));
3284    return cc;    return cc;
3285    
3286    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3287    case OP_DIGIT:    case OP_DIGIT:
3288    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3289    read_char8_type(common);    read_char8_type(common);
3290    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3291    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3292    return cc;    return cc;
3293    
3294    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3295    case OP_WHITESPACE:    case OP_WHITESPACE:
3296    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3297    read_char8_type(common);    read_char8_type(common);
3298    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);
3299    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));
3300    return cc;    return cc;
3301    
3302    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3303    case OP_WORDCHAR:    case OP_WORDCHAR:
3304    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3305    read_char8_type(common);    read_char8_type(common);
3306    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);
3307    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));
3308    return cc;    return cc;
3309    
3310    case OP_ANY:    case OP_ANY:
3311    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3312    read_char(common);    read_char(common);
3313    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3314      {      {
3315      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);
3316      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3317      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3318      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      else
3319      JUMPHERE(jump[1]);        jump[1] = check_str_end(common);
3320    
3321        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3322        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3323        if (jump[1] != NULL)
3324          JUMPHERE(jump[1]);
3325      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3326      }      }
3327    else    else
3328      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
3329    return cc;    return cc;
3330    
3331    case OP_ALLANY:    case OP_ALLANY:
3332    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3333  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3334    if (common->utf8)    if (common->utf)
3335      {      {
3336      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3337      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));
3338    #ifdef COMPILE_PCRE8
3339      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3340      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3341      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3342    #else /* COMPILE_PCRE8 */
3343    #ifdef COMPILE_PCRE16
3344        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3345        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3346        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3347        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3348        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3349        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3350    #endif /* COMPILE_PCRE16 */
3351    #endif /* COMPILE_PCRE8 */
3352      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3353      return cc;      return cc;
3354      }      }
3355  #endif  #endif
3356    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));
3357    return cc;    return cc;
3358    
3359    case OP_ANYBYTE:    case OP_ANYBYTE:
3360    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3361    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));
3362    return cc;    return cc;
3363    
3364  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3365  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3366    case OP_NOTPROP:    case OP_NOTPROP:
3367    case OP_PROP:    case OP_PROP:
# Line 2830  switch(type) Line 3370  switch(type)
3370    propdata[2] = cc[0];    propdata[2] = cc[0];
3371    propdata[3] = cc[1];    propdata[3] = cc[1];
3372    propdata[4] = XCL_END;    propdata[4] = XCL_END;
3373    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_trypath(common, propdata, backtracks);
3374    return cc + 2;    return cc + 2;
3375  #endif  #endif
3376  #endif  #endif
3377    
3378    case OP_ANYNL:    case OP_ANYNL:
3379    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3380    read_char(common);    read_char(common);
3381    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3382    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3383    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3384        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3385      else
3386        jump[1] = check_str_end(common);
3387      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3388    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3389    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));
3390    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3391    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3392    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
3393    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3394    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
3395    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 2853  switch(type) Line 3397  switch(type)
3397    
3398    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3399    case OP_HSPACE:    case OP_HSPACE:
3400    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3401    read_char(common);    read_char(common);
3402    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3403    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3404    return cc;    return cc;
3405    
3406    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3407    case OP_VSPACE:    case OP_VSPACE:
3408    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3409    read_char(common);    read_char(common);
3410    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3411    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
3412    return cc;    return cc;
3413    
3414  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3415    case OP_EXTUNI:    case OP_EXTUNI:
3416    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3417    read_char(common);    read_char(common);
3418    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3419    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
3420    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));
3421    
3422    label = LABEL();    label = LABEL();
3423    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
# Line 2885  switch(type) Line 3429  switch(type)
3429    
3430    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3431    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3432      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3433        {
3434        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3435        /* Since we successfully read a char above, partial matching must occure. */
3436        check_partial(common, TRUE);
3437        JUMPHERE(jump[0]);
3438        }
3439    return cc;    return cc;
3440  #endif  #endif
3441    
3442    case OP_EODN:    case OP_EODN:
3443      /* Requires rather complex checks. */
3444    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3445    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3446      {      {
3447      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3448      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3449      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3450      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3451      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      else
3452      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));        {
3453          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3454          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3455          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3456          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3457          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3458          add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
3459          check_partial(common, TRUE);
3460          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3461          JUMPHERE(jump[1]);
3462          }
3463        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3464        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3465        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3466      }      }
3467    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3468      {      {
3469      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3470      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3471      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3472      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3473      }      }
3474    else    else
3475      {      {
3476      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3477      jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);      jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3478      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3479      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3480      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3481      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
3482      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3483        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3484      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3485      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3486    
3487      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3488      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3489        {        {
3490        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3491        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
3492        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3493        }        }
3494      else      else
3495        {        {
3496        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
3497        read_char(common);        read_char(common);
3498        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3499        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
3500        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3501        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3502        }        }
3503      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
3504      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3505      }      }
3506    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3507      check_partial(common, FALSE);
3508    return cc;    return cc;
3509    
3510    case OP_EOD:    case OP_EOD:
3511    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3512      check_partial(common, FALSE);
3513    return cc;    return cc;
3514    
3515    case OP_CIRC:    case OP_CIRC:
3516    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3517    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3518    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0));
3519    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3520    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3521    return cc;    return cc;
3522    
3523    case OP_CIRCM:    case OP_CIRCM:
# Line 2957  switch(type) Line 3525  switch(type)
3525    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin));
3526    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
3527    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, notbol));
3528    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3529    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3530    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3531    
3532    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0));  
   
3533    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3534      {      {
3535      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3536      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3537      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3538      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3539      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3540      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3541      }      }
3542    else    else
3543      {      {
3544      skip_char_back(common);      skip_char_back(common);
3545      read_char(common);      read_char(common);
3546      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
3547      }      }
3548    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3549    return cc;    return cc;
# Line 2985  switch(type) Line 3551  switch(type)
3551    case OP_DOLL:    case OP_DOLL:
3552    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3553    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3554    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3555    
3556    if (!common->endonly)    if (!common->endonly)
3557      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_trypath(common, OP_EODN, cc, backtracks);
3558    else    else
3559      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      {
3560        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3561        check_partial(common, FALSE);
3562        }
3563    return cc;    return cc;
3564    
3565    case OP_DOLLM:    case OP_DOLLM:
3566    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3567    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3568    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3569    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3570      check_partial(common, FALSE);
3571    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3572    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3573    
3574    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3575      {      {
3576      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3577      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3578      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3579      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3580      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      else
3581      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));        {
3582          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3583          /* STR_PTR = STR_END - IN_UCHARS(1) */
3584          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3585          check_partial(common, TRUE);
3586          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3587          JUMPHERE(jump[1]);
3588          }
3589    
3590        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3591        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3592        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3593      }      }
3594    else    else
3595      {      {
3596      peek_char(common);      peek_char(common);
3597      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
3598      }      }
3599    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3600    return cc;    return cc;
# Line 3021  switch(type) Line 3602  switch(type)
3602    case OP_CHAR:    case OP_CHAR:
3603    case OP_CHARI:    case OP_CHARI:
3604    length = 1;    length = 1;
3605  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3606    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3607  #endif  #endif
3608    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
3609      {      {
3610      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3611      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3612    
3613      context.length = length;      context.length = IN_UCHARS(length);
3614      context.sourcereg = -1;      context.sourcereg = -1;
3615  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3616      context.byteptr = 0;      context.ucharptr = 0;
3617  #endif  #endif
3618      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks);
3619      }      }
3620    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    detect_partial_match(common, backtracks);
3621    read_char(common);    read_char(common);
3622  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3623    if (common->utf8)    if (common->utf)
3624      {      {
3625      GETCHAR(c, cc);      GETCHAR(c, cc);
3626      }      }
3627    else    else
3628  #endif  #endif
3629      c = *cc;      c = *cc;
3630      if (type == OP_CHAR || !char_has_othercase(common, cc))
3631        {
3632        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3633        return cc + length;
3634        }
3635      oc = char_othercase(common, c);
3636      bit = c ^ oc;
3637      if (ispowerof2(bit))
3638        {
3639        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3640        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3641        return cc + length;
3642        }
3643    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3644    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3645    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
3646    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3647    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3648    return cc + length;    return cc + length;
3649    
3650    case OP_NOT:    case OP_NOT:
3651    case OP_NOTI:    case OP_NOTI:
3652      detect_partial_match(common, backtracks);
3653    length = 1;    length = 1;
3654  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3655    if (common->utf8)    if (common->utf)
3656      {      {
3657      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3658        c = *cc;
3659      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3660        {        {
3661        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3662        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3663          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3664        else        else
3665          {          {
3666          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3667          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3668          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
3669          }          }
3670        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3671        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));
3672        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3673        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3674        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3675        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
3676        return cc + length;        return cc + 1;
3677        }        }
3678      else      else
3679    #endif /* COMPILE_PCRE8 */
3680          {
3681          GETCHARLEN(c, cc, length);
3682        read_char(common);        read_char(common);
3683          }
3684      }      }
3685    else    else
3686  #endif  #endif /* SUPPORT_UTF */
3687      {      {
3688      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      read_char(common);
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);  
3689      c = *cc;      c = *cc;
3690      }      }
3691    
3692    if (type == OP_NOT || !char_has_othercase(common, cc))    if (type == OP_NOT || !char_has_othercase(common, cc))
3693      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3694    else    else
3695      {      {
3696      oc = char_othercase(common, c);      oc = char_othercase(common, c);
# Line 3104  switch(type) Line 3698  switch(type)
3698      if (ispowerof2(bit))      if (ispowerof2(bit))
3699        {        {
3700        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3701        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3702        }        }
3703      else      else
3704        {        {
3705        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3706        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3707        }        }
3708      }      }
3709    return cc + length;    return cc + length;
3710    
3711    case OP_CLASS:    case OP_CLASS:
3712    case OP_NCLASS:    case OP_NCLASS:
3713    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3714    read_char(common);    read_char(common);
3715  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3716    jump[0] = NULL;    jump[0] = NULL;
3717    if (common->utf8)  #ifdef COMPILE_PCRE8
3718      /* This check only affects 8 bit mode. In other modes, we
3719      always need to compare the value with 255. */
3720      if (common->utf)
3721    #endif /* COMPILE_PCRE8 */
3722      {      {
3723      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3724      if (type == OP_CLASS)      if (type == OP_CLASS)
3725        {        {
3726        add_jump(compiler, fallbacks, jump[0]);        add_jump(compiler, backtracks, jump[0]);
3727        jump[0] = NULL;        jump[0] = NULL;
3728        }        }
3729      }      }
3730  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3731    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3732    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3733    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3734    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3735    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);
3736    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
3737  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3738    if (jump[0] != NULL)    if (jump[0] != NULL)
3739      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3740  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3741    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3742    
3743  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3744    case OP_XCLASS:    case OP_XCLASS:
3745    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_trypath(common, cc + LINK_SIZE, backtracks);
3746    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
3747  #endif  #endif
3748    
3749    case OP_REVERSE:    case OP_REVERSE:
3750    length = GET(cc, 0);    length = GET(cc, 0);
3751    SLJIT_ASSERT(length > 0);    if (length == 0)
3752        return cc + LINK_SIZE;
3753    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3754    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3755  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3756      {      {
3757        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3758      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3759      label = LABEL();      label = LABEL();
3760      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
3761      skip_char_back(common);      skip_char_back(common);
3762      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, 1);
3763      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3764      }      }
3765      else
3766  #endif  #endif
3767    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3768    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3769        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3770        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3771        }
3772      check_start_used_ptr(common);
3773    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3774    }    }
3775  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3776  return cc;  return cc;
3777  }  }
3778    
3779  static SLJIT_INLINE uschar *compile_charn_hotpath(compiler_common *common, uschar *cc, uschar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_trypath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **backtracks)
3780  {  {
3781  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3782  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
3783  DEFINE_COMPILER;  DEFINE_COMPILER;
3784  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3785  compare_context context;  compare_context context;
3786  int size;  int size;
3787    
# Line 3191  do Line 3794  do
3794    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3795      {      {
3796      size = 1;      size = 1;
3797  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3798      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3799        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3800  #endif  #endif
3801      }      }
3802    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3803      {      {
3804      size = 1;      size = 1;
3805  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3806      if (common->utf8)      if (common->utf)
3807        {        {
3808        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3809          size = 0;          size = 0;
3810        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3811          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3812        }        }
3813      else      else
3814  #endif  #endif
# Line 3216  do Line 3819  do
3819      size = 0;      size = 0;
3820    
3821    cc += 1 + size;    cc += 1 + size;
3822    context.length += size;    context.length += IN_UCHARS(size);
3823    }    }
3824  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3825    
# Line 3225  if (context.length > 0) Line 3828  if (context.length > 0)
3828    {    {
3829    /* We have a fixed-length byte sequence. */    /* We have a fixed-length byte sequence. */
3830    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, context.length);
3831    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3832    
3833    context.sourcereg = -1;    context.sourcereg = -1;
3834  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3835    context.byteptr = 0;    context.ucharptr = 0;
3836  #endif  #endif
3837    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, backtracks); while (context.length > 0);
3838    return cc;    return cc;
3839    }    }
3840    
3841  /* A non-fixed length character will be checked if length == 0. */  /* A non-fixed length character will be checked if length == 0. */
3842  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_trypath(common, *cc, cc + 1, backtracks);
3843  }  }
3844    
3845  static struct sljit_jump *compile_ref_checks(compiler_common *common, uschar *cc, jump_list **fallbacks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3846  {  {
3847  DEFINE_COMPILER;  DEFINE_COMPILER;
3848  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3247  int offset = GET2(cc, 1) << 1; Line 3850  int offset = GET2(cc, 1) << 1;
3850  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3851  if (!common->jscript_compat)  if (!common->jscript_compat)
3852    {    {
3853    if (fallbacks == NULL)    if (backtracks == NULL)
3854      {      {
3855        /* OVECTOR(1) contains the "string begin - 1" constant. */
3856      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3857      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3858      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3859      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3860      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
3861      }      }
3862    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3863    }    }
3864  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
3865  }  }
3866    
3867  /* Forward definitions. */  /* Forward definitions. */
3868  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_trypath(compiler_common *, pcre_uchar *, pcre_uchar *, backtrack_common *);
3869  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_backtrackpath(compiler_common *, struct backtrack_common *);
3870    
3871  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_BACKTRACK(size, ccstart, error) \
3872    do \    do \
3873      { \      { \
3874      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
3875      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3876        return error; \        return error; \
3877      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
3878      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
3879      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
3880      parent->top = fallback; \      parent->top = backtrack; \
3881      } \      } \
3882    while (0)    while (0)
3883    
3884  #define PUSH_FALLBACK_NOVALUE(size, ccstart) \  #define PUSH_BACKTRACK_NOVALUE(size, ccstart) \
3885    do \    do \
3886      { \      { \
3887      fallback = sljit_alloc_memory(compiler, (size)); \      backtrack = sljit_alloc_memory(compiler, (size)); \
3888      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) \
3889        return; \        return; \
3890      memset(fallback, 0, size); \      memset(backtrack, 0, size); \
3891      fallback->prev = parent->top; \      backtrack->prev = parent->top; \
3892      fallback->cc = (ccstart); \      backtrack->cc = (ccstart); \
3893      parent->top = fallback; \      parent->top = backtrack; \
3894      } \      } \
3895    while (0)    while (0)
3896    
3897  #define FALLBACK_AS(type) ((type*)fallback)  #define BACKTRACK_AS(type) ((type *)backtrack)
3898    
3899  static uschar *compile_ref_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_trypath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks, BOOL withchecks, BOOL emptyfail)
3900  {  {
3901  DEFINE_COMPILER;  DEFINE_COMPILER;
3902  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3903  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3904    struct sljit_jump *partial;
3905    struct sljit_jump *nopartial;
3906    
3907  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3908    /* OVECTOR(1) contains the "string begin - 1" constant. */
3909  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3910    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3911    
3912  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3913  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3914    {    {
3915    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
3916    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3314  if (common->utf8 && *cc == OP_REFI) Line 3920  if (common->utf8 && *cc == OP_REFI)
3920    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3921    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3922    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3923    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
3924    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf8caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3925    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3926    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3927        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3928      else
3929        {
3930        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3931        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3932        check_partial(common, FALSE);
3933        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3934        JUMPHERE(nopartial);
3935        }
3936    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3937    }    }
3938  else  else
3939  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3940    {    {
3941    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3942    if (withchecks)    if (withchecks)
3943      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3944    
3945    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3946      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3947      if (common->mode == JIT_COMPILE)
3948        add_jump(compiler, backtracks, partial);
3949    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3950    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3951    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3952    
3953      if (common->mode != JIT_COMPILE)
3954        {
3955        nopartial = JUMP(SLJIT_JUMP);
3956        JUMPHERE(partial);
3957        /* TMP2 -= STR_END - STR_PTR */
3958        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3959        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3960        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3961        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3962        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3963        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3964        JUMPHERE(partial);
3965        check_partial(common, FALSE);
3966        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
3967        JUMPHERE(nopartial);
3968        }
3969    }    }
3970    
3971  if (jump != NULL)  if (jump != NULL)
3972    {    {
3973    if (emptyfail)    if (emptyfail)
3974      add_jump(compiler, fallbacks, jump);      add_jump(compiler, backtracks, jump);
3975    else    else
3976      JUMPHERE(jump);      JUMPHERE(jump);
3977    }    }
3978  return cc + 3;  return cc + 1 + IMM2_SIZE;
3979  }  }
3980    
3981  static SLJIT_INLINE uschar *compile_ref_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
3982  {  {
3983  DEFINE_COMPILER;  DEFINE_COMPILER;
3984  fallback_common *fallback;  backtrack_common *backtrack;
3985  uschar type;  pcre_uchar type;
3986  struct sljit_label *label;  struct sljit_label *label;
3987  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3988  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3989  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3990  int min = 0, max = 0;  int min = 0, max = 0;
3991  BOOL minimize;  BOOL minimize;
3992    
3993  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(iterator_backtrack), cc, NULL);
3994    
3995  type = cc[3];  type = cc[1 + IMM2_SIZE];
3996  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3997  switch(type)  switch(type)
3998    {    {
# Line 3366  switch(type) Line 4000  switch(type)
4000    case OP_CRMINSTAR:    case OP_CRMINSTAR:
4001    min = 0;    min = 0;
4002    max = 0;    max = 0;
4003    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4004    break;    break;
4005    case OP_CRPLUS:    case OP_CRPLUS:
4006    case OP_CRMINPLUS:    case OP_CRMINPLUS:
4007    min = 1;    min = 1;
4008    max = 0;    max = 0;
4009    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4010    break;    break;
4011    case OP_CRQUERY:    case OP_CRQUERY:
4012    case OP_CRMINQUERY:    case OP_CRMINQUERY:
4013    min = 0;    min = 0;
4014    max = 1;    max = 1;
4015    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4016    break;    break;
4017    case OP_CRRANGE:    case OP_CRRANGE:
4018    case OP_CRMINRANGE:    case OP_CRMINRANGE:
4019    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
4020    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
4021    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
4022    break;    break;
4023    default:    default:
4024    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3408  if (!minimize) Line 4042  if (!minimize)
4042      {      {
4043      allocate_stack(common, 1);      allocate_stack(common, 1);
4044      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4045      zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);      zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4046      }      }
4047    
4048    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4049      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, 0);
4050    
4051    label = LABEL();    label = LABEL();
4052    compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, FALSE, FALSE);    compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, FALSE, FALSE);
4053    
4054    if (min > 1 || max > 1)    if (min > 1 || max > 1)
4055      {      {
# Line 3443  if (!minimize) Line 4077  if (!minimize)
4077      }      }
4078    
4079    JUMPHERE(zerolength);    JUMPHERE(zerolength);
4080    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4081    
4082    decrease_call_count(common);    decrease_call_count(common);
4083    return cc;    return cc;
# Line 3461  if (min == 0) Line 4095  if (min == 0)
4095    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4096    }    }
4097  else  else
4098    zerolength = compile_ref_checks(common, ccbegin, &fallback->topfallbacks);    zerolength = compile_ref_checks(common, ccbegin, &backtrack->topbacktracks);
4099    
4100  FALLBACK_AS(iterator_fallback)->hotpath = LABEL();  BACKTRACK_AS(iterator_backtrack)->trypath = LABEL();
4101  if (max > 0)  if (max > 0)
4102    add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));    add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, max));
4103    
4104  compile_ref_hotpath(common, ccbegin, &fallback->topfallbacks, TRUE, TRUE);  compile_ref_trypath(common, ccbegin, &backtrack->topbacktracks, TRUE, TRUE);
4105  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
4106    
4107  if (min > 1)  if (min > 1)
# Line 3475  if (min > 1) Line 4109  if (min > 1)
4109    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
4110    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4111    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4112    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, FALLBACK_AS(iterator_fallback)->hotpath);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, min, BACKTRACK_AS(iterator_backtrack)->trypath);
4113    }    }
4114  else if (max > 0)  else if (max > 0)
4115    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);    OP2(SLJIT_ADD, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 1);
# Line 3488  decrease_call_count(common); Line 4122  decrease_call_count(common);
4122  return cc;  return cc;
4123  }  }
4124    
4125  static SLJIT_INLINE uschar *compile_recurse_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_trypath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
4126  {  {
4127  DEFINE_COMPILER;  DEFINE_COMPILER;
4128  fallback_common *fallback;  backtrack_common *backtrack;
4129  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
4130  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
4131  int start = GET(cc, 1);  int start = GET(cc, 1);
4132    
4133  PUSH_FALLBACK(sizeof(recurse_fallback), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
4134  while (entry != NULL)  while (entry != NULL)
4135    {    {
4136    if (entry->start == start)    if (entry->start == start)
# Line 3521  if (entry == NULL) Line 4155  if (entry == NULL)
4155      common->entries = entry;      common->entries = entry;
4156    }    }
4157    
4158  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4159  allocate_stack(common, 1);    {
4160  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4161      allocate_stack(common, 2);
4162      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4163      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4164      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4165      }
4166    else if (common->has_set_som || common->mark_ptr != 0)
4167      {
4168      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (int)(OVECTOR(0)) : common->mark_ptr);
4169      allocate_stack(common, 1);
4170      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4171      }
4172    
4173  if (entry->entry == NULL)  if (entry->entry == NULL)
4174    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
4175  else  else
4176    JUMPTO(SLJIT_FAST_CALL, entry->entry);    JUMPTO(SLJIT_FAST_CALL, entry->entry);
4177  /* Leave if the match is failed. */  /* Leave if the match is failed. */
4178  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));  add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0));
4179  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4180  }  }
4181    
4182  static uschar *compile_assert_hotpath(compiler_common *common, uschar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_trypath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
4183  {  {
4184  DEFINE_COMPILER;  DEFINE_COMPILER;
4185  int framesize;  int framesize;
4186  int localptr;  int localptr;
4187  fallback_common altfallback;  backtrack_common altbacktrack;
4188  uschar *ccbegin;  pcre_uchar *ccbegin;
4189  uschar opcode;  pcre_uchar opcode;
4190  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4191  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4192  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
4193  jump_list **found;  jump_list **found;
4194  /* Saving previous accept variables. */  /* Saving previous accept variables. */
4195    struct sljit_label *save_leavelabel = common->leavelabel;
4196  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_acceptlabel = common->acceptlabel;
4197    jump_list *save_leave = common->leave;
4198    jump_list *save_accept = common->accept;
4199  struct sljit_jump *jump;  struct sljit_jump *jump;
4200  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
 jump_list *save_accept = common->accept;  
4201    
4202  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
4203    {    {
# Line 3558  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4205  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4205    bra = *cc;    bra = *cc;
4206    cc++;    cc++;
4207    }    }
4208  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4209  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4210  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4211  fallback->framesize = framesize;  backtrack->framesize = framesize;
4212  fallback->localptr = localptr;  backtrack->localptr = localptr;
4213  opcode = *cc;  opcode = *cc;
4214  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
4215  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 3571  cc += GET(cc, 1); Line 4218  cc += GET(cc, 1);
4218    
4219  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4220    {    {
4221    /* This is a braminzero fallback path. */    /* This is a braminzero backtrack path. */
4222    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4223    free_stack(common, 1);    free_stack(common, 1);
4224    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);    brajump = CMP(SLJIT_C_EQUAL, STR_PTR, 0, SLJIT_IMM, 0);
# Line 3594  else Line 4241  else
4241    init_frame(common, ccbegin, framesize + 1, 2, FALSE);    init_frame(common, ccbegin, framesize + 1, 2, FALSE);
4242    }    }
4243    
4244  memset(&altfallback, 0, sizeof(fallback_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
4245    common->leavelabel = NULL;
4246    common->leave = NULL;
4247  while (1)  while (1)
4248    {    {
4249    common->acceptlabel = NULL;    common->acceptlabel = NULL;
4250    common->accept = NULL;    common->accept = NULL;
4251    altfallback.top = NULL;    altbacktrack.top = NULL;
4252    altfallback.topfallbacks = NULL;    altbacktrack.topbacktracks = NULL;
4253    
4254    if (*ccbegin == OP_ALT)    if (*ccbegin == OP_ALT)
4255      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4256    
4257    altfallback.cc = ccbegin;    altbacktrack.cc = ccbegin;
4258    compile_hotpath(common, ccbegin + 1 + LINK_SIZE, cc, &altfallback);    compile_trypath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
4259    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
4260      {      {
4261        common->leavelabel = save_leavelabel;
4262      common->acceptlabel = save_acceptlabel;      common->acceptlabel = save