/[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 741 by zherczeg, Mon Oct 31 09:31:46 2011 UTC revision 987 by zherczeg, Sat Jul 7 04:11:29 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 60  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 80  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 106  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 146  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
160    uschar notbol;    pcre_uint8 notbol;
161    uschar noteol;    pcre_uint8 noteol;
162    uschar notempty;    pcre_uint8 notempty;
163    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    pcre_jit_callback callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171    } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 184  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 260  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 295  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 314  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 356  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 394  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 412  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 465  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 472  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 481  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 519  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 540  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 559  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 600  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)  #define CASE_ITERATOR_LOCAL1 \
671        case OP_MINSTAR: \
672        case OP_MINPLUS: \
673        case OP_QUERY: \
674        case OP_MINQUERY: \
675        case OP_MINSTARI: \
676        case OP_MINPLUSI: \
677        case OP_QUERYI: \
678        case OP_MINQUERYI: \
679        case OP_NOTMINSTAR: \
680        case OP_NOTMINPLUS: \
681        case OP_NOTQUERY: \
682        case OP_NOTMINQUERY: \
683        case OP_NOTMINSTARI: \
684        case OP_NOTMINPLUSI: \
685        case OP_NOTQUERYI: \
686        case OP_NOTMINQUERYI:
687    
688    #define CASE_ITERATOR_LOCAL2A \
689        case OP_STAR: \
690        case OP_PLUS: \
691        case OP_STARI: \
692        case OP_PLUSI: \
693        case OP_NOTSTAR: \
694        case OP_NOTPLUS: \
695        case OP_NOTSTARI: \
696        case OP_NOTPLUSI:
697    
698    #define CASE_ITERATOR_LOCAL2B \
699        case OP_UPTO: \
700        case OP_MINUPTO: \
701        case OP_UPTOI: \
702        case OP_MINUPTOI: \
703        case OP_NOTUPTO: \
704        case OP_NOTMINUPTO: \
705        case OP_NOTUPTOI: \
706        case OP_NOTMINUPTOI:
707    
708    #define CASE_ITERATOR_TYPE_LOCAL1 \
709        case OP_TYPEMINSTAR: \
710        case OP_TYPEMINPLUS: \
711        case OP_TYPEQUERY: \
712        case OP_TYPEMINQUERY:
713    
714    #define CASE_ITERATOR_TYPE_LOCAL2A \
715        case OP_TYPESTAR: \
716        case OP_TYPEPLUS:
717    
718    #define CASE_ITERATOR_TYPE_LOCAL2B \
719        case OP_TYPEUPTO: \
720        case OP_TYPEMINUPTO:
721    
722    static int get_class_iterator_size(pcre_uchar *cc)
723    {
724    switch(*cc)
725      {
726      case OP_CRSTAR:
727      case OP_CRPLUS:
728      return 2;
729    
730      case OP_CRMINSTAR:
731      case OP_CRMINPLUS:
732      case OP_CRQUERY:
733      case OP_CRMINQUERY:
734      return 1;
735    
736      case OP_CRRANGE:
737      case OP_CRMINRANGE:
738      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
739        return 0;
740      return 2;
741    
742      default:
743      return 0;
744      }
745    }
746    
747    static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
748  {  {
749  int localspace = 0;  int localspace = 0;
750  uschar *alternative;  pcre_uchar *alternative;
751    pcre_uchar *end = NULL;
752    int space, size, bracketlen;
753    
754  /* 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. */
755  while (cc < ccend)  while (cc < ccend)
756    {    {
757      space = 0;
758      size = 0;
759      bracketlen = 0;
760    switch(*cc)    switch(*cc)
761      {      {
762        case OP_SET_SOM:
763        common->has_set_som = TRUE;
764        cc += 1;
765        break;
766    
767      case OP_ASSERT:      case OP_ASSERT:
768      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
769      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 627  while (cc < ccend) Line 775  while (cc < ccend)
775      case OP_SBRAPOS:      case OP_SBRAPOS:
776      case OP_SCOND:      case OP_SCOND:
777      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
778      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
779      break;      break;
780    
781      case OP_CBRAPOS:      case OP_CBRAPOS:
782      case OP_SCBRAPOS:      case OP_SCBRAPOS:
783      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
784      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
785      break;      break;
786    
787      case OP_COND:      case OP_COND:
# Line 641  while (cc < ccend) Line 789  while (cc < ccend)
789      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
790      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
791        localspace += sizeof(sljit_w);        localspace += sizeof(sljit_w);
792        bracketlen = 1 + LINK_SIZE;
793        break;
794    
795        case OP_BRA:
796        bracketlen = 1 + LINK_SIZE;
797        break;
798    
799        case OP_CBRA:
800        case OP_SCBRA:
801        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
802        break;
803    
804        CASE_ITERATOR_LOCAL1
805        space = 1;
806        size = -2;
807        break;
808    
809        CASE_ITERATOR_LOCAL2A
810        space = 2;
811        size = -2;
812        break;
813    
814        CASE_ITERATOR_LOCAL2B
815        space = 2;
816        size = -(2 + IMM2_SIZE);
817        break;
818    
819        CASE_ITERATOR_TYPE_LOCAL1
820        space = 1;
821        size = 1;
822        break;
823    
824        CASE_ITERATOR_TYPE_LOCAL2A
825        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
826          space = 2;
827        size = 1;
828        break;
829    
830        CASE_ITERATOR_TYPE_LOCAL2B
831        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
832          space = 2;
833        size = 1 + IMM2_SIZE;
834        break;
835    
836        case OP_CLASS:
837        case OP_NCLASS:
838        size += 1 + 32 / sizeof(pcre_uchar);
839        space = get_class_iterator_size(cc + size);
840        break;
841    
842    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
843        case OP_XCLASS:
844        size = GET(cc, 1);
845        space = get_class_iterator_size(cc + size);
846        break;
847    #endif
848    
849        case OP_RECURSE:
850        /* Set its value only once. */
851        if (common->recursive_head == 0)
852          {
853          common->recursive_head = common->ovector_start;
854          common->ovector_start += sizeof(sljit_w);
855          }
856      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
857      break;      break;
858    
859        case OP_MARK:
860        if (common->mark_ptr == 0)
861          {
862          common->mark_ptr = common->ovector_start;
863          common->ovector_start += sizeof(sljit_w);
864          }
865        cc += 1 + 2 + cc[1];
866        break;
867    
868      default:      default:
869      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
870      if (cc == NULL)      if (cc == NULL)
871        return -1;        return -1;
872      break;      break;
873      }      }
874    
875      if (space > 0 && cc >= end)
876        localspace += sizeof(sljit_w) * space;
877    
878      if (size != 0)
879        {
880        if (size < 0)
881          {
882          cc += -size;
883    #ifdef SUPPORT_UTF
884          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
885    #endif
886          }
887        else
888          cc += size;
889        }
890    
891      if (bracketlen > 0)
892        {
893        if (cc >= end)
894          {
895          end = bracketend(cc);
896          if (end[-1 - LINK_SIZE] == OP_KET)
897            end = NULL;
898          }
899        cc += bracketlen;
900        }
901    }    }
902  return localspace;  return localspace;
903  }  }
904    
905  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
906  {  {
907  uschar *cc = common->start;  pcre_uchar *cc = common->start;
908  uschar *alternative;  pcre_uchar *alternative;
909    pcre_uchar *end = NULL;
910    int space, size, bracketlen;
911    
912  while (cc < ccend)  while (cc < ccend)
913    {    {
914      space = 0;
915      size = 0;
916      bracketlen = 0;
917    switch(*cc)    switch(*cc)
918      {      {
919      case OP_ASSERT:      case OP_ASSERT:
# Line 674  while (cc < ccend) Line 928  while (cc < ccend)
928      case OP_SCOND:      case OP_SCOND:
929      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
930      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
931      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
932      break;      break;
933    
934      case OP_CBRAPOS:      case OP_CBRAPOS:
935      case OP_SCBRAPOS:      case OP_SCBRAPOS:
936      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
937      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
938      cc += 1 + LINK_SIZE + 2;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
939      break;      break;
940    
941      case OP_COND:      case OP_COND:
# Line 692  while (cc < ccend) Line 946  while (cc < ccend)
946        common->localptrs[cc - common->start] = localptr;        common->localptrs[cc - common->start] = localptr;
947        localptr += sizeof(sljit_w);        localptr += sizeof(sljit_w);
948        }        }
949      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
950        break;
951    
952        case OP_BRA:
953        bracketlen = 1 + LINK_SIZE;
954        break;
955    
956        case OP_CBRA:
957        case OP_SCBRA:
958        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
959        break;
960    
961        CASE_ITERATOR_LOCAL1
962        space = 1;
963        size = -2;
964        break;
965    
966        CASE_ITERATOR_LOCAL2A
967        space = 2;
968        size = -2;
969        break;
970    
971        CASE_ITERATOR_LOCAL2B
972        space = 2;
973        size = -(2 + IMM2_SIZE);
974        break;
975    
976        CASE_ITERATOR_TYPE_LOCAL1
977        space = 1;
978        size = 1;
979      break;      break;
980    
981        CASE_ITERATOR_TYPE_LOCAL2A
982        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
983          space = 2;
984        size = 1;
985        break;
986    
987        CASE_ITERATOR_TYPE_LOCAL2B
988        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
989          space = 2;
990        size = 1 + IMM2_SIZE;
991        break;
992    
993        case OP_CLASS:
994        case OP_NCLASS:
995        size += 1 + 32 / sizeof(pcre_uchar);
996        space = get_class_iterator_size(cc + size);
997        break;
998    
999    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1000        case OP_XCLASS:
1001        size = GET(cc, 1);
1002        space = get_class_iterator_size(cc + size);
1003        break;
1004    #endif
1005    
1006      default:      default:
1007      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1008      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1009      break;      break;
1010      }      }
1011    
1012      if (space > 0 && cc >= end)
1013        {
1014        common->localptrs[cc - common->start] = localptr;
1015        localptr += sizeof(sljit_w) * space;
1016        }
1017    
1018      if (size != 0)
1019        {
1020        if (size < 0)
1021          {
1022          cc += -size;
1023    #ifdef SUPPORT_UTF
1024          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1025    #endif
1026          }
1027        else
1028          cc += size;
1029        }
1030    
1031      if (bracketlen > 0)
1032        {
1033        if (cc >= end)
1034          {
1035          end = bracketend(cc);
1036          if (end[-1 - LINK_SIZE] == OP_KET)
1037            end = NULL;
1038          }
1039        cc += bracketlen;
1040        }
1041    }    }
1042  }  }
1043    
1044  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
1045  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
1046  {  {
1047  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1048  int length = 0;  int length = 0;
1049  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1050  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1051    BOOL setmark_found = recursive;
1052    
1053  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1054    {    {
# Line 723  while (cc < ccend) Line 1062  while (cc < ccend)
1062    switch(*cc)    switch(*cc)
1063      {      {
1064      case OP_SET_SOM:      case OP_SET_SOM:
1065      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1066      if (!setsom_found)      if (!setsom_found)
1067        {        {
1068        length += 2;        length += 2;
1069        setsom_found = TRUE;        setsom_found = TRUE;
1070        }        }
1071      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1072        break;
1073    
1074        case OP_MARK:
1075        SLJIT_ASSERT(common->mark_ptr != 0);
1076        if (!setmark_found)
1077          {
1078          length += 2;
1079          setmark_found = TRUE;
1080          }
1081        cc += 1 + 2 + cc[1];
1082        break;
1083    
1084        case OP_RECURSE:
1085        if (common->has_set_som && !setsom_found)
1086          {
1087          length += 2;
1088          setsom_found = TRUE;
1089          }
1090        if (common->mark_ptr != 0 && !setmark_found)
1091          {
1092          length += 2;
1093          setmark_found = TRUE;
1094          }
1095        cc += 1 + LINK_SIZE;
1096      break;      break;
1097    
1098      case OP_CBRA:      case OP_CBRA:
# Line 737  while (cc < ccend) Line 1100  while (cc < ccend)
1100      case OP_SCBRA:      case OP_SCBRA:
1101      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1102      length += 3;      length += 3;
1103      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1104      break;      break;
1105    
1106      default:      default:
# Line 755  if (length > 0) Line 1118  if (length > 0)
1118  return -1;  return -1;
1119  }  }
1120    
1121  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)
1122  {  {
1123  DEFINE_COMPILER;  DEFINE_COMPILER;
1124  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1125  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1126    BOOL setmark_found = recursive;
1127  int offset;  int offset;
1128    
1129  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1130    SLJIT_UNUSED_ARG(stacktop);
1131  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1132    
1133  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 773  while (cc < ccend) Line 1138  while (cc < ccend)
1138    switch(*cc)    switch(*cc)
1139      {      {
1140      case OP_SET_SOM:      case OP_SET_SOM:
1141      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1142      if (!setsom_found)      if (!setsom_found)
1143        {        {
1144        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 783  while (cc < ccend) Line 1148  while (cc < ccend)
1148        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1149        setsom_found = TRUE;        setsom_found = TRUE;
1150        }        }
1151      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1152        break;
1153    
1154        case OP_MARK:
1155        SLJIT_ASSERT(common->mark_ptr != 0);
1156        if (!setmark_found)
1157          {
1158          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1159          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1160          stackpos += (int)sizeof(sljit_w);
1161          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1162          stackpos += (int)sizeof(sljit_w);
1163          setmark_found = TRUE;
1164          }
1165        cc += 1 + 2 + cc[1];
1166        break;
1167    
1168        case OP_RECURSE:
1169        if (common->has_set_som && !setsom_found)
1170          {
1171          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1172          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1173          stackpos += (int)sizeof(sljit_w);
1174          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1175          stackpos += (int)sizeof(sljit_w);
1176          setsom_found = TRUE;
1177          }
1178        if (common->mark_ptr != 0 && !setmark_found)
1179          {
1180          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1181          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1182          stackpos += (int)sizeof(sljit_w);
1183          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1184          stackpos += (int)sizeof(sljit_w);
1185          setmark_found = TRUE;
1186          }
1187        cc += 1 + LINK_SIZE;
1188      break;      break;
1189    
1190      case OP_CBRA:      case OP_CBRA:
# Line 800  while (cc < ccend) Line 1201  while (cc < ccend)
1201      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1202      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
1203    
1204      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1205      break;      break;
1206    
1207      default:      default:
# Line 813  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1214  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1214  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1215  }  }
1216    
1217  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)
1218  {  {
1219  int localsize = 2;  int localsize = 2;
1220  uschar *alternative;  int size;
1221    pcre_uchar *alternative;
1222  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
1223  while (cc < ccend)  while (cc < ccend)
1224    {    {
1225      size = 0;
1226    switch(*cc)    switch(*cc)
1227      {      {
1228      case OP_ASSERT:      case OP_ASSERT:
# Line 839  while (cc < ccend) Line 1242  while (cc < ccend)
1242      case OP_CBRA:      case OP_CBRA:
1243      case OP_SCBRA:      case OP_SCBRA:
1244      localsize++;      localsize++;
1245      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1246      break;      break;
1247    
1248      case OP_CBRAPOS:      case OP_CBRAPOS:
1249      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1250      localsize += 2;      localsize += 2;
1251      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1252      break;      break;
1253    
1254      case OP_COND:      case OP_COND:
# Line 856  while (cc < ccend) Line 1259  while (cc < ccend)
1259      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1260      break;      break;
1261    
1262        CASE_ITERATOR_LOCAL1
1263        if (PRIV_DATA(cc))
1264          localsize++;
1265        cc += 2;
1266    #ifdef SUPPORT_UTF
1267        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1268    #endif
1269        break;
1270    
1271        CASE_ITERATOR_LOCAL2A
1272        if (PRIV_DATA(cc))
1273          localsize += 2;
1274        cc += 2;
1275    #ifdef SUPPORT_UTF
1276        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1277    #endif
1278        break;
1279    
1280        CASE_ITERATOR_LOCAL2B
1281        if (PRIV_DATA(cc))
1282          localsize += 2;
1283        cc += 2 + IMM2_SIZE;
1284    #ifdef SUPPORT_UTF
1285        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1286    #endif
1287        break;
1288    
1289        CASE_ITERATOR_TYPE_LOCAL1
1290        if (PRIV_DATA(cc))
1291          localsize++;
1292        cc += 1;
1293        break;
1294    
1295        CASE_ITERATOR_TYPE_LOCAL2A
1296        if (PRIV_DATA(cc))
1297          localsize += 2;
1298        cc += 1;
1299        break;
1300    
1301        CASE_ITERATOR_TYPE_LOCAL2B
1302        if (PRIV_DATA(cc))
1303          localsize += 2;
1304        cc += 1 + IMM2_SIZE;
1305        break;
1306    
1307        case OP_CLASS:
1308        case OP_NCLASS:
1309    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1310        case OP_XCLASS:
1311        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / sizeof(pcre_uchar);
1312    #else
1313        size = 1 + 32 / sizeof(pcre_uchar);
1314    #endif
1315        if (PRIV_DATA(cc))
1316          localsize += get_class_iterator_size(cc + size);
1317        cc += size;
1318        break;
1319    
1320      default:      default:
1321      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1322      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 866  SLJIT_ASSERT(cc == ccend); Line 1327  SLJIT_ASSERT(cc == ccend);
1327  return localsize;  return localsize;
1328  }  }
1329    
1330  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1331    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1332  {  {
1333  DEFINE_COMPILER;  DEFINE_COMPILER;
1334  int srcw[2];  int srcw[2];
1335  int count;  int count, size;
1336  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1337  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1338  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1339  uschar *alternative;  pcre_uchar *alternative;
1340  enum {  enum {
1341    start,    start,
1342    loop,    loop,
# Line 910  while (status != end) Line 1371  while (status != end)
1371    switch(status)    switch(status)
1372      {      {
1373      case start:      case start:
1374      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1375      count = 1;      count = 1;
1376      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1377      status = loop;      status = loop;
1378      break;      break;
1379    
# Line 936  while (status != end) Line 1397  while (status != end)
1397        case OP_SBRAPOS:        case OP_SBRAPOS:
1398        case OP_SCOND:        case OP_SCOND:
1399        count = 1;        count = 1;
1400        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1401        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1402        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1403        break;        break;
# Line 945  while (status != end) Line 1406  while (status != end)
1406        case OP_SCBRA:        case OP_SCBRA:
1407        count = 1;        count = 1;
1408        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1409        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1410        break;        break;
1411    
1412        case OP_CBRAPOS:        case OP_CBRAPOS:
1413        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1414        count = 2;        count = 2;
1415        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1416        srcw[0] = PRIV(cc);        srcw[1] = PRIV_DATA(cc);
1417        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1418        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1419        break;        break;
1420    
1421        case OP_COND:        case OP_COND:
# Line 963  while (status != end) Line 1424  while (status != end)
1424        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1425          {          {
1426          count = 1;          count = 1;
1427          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1428          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1429          }          }
1430        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1431        break;        break;
1432    
1433          CASE_ITERATOR_LOCAL1
1434          if (PRIV_DATA(cc))
1435            {
1436            count = 1;
1437            srcw[0] = PRIV_DATA(cc);
1438            }
1439          cc += 2;
1440    #ifdef SUPPORT_UTF
1441          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1442    #endif
1443          break;
1444    
1445          CASE_ITERATOR_LOCAL2A
1446          if (PRIV_DATA(cc))
1447            {
1448            count = 2;
1449            srcw[0] = PRIV_DATA(cc);
1450            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1451            }
1452          cc += 2;
1453    #ifdef SUPPORT_UTF
1454          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1455    #endif
1456          break;
1457    
1458          CASE_ITERATOR_LOCAL2B
1459          if (PRIV_DATA(cc))
1460            {
1461            count = 2;
1462            srcw[0] = PRIV_DATA(cc);
1463            srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);
1464            }
1465          cc += 2 + IMM2_SIZE;
1466    #ifdef SUPPORT_UTF
1467          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1468    #endif
1469          break;
1470    
1471          CASE_ITERATOR_TYPE_LOCAL1
1472          if (PRIV_DATA(cc))
1473            {
1474            count = 1;
1475            srcw[0] = PRIV_DATA(cc);
1476            }
1477          cc += 1;
1478          break;
1479    
1480          CASE_ITERATOR_TYPE_LOCAL2A
1481          if (PRIV_DATA(cc))
1482            {
1483            count = 2;
1484            srcw[0] = PRIV_DATA(cc);
1485            srcw[1] = srcw[0] + sizeof(sljit_w);
1486            }
1487          cc += 1;
1488          break;
1489    
1490          CASE_ITERATOR_TYPE_LOCAL2B
1491          if (PRIV_DATA(cc))
1492            {
1493            count = 2;
1494            srcw[0] = PRIV_DATA(cc);
1495            srcw[1] = srcw[0] + sizeof(sljit_w);
1496            }
1497          cc += 1 + IMM2_SIZE;
1498          break;
1499    
1500          case OP_CLASS:
1501          case OP_NCLASS:
1502    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1503          case OP_XCLASS:
1504          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / sizeof(pcre_uchar);
1505    #else
1506          size = 1 + 32 / sizeof(pcre_uchar);
1507    #endif
1508          if (PRIV_DATA(cc))
1509            switch(get_class_iterator_size(cc + size))
1510              {
1511              case 1:
1512              count = 1;
1513              srcw[0] = PRIV_DATA(cc);
1514              break;
1515    
1516              case 2:
1517              count = 2;
1518              srcw[0] = PRIV_DATA(cc);
1519              srcw[1] = srcw[0] + sizeof(sljit_w);
1520              break;
1521    
1522              default:
1523              SLJIT_ASSERT_STOP();
1524              break;
1525              }
1526          cc += size;
1527          break;
1528    
1529        default:        default:
1530        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1531        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1071  if (save) Line 1628  if (save)
1628  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1629  }  }
1630    
1631    #undef CASE_ITERATOR_LOCAL1
1632    #undef CASE_ITERATOR_LOCAL2A
1633    #undef CASE_ITERATOR_LOCAL2B
1634    #undef CASE_ITERATOR_TYPE_LOCAL1
1635    #undef CASE_ITERATOR_TYPE_LOCAL2A
1636    #undef CASE_ITERATOR_TYPE_LOCAL2B
1637    
1638  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)
1639  {  {
1640  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
# Line 1171  struct sljit_label *loop; Line 1735  struct sljit_label *loop;
1735  int i;  int i;
1736  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1737  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1738  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));
1739  if (length < 8)  if (length < 8)
1740    {    {
1741    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1179  if (length < 8) Line 1743  if (length < 8)
1743    }    }
1744  else  else
1745    {    {
1746    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));
1747    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);
1748    loop = LABEL();    loop = LABEL();
1749    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 1195  struct sljit_label *loop; Line 1759  struct sljit_label *loop;
1759  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1760    
1761  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1762  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));
1763  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);
1764    
1765  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1766    if (common->mark_ptr != 0)
1767      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1768  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));
1769    if (common->mark_ptr != 0)
1770      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1771  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));
1772  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));
1773  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1774  /* Unlikely, but possible */  /* Unlikely, but possible */
1775  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1776  loop = LABEL();  loop = LABEL();
1777  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);
1778  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));
1779  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1780  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1781    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1782    #endif
1783    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1784  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);
1785  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1786  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1217  JUMPHERE(earlyexit); Line 1788  JUMPHERE(earlyexit);
1788  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1789  if (topbracket > 1)  if (topbracket > 1)
1790    {    {
1791    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));
1792    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1793    
1794    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1795    loop = LABEL();    loop = LABEL();
1796    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)));
1797    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);
1798    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);
1799    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1800    }    }
1801  else  else
1802    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1803    }
1804    
1805    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1806    {
1807    DEFINE_COMPILER;
1808    
1809    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1810    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1811    
1812    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1813    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1814    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1815    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1816    
1817    /* Store match begin and end. */
1818    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1819    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1820    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);
1821    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1822    #ifdef COMPILE_PCRE16
1823    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1824    #endif
1825    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1826    
1827    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1828    #ifdef COMPILE_PCRE16
1829    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1830    #endif
1831    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1832    
1833    JUMPTO(SLJIT_JUMP, leave);
1834    }
1835    
1836    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1837    {
1838    /* May destroy TMP1. */
1839    DEFINE_COMPILER;
1840    struct sljit_jump *jump;
1841    
1842    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1843      {
1844      /* The value of -1 must be kept for start_used_ptr! */
1845      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1846      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1847      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1848      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1849      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1850      JUMPHERE(jump);
1851      }
1852    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1853      {
1854      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1855      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1856      JUMPHERE(jump);
1857      }
1858  }  }
1859    
1860  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1861  {  {
1862  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1863  unsigned int c;  unsigned int c;
1864    
1865  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1866  if (common->utf8)  if (common->utf)
1867    {    {
1868    GETCHAR(c, cc);    GETCHAR(c, cc);
1869    if (c > 127)    if (c > 127)
# Line 1248  if (common->utf8) Line 1874  if (common->utf8)
1874      return FALSE;      return FALSE;
1875  #endif  #endif
1876      }      }
1877    #ifndef COMPILE_PCRE8
1878      return common->fcc[c] != c;
1879    #endif
1880    }    }
1881  else  else
1882  #endif  #endif
1883    c = *cc;    c = *cc;
1884  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1885  }  }
1886    
1887  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)
1888  {  {
1889  /* Returns with the othercase. */  /* Returns with the othercase. */
1890  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1891  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1892    {    {
1893  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1894    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1268  if (common->utf8 && c > 127) Line 1897  if (common->utf8 && c > 127)
1897  #endif  #endif
1898    }    }
1899  #endif  #endif
1900  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1901  }  }
1902    
1903  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)
1904  {  {
1905  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1906  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1907  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1908  int n;  int n;
1909  #endif  #endif
1910    
1911  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1912  if (common->utf8)  if (common->utf)
1913    {    {
1914    GETCHAR(c, cc);    GETCHAR(c, cc);
1915    if (c <= 127)    if (c <= 127)
# Line 1297  if (common->utf8) Line 1926  if (common->utf8)
1926  else  else
1927    {    {
1928    c = *cc;    c = *cc;
1929    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1930    }    }
1931  #else  #else
1932  c = *cc;  c = *cc;
1933  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1934  #endif  #endif
1935    
1936  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1315  if (c <= 127 && bit == 0x20) Line 1944  if (c <= 127 && bit == 0x20)
1944  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1945    return 0;    return 0;
1946    
1947  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1948  if (common->utf8 && c > 127)  
1949    #ifdef SUPPORT_UTF
1950    if (common->utf && c > 127)
1951    {    {
1952    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1953    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1954      {      {
1955      n--;      n--;
# Line 1326  if (common->utf8 && c > 127) Line 1957  if (common->utf8 && c > 127)
1957      }      }
1958    return (n << 8) | bit;    return (n << 8) | bit;
1959    }    }
1960  #endif  #endif /* SUPPORT_UTF */
1961  return (0 << 8) | bit;  return (0 << 8) | bit;
1962    
1963    #else /* COMPILE_PCRE8 */
1964    
1965    #ifdef COMPILE_PCRE16
1966    #ifdef SUPPORT_UTF
1967    if (common->utf && c > 65535)
1968      {
1969      if (bit >= (1 << 10))
1970        bit >>= 10;
1971      else
1972        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1973      }
1974    #endif /* SUPPORT_UTF */
1975    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1976    #endif /* COMPILE_PCRE16 */
1977    
1978    #endif /* COMPILE_PCRE8 */
1979    }
1980    
1981    static void check_partial(compiler_common *common, BOOL force)
1982    {
1983    /* Checks whether a partial matching is occured. Does not modify registers. */
1984    DEFINE_COMPILER;
1985    struct sljit_jump *jump = NULL;
1986    
1987    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1988    
1989    if (common->mode == JIT_COMPILE)
1990      return;
1991    
1992    if (!force)
1993      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1994    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1995      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1996    
1997    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1998      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1999    else
2000      {
2001      if (common->partialmatchlabel != NULL)
2002        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2003      else
2004        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2005      }
2006    
2007    if (jump != NULL)
2008      JUMPHERE(jump);
2009    }
2010    
2011    static struct sljit_jump *check_str_end(compiler_common *common)
2012    {
2013    /* Does not affect registers. Usually used in a tight spot. */
2014    DEFINE_COMPILER;
2015    struct sljit_jump *jump;
2016    struct sljit_jump *nohit;
2017    struct sljit_jump *return_value;
2018    
2019    if (common->mode == JIT_COMPILE)
2020      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2021    
2022    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2023    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2024      {
2025      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2026      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2027      JUMPHERE(nohit);
2028      return_value = JUMP(SLJIT_JUMP);
2029      }
2030    else
2031      {
2032      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2033      if (common->partialmatchlabel != NULL)
2034        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2035      else
2036        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2037      }
2038    JUMPHERE(jump);
2039    return return_value;
2040  }  }
2041    
2042  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2043  {  {
2044  DEFINE_COMPILER;  DEFINE_COMPILER;
2045  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
2046    
2047    if (common->mode == JIT_COMPILE)
2048      {
2049      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2050      return;
2051      }
2052    
2053    /* Partial matching mode. */
2054    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2055    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2056    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2057      {
2058      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2059      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2060      }
2061    else
2062      {
2063      if (common->partialmatchlabel != NULL)
2064        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2065      else
2066        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2067      }
2068    JUMPHERE(jump);
2069  }  }
2070    
2071  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1341  static void read_char(compiler_common *c Line 2073  static void read_char(compiler_common *c
2073  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2074  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2075  DEFINE_COMPILER;  DEFINE_COMPILER;
2076  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2077  struct sljit_jump *jump;  struct sljit_jump *jump;
2078  #endif  #endif
2079    
2080  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2081  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2082  if (common->utf8)  if (common->utf)
2083    {    {
2084    #ifdef COMPILE_PCRE8
2085    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2086    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2087    #ifdef COMPILE_PCRE16
2088      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2089    #endif
2090    #endif /* COMPILE_PCRE8 */
2091      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2092    JUMPHERE(jump);    JUMPHERE(jump);
2093    }    }
2094  #endif  #endif
2095  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));
2096  }  }
2097    
2098  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1362  static void peek_char(compiler_common *c Line 2100  static void peek_char(compiler_common *c
2100  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2101  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2102  DEFINE_COMPILER;  DEFINE_COMPILER;
2103  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2104  struct sljit_jump *jump;  struct sljit_jump *jump;
2105  #endif  #endif
2106    
2107  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2108  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2109  if (common->utf8)  if (common->utf)
2110    {    {
2111    #ifdef COMPILE_PCRE8
2112    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2113    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
2114    #ifdef COMPILE_PCRE16
2115      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2116    #endif
2117    #endif /* COMPILE_PCRE8 */
2118      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2119    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2120    JUMPHERE(jump);    JUMPHERE(jump);
2121    }    }
# Line 1382  static void read_char8_type(compiler_com Line 2126  static void read_char8_type(compiler_com
2126  {  {
2127  /* 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. */
2128  DEFINE_COMPILER;  DEFINE_COMPILER;
2129  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2130  struct sljit_jump *jump;  struct sljit_jump *jump;
2131  #endif  #endif
2132    
2133  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2134  if (common->utf8)  if (common->utf)
2135    {    {
2136    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2137    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));
2138    #ifdef COMPILE_PCRE8
2139    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2140    it is a clever early read in most cases. */    it is needed in most cases. */
2141    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2142    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2143    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2144    JUMPHERE(jump);    JUMPHERE(jump);
2145    #else
2146    #ifdef COMPILE_PCRE16
2147      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2148      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2149      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2150      JUMPHERE(jump);
2151      /* Skip low surrogate if necessary. */
2152      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2153      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2154      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2155      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2156      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2157    #endif
2158    #endif /* COMPILE_PCRE8 */
2159    return;    return;
2160    }    }
2161  #endif  #endif
2162  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2163  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));
2164  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
2165    /* The ctypes array contains only 256 values. */
2166    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2167    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2168    #endif
2169    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2170    #ifdef COMPILE_PCRE16
2171    JUMPHERE(jump);
2172    #endif
2173  }  }
2174    
2175  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
2176  {  {
2177  /* 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. */
2178  DEFINE_COMPILER;  DEFINE_COMPILER;
2179  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2180  struct sljit_label *label;  struct sljit_label *label;
2181    
2182  if (common->utf8)  if (common->utf)
2183    {    {
2184    label = LABEL();    label = LABEL();
2185    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2186    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));
2187    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
2188    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2189    return;    return;
2190    }    }
2191  #endif  #endif
2192  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2193    if (common->utf)
2194      {
2195      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
2196      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2197      /* Skip low surrogate if necessary. */
2198      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2199      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2200      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2201      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2202      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2203      return;
2204      }
2205    #endif
2206    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2207  }  }
2208    
2209  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)
2210  {  {
2211  /* 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. */
2212  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1433  DEFINE_COMPILER; Line 2214  DEFINE_COMPILER;
2214  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2215    {    {
2216    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2217    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));
2218    }    }
2219  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2220    {    {
# Line 1441  else if (nltype == NLTYPE_ANYCRLF) Line 2222  else if (nltype == NLTYPE_ANYCRLF)
2222    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2223    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);
2224    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2225    add_jump(compiler, fallbacks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2226    }    }
2227  else  else
2228    {    {
2229    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2230    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));
2231    }    }
2232  }  }
2233    
2234  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2235  static void do_utf8readchar(compiler_common *common)  
2236    #ifdef COMPILE_PCRE8
2237    static void do_utfreadchar(compiler_common *common)
2238  {  {
2239  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
2240  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. */
2241  DEFINE_COMPILER;  DEFINE_COMPILER;
2242  struct sljit_jump *jump;  struct sljit_jump *jump;
2243    
2244  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2245  /* Searching for the first zero. */  /* Searching for the first zero. */
2246  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);
2247  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2248  /* 2 byte sequence */  /* Two byte sequence. */
2249  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2250  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));
2251  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
2252  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
2253  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2254  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2255  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2256  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2257  JUMPHERE(jump);  JUMPHERE(jump);
2258    
2259  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);
2260  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2261  /* 3 byte sequence */  /* Three byte sequence. */
2262  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2263  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
2264  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
2265  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2266  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2267  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2268  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
2269  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));
2270  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2271  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2272  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
2273  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2274  JUMPHERE(jump);  JUMPHERE(jump);
2275    
2276  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
2277  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);  
2278  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
2279  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
2280  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2281  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
2282  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2283  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);  
2284  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2285  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2286  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2287  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
2288  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));
2289  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
2290  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2291  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
2292  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2293  }  }
2294    
2295  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
2296  {  {
2297  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
2298  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
2299  DEFINE_COMPILER;  DEFINE_COMPILER;
2300  struct sljit_jump *jump;  struct sljit_jump *jump;
2301  struct sljit_jump *compare;  struct sljit_jump *compare;
2302    
2303  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2304    
2305  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);
2306  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
2307  /* 2 byte sequence */  /* Two byte sequence. */
2308  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2309  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));
2310  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
2311  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
2312  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1563  sljit_emit_fast_return(compiler, RETURN_ Line 2321  sljit_emit_fast_return(compiler, RETURN_
2321  JUMPHERE(jump);  JUMPHERE(jump);
2322    
2323  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2324  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);
2325  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2326  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2327  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2328  }  }
2329    
2330  #endif  #else /* COMPILE_PCRE8 */
2331    
2332    #ifdef COMPILE_PCRE16
2333    static void do_utfreadchar(compiler_common *common)
2334    {
2335    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
2336    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
2337    DEFINE_COMPILER;
2338    struct sljit_jump *jump;
2339    
2340    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2341    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2342    /* Do nothing, only return. */
2343    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2344    
2345    JUMPHERE(jump);
2346    /* Combine two 16 bit characters. */
2347    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2348    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2349    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
2350    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
2351    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
2352    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2353    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2354    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2355    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2356    }
2357    #endif /* COMPILE_PCRE16 */
2358    
2359    #endif /* COMPILE_PCRE8 */
2360    
2361    #endif /* SUPPORT_UTF */
2362    
2363  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2364    
# Line 1585  DEFINE_COMPILER; Line 2374  DEFINE_COMPILER;
2374    
2375  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2376    
2377  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2378  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2379  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));
2380  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2381  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2382  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2383  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
2384  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2385  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));
2386  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2387  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2388  }  }
# Line 1607  struct sljit_label *newlinelabel = NULL; Line 2396  struct sljit_label *newlinelabel = NULL;
2396  struct sljit_jump *start;  struct sljit_jump *start;
2397  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2398  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2399  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2400  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
2401  #endif  #endif
2402  jump_list *newline = NULL;  jump_list *newline = NULL;
2403  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
2404  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
2405    
2406  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
2407      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1621  if (!(hascrorlf || firstline) && (common Line 2410  if (!(hascrorlf || firstline) && (common
2410  if (firstline)  if (firstline)
2411    {    {
2412    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2413      SLJIT_ASSERT(common->first_line_end != 0);
2414    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
2415    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);
2416    
2417    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2418      {      {
2419      mainloop = LABEL();      mainloop = LABEL();
2420      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));
2421      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2422      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2423      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2424      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);
2425      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);
2426      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));
2427      }      }
2428    else    else
2429      {      {
2430      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2431      mainloop = LABEL();      mainloop = LABEL();
2432      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2433      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);
2434      read_char(common);      read_char(common);
2435      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2436      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2437      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);
2438      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2439      }      }
2440    
# Line 1657  start = JUMP(SLJIT_JUMP); Line 2447  start = JUMP(SLJIT_JUMP);
2447  if (newlinecheck)  if (newlinecheck)
2448    {    {
2449    newlinelabel = LABEL();    newlinelabel = LABEL();
2450    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));
2451    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2452    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2453    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);
2454    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2455    #ifdef COMPILE_PCRE16
2456      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2457    #endif
2458    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2459    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2460    }    }
# Line 1669  if (newlinecheck) Line 2462  if (newlinecheck)
2462  mainloop = LABEL();  mainloop = LABEL();
2463    
2464  /* 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. */
2465  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2466  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2467  #endif  #endif
2468  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2469    
2470  if (readbyte)  if (readuchar)
2471    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2472    
2473  if (newlinecheck)  if (newlinecheck)
2474    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);
2475    
2476  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));
2477  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2478  if (common->utf8)  if (common->utf)
2479      {
2480      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2481      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2482      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2483      JUMPHERE(singlechar);
2484      }
2485    #endif
2486    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2487    if (common->utf)
2488    {    {
2489    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2490    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);
2491      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2492      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2493      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2494    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2495    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
2496    }    }
2497  #endif  #endif
2498  JUMPHERE(start);  JUMPHERE(start);
# Line 1701  if (newlinecheck) Line 2506  if (newlinecheck)
2506  return mainloop;  return mainloop;
2507  }  }
2508    
2509  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)
2510    {
2511    DEFINE_COMPILER;
2512    struct sljit_label *start;
2513    struct sljit_jump *leave;
2514    struct sljit_jump *found;
2515    pcre_int32 chars[4];
2516    pcre_uchar *cc = common->start + 1 + IMM2_SIZE;
2517    int index = 0;
2518    pcre_int32 len, c, bit;
2519    unsigned int caseless;
2520    BOOL must_end;
2521    
2522    #ifdef COMPILE_PCRE8
2523    union {
2524        sljit_uh ascombined;
2525        sljit_ub asuchars[2];
2526    } pair;
2527    #else
2528    union {
2529        sljit_ui ascombined;
2530        sljit_uh asuchars[2];
2531    } pair;
2532    #endif
2533    
2534    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2535      return FALSE;
2536    
2537    while (TRUE)
2538      {
2539      caseless = 0;
2540      must_end = TRUE;
2541      switch(*cc)
2542        {
2543        case OP_CHAR:
2544        must_end = FALSE;
2545        cc++;
2546        break;
2547    
2548        case OP_CHARI:
2549        caseless = 1;
2550        must_end = FALSE;
2551        cc++;
2552        break;
2553    
2554        case OP_SOD:
2555        case OP_SOM:
2556        case OP_SET_SOM:
2557        case OP_NOT_WORD_BOUNDARY:
2558        case OP_WORD_BOUNDARY:
2559        case OP_EODN:
2560        case OP_EOD:
2561        case OP_CIRC:
2562        case OP_CIRCM:
2563        case OP_DOLL:
2564        case OP_DOLLM:
2565        /* Zero width assertions. */
2566        cc++;
2567        continue;
2568    
2569        case OP_PLUS:
2570        case OP_MINPLUS:
2571        case OP_POSPLUS:
2572        cc++;
2573        break;
2574    
2575        case OP_EXACT:
2576        cc += 1 + IMM2_SIZE;
2577        break;
2578    
2579        case OP_PLUSI:
2580        case OP_MINPLUSI:
2581        case OP_POSPLUSI:
2582        caseless = 1;
2583        cc++;
2584        break;
2585    
2586        case OP_EXACTI:
2587        caseless = 1;
2588        cc += 1 + IMM2_SIZE;
2589        break;
2590    
2591        default:
2592        return FALSE;
2593        }
2594    
2595      len = 1;
2596    #ifdef SUPPORT_UTF
2597      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2598    #endif
2599    
2600      if (caseless && char_has_othercase(common, cc))
2601        {
2602        caseless = char_get_othercase_bit(common, cc);
2603        if (caseless == 0)
2604          return FALSE;
2605    #ifdef COMPILE_PCRE8
2606        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2607    #else
2608        if ((caseless & 0x100) != 0)
2609          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2610        else
2611          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2612    #endif
2613        }
2614      else
2615        caseless = 0;
2616    
2617      while (len > 0 && index < 2 * 2)
2618        {
2619        c = *cc;
2620        bit = 0;
2621        if (len == (caseless & 0xff))
2622          {
2623          bit = caseless >> 8;
2624          c |= bit;
2625          }
2626    
2627        chars[index] = c;
2628        chars[index + 1] = bit;
2629    
2630        len--;
2631        index += 2;
2632        cc++;
2633        }
2634    
2635      if (index == 2 * 2)
2636        break;
2637      else if (must_end)
2638        return FALSE;
2639      }
2640    
2641    if (firstline)
2642      {
2643      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2644      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2645      }
2646    else
2647      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2648    
2649    start = LABEL();
2650    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2651    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2652    #ifdef COMPILE_PCRE8
2653    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2654    #else /* COMPILE_PCRE8 */
2655    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2656    #endif
2657    
2658    #else /* SLJIT_UNALIGNED */
2659    
2660    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2661    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2662    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2663    #else /* SLJIT_BIG_ENDIAN */
2664    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2665    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2666    #endif /* SLJIT_BIG_ENDIAN */
2667    
2668    #ifdef COMPILE_PCRE8
2669    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2670    #else /* COMPILE_PCRE8 */
2671    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2672    #endif
2673    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2674    
2675    #endif
2676    
2677    if (chars[1] != 0 || chars[3] != 0)
2678      {
2679      pair.asuchars[0] = chars[1];
2680      pair.asuchars[1] = chars[3];
2681      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2682      }
2683    
2684    pair.asuchars[0] = chars[0];
2685    pair.asuchars[1] = chars[2];
2686    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2687    
2688    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2689    JUMPTO(SLJIT_JUMP, start);
2690    JUMPHERE(found);
2691    JUMPHERE(leave);
2692    
2693    if (firstline)
2694      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2695    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2696    return TRUE;
2697    }
2698    
2699    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2700  {  {
2701  DEFINE_COMPILER;  DEFINE_COMPILER;
2702  struct sljit_label *start;  struct sljit_label *start;
2703  struct sljit_jump *leave;  struct sljit_jump *leave;
2704  struct sljit_jump *found;  struct sljit_jump *found;
2705  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2706    
2707  if (firstline)  if (firstline)
2708    {    {
2709    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2710    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);
2711    }    }
2712    
2713  start = LABEL();  start = LABEL();
2714  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2715  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2716    
2717  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2718    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2719      {
2720      oc = TABLE_GET(first_char, common->fcc, first_char);
2721    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2722      if (first_char > 127 && common->utf)
2723        oc = UCD_OTHERCASE(first_char);
2724    #endif
2725      }
2726    if (first_char == oc)
2727      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2728  else  else
2729    {    {
2730    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2731    if (ispowerof2(bit))    if (ispowerof2(bit))
2732      {      {
2733      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2734      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2735      }      }
2736    else    else
2737      {      {
2738      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);
2739      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2740      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);
2741      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 1741  else Line 2743  else
2743      }      }
2744    }    }
2745    
2746  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));
 #ifdef SUPPORT_UTF8  
 if (common->utf8)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2747  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2748  JUMPHERE(found);  JUMPHERE(found);
2749  JUMPHERE(leave);  JUMPHERE(leave);
# Line 1772  jump_list *newline = NULL; Line 2766  jump_list *newline = NULL;
2766  if (firstline)  if (firstline)
2767    {    {
2768    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2769    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);
2770    }    }
2771    
2772  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1783  if (common->nltype == NLTYPE_FIXED && co Line 2777  if (common->nltype == NLTYPE_FIXED && co
2777    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));
2778    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2779    
2780    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2781    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);
2782    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2783    #ifdef COMPILE_PCRE16
2784      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2785    #endif
2786    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2787    
2788    loop = LABEL();    loop = LABEL();
2789    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));
2790    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2791    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2792    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2793    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);
2794    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);
2795    
# Line 1823  if (common->nltype == NLTYPE_ANY || comm Line 2820  if (common->nltype == NLTYPE_ANY || comm
2820    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2821    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2822    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2823    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2824    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);
2825    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2826    #ifdef COMPILE_PCRE16
2827      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2828    #endif
2829    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2830    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2831    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1843  DEFINE_COMPILER; Line 2843  DEFINE_COMPILER;
2843  struct sljit_label *start;  struct sljit_label *start;
2844  struct sljit_jump *leave;  struct sljit_jump *leave;
2845  struct sljit_jump *found;  struct sljit_jump *found;
2846    #ifndef COMPILE_PCRE8
2847    struct sljit_jump *jump;
2848    #endif
2849    
2850  if (firstline)  if (firstline)
2851    {    {
2852    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2853    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);
2854    }    }
2855    
2856  start = LABEL();  start = LABEL();
2857  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2858  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2859  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2860  if (common->utf8)  if (common->utf)
2861    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2862  #endif  #endif
2863    #ifndef COMPILE_PCRE8
2864    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2865    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2866    JUMPHERE(jump);
2867    #endif
2868  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2869  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2870  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1864  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2872  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2872  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);
2873  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2874    
2875  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2876  if (common->utf8)  if (common->utf)
2877    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2878  #endif  #endif
2879  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));
2880  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2881  if (common->utf8)  if (common->utf)
2882    {    {
2883    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2884    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);
2885      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2886      }
2887    #endif
2888    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2889    if (common->utf)
2890      {
2891      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2892      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2893      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2894      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2895      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2896    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2897    }    }
2898  #endif  #endif
# Line 1885  if (firstline) Line 2904  if (firstline)
2904    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2905  }  }
2906    
2907  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)
2908  {  {
2909  DEFINE_COMPILER;  DEFINE_COMPILER;
2910  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1894  struct sljit_jump *alreadyfound; Line 2913  struct sljit_jump *alreadyfound;
2913  struct sljit_jump *found;  struct sljit_jump *found;
2914  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2915  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2916  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2917    
2918  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2919    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2920  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);
2921  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2922  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2923    
2924  if (has_firstbyte)  if (has_firstchar)
2925    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2926  else  else
2927    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2928    
2929  loop = LABEL();  loop = LABEL();
2930  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2931    
2932  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2933  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2934    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2935      {
2936      oc = TABLE_GET(req_char, common->fcc, req_char);
2937    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2938      if (req_char > 127 && common->utf)
2939        oc = UCD_OTHERCASE(req_char);
2940    #endif
2941      }
2942    if (req_char == oc)
2943      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2944  else  else
2945    {    {
2946    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2947    if (ispowerof2(bit))    if (ispowerof2(bit))
2948      {      {
2949      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2950      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2951      }      }
2952    else    else
2953      {      {
2954      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2955      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2956      }      }
2957    }    }
2958  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2959  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2960    
2961  JUMPHERE(found);  JUMPHERE(found);
2962  if (foundoc)  if (foundoc)
2963    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2964  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);
2965  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2966  JUMPHERE(toolong);  JUMPHERE(toolong);
2967  return notfound;  return notfound;
# Line 1946  DEFINE_COMPILER; Line 2973  DEFINE_COMPILER;
2973  struct sljit_jump *jump;  struct sljit_jump *jump;
2974  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2975    
2976  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2977  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2978    GET_LOCAL_BASE(TMP3, 0, 0);
2979    
2980  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
2981  mainloop = LABEL();  mainloop = LABEL();
2982  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2983  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);
2984  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2985  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));
2986  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));
2987  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 1973  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 3001  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
3001  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3002    
3003  JUMPHERE(jump);  JUMPHERE(jump);
3004    if (common->mark_ptr != 0)
3005      {
3006      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3007      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3008      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3009      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3010      JUMPTO(SLJIT_JUMP, mainloop);
3011    
3012      JUMPHERE(jump);
3013      }
3014    
3015  /* Unknown command. */  /* Unknown command. */
3016  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));
3017  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 1981  JUMPTO(SLJIT_JUMP, mainloop); Line 3020  JUMPTO(SLJIT_JUMP, mainloop);
3020  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3021  {  {
3022  DEFINE_COMPILER;  DEFINE_COMPILER;
3023  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3024  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3025  struct sljit_jump *jump;  struct sljit_jump *jump;
3026  #endif  #endif
3027    
3028  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3029    
3030  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);
3031  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3032  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3033  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));
3034  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3035  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3036  skip_char_back(common);  skip_char_back(common);
3037    check_start_used_ptr(common);
3038  read_char(common);  read_char(common);
3039    
3040  /* Testing char type. */  /* Testing char type. */
3041  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3042  if (common->useucp)  if (common->use_ucp)
3043    {    {
3044    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3045    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2016  if (common->useucp) Line 3056  if (common->useucp)
3056  else  else
3057  #endif  #endif
3058    {    {
3059  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3060      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3061    #elif defined SUPPORT_UTF
3062    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3063    jump = NULL;    jump = NULL;
3064    if (common->utf8)    if (common->utf)
3065      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3066  #endif  #endif /* COMPILE_PCRE8 */
3067    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3068    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3069    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3070    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3071  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3072      JUMPHERE(jump);
3073    #elif defined SUPPORT_UTF
3074    if (jump != NULL)    if (jump != NULL)
3075      JUMPHERE(jump);      JUMPHERE(jump);
3076  #endif  #endif /* COMPILE_PCRE8 */
3077    }    }
3078  JUMPHERE(beginend);  JUMPHERE(skipread);
3079    
3080  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3081  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3082  peek_char(common);  peek_char(common);
3083    
3084  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3085  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3086  if (common->useucp)  if (common->use_ucp)
3087    {    {
3088    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3089    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2055  if (common->useucp) Line 3099  if (common->useucp)
3099  else  else
3100  #endif  #endif
3101    {    {
3102  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3103      /* TMP2 may be destroyed by peek_char. */
3104      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3105      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3106    #elif defined SUPPORT_UTF
3107    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3108    jump = NULL;    jump = NULL;
3109    if (common->utf8)    if (common->utf)
3110      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3111  #endif  #endif
3112    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3113    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3114    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3115  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3116      JUMPHERE(jump);
3117    #elif defined SUPPORT_UTF
3118    if (jump != NULL)    if (jump != NULL)
3119      JUMPHERE(jump);      JUMPHERE(jump);
3120  #endif  #endif /* COMPILE_PCRE8 */
3121    }    }
3122  JUMPHERE(beginend);  JUMPHERE(skipread);
3123    
3124  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);
3125  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2080  static void check_anynewline(compiler_co Line 3130  static void check_anynewline(compiler_co
3130  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3131  DEFINE_COMPILER;  DEFINE_COMPILER;
3132    
3133  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3134    
3135  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3136  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);
3137  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3138  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);
3139  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3140  if (common->utf8)  #ifdef COMPILE_PCRE8
3141    if (common->utf)
3142    {    {
3143    #endif
3144    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3145    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3146    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);
3147    #ifdef COMPILE_PCRE8
3148    }    }
3149  #endif  #endif
3150    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3151  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3152  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3153  }  }
# Line 2103  static void check_hspace(compiler_common Line 3157  static void check_hspace(compiler_common
3157  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3158  DEFINE_COMPILER;  DEFINE_COMPILER;
3159    
3160  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3161    
3162  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);
3163  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3164  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);
3165  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3166  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);
3167  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3168  if (common->utf8)  #ifdef COMPILE_PCRE8
3169    if (common->utf)
3170    {    {
3171    #endif
3172    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3173    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);
3174    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2126  if (common->utf8) Line 3182  if (common->utf8)
3182    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);
3183    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3184    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);
3185    #ifdef COMPILE_PCRE8
3186    }    }
3187  #endif  #endif
3188    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3189  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3190    
3191  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2138  static void check_vspace(compiler_common Line 3196  static void check_vspace(compiler_common
3196  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3197  DEFINE_COMPILER;  DEFINE_COMPILER;
3198    
3199  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3200    
3201  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3202  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);
3203  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3204  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);
3205  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3206  if (common->utf8)  #ifdef COMPILE_PCRE8
3207    if (common->utf)
3208    {    {
3209    #endif
3210    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3211    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3212    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);
3213    #ifdef COMPILE_PCRE8
3214    }    }
3215  #endif  #endif
3216    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3217  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3218    
3219  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2166  DEFINE_COMPILER; Line 3228  DEFINE_COMPILER;
3228  struct sljit_jump *jump;  struct sljit_jump *jump;
3229  struct sljit_label *label;  struct sljit_label *label;
3230    
3231  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3232  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3233  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3234  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3235  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3236  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));
3237    
3238  label = LABEL();  label = LABEL();
3239  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3240  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3241  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3242  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));
3243  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3244    
3245  JUMPHERE(jump);  JUMPHERE(jump);
3246  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));
3247  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3248  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3249  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2195  DEFINE_COMPILER; Line 3257  DEFINE_COMPILER;
3257  struct sljit_jump *jump;  struct sljit_jump *jump;
3258  struct sljit_label *label;  struct sljit_label *label;
3259    
3260  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3261  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3262    
3263  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3264  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3265  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3266  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3267  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3268  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));
3269    
3270  label = LABEL();  label = LABEL();
3271  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3272  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3273    #ifndef COMPILE_PCRE8
3274    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3275    #endif
3276  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3277    #ifndef COMPILE_PCRE8
3278    JUMPHERE(jump);
3279    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3280    #endif
3281  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3282    #ifndef COMPILE_PCRE8
3283    JUMPHERE(jump);
3284    #endif
3285  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3286  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));
3287  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3288    
3289  JUMPHERE(jump);  JUMPHERE(jump);
3290  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));
3291  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3292  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3293  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2226  sljit_emit_fast_return(compiler, RETURN_ Line 3298  sljit_emit_fast_return(compiler, RETURN_
3298  #undef CHAR1  #undef CHAR1
3299  #undef CHAR2  #undef CHAR2
3300    
3301  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3302    
3303  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)
3304  {  {
3305  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3306  int c1, c2;  int c1, c2;
3307  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3308  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3309    
3310  while (src1 < end1)  while (src1 < end1)
3311    {    {
3312    if (src2 >= end2)    if (src2 >= end2)
3313      return 0;      return (pcre_uchar*)1;
3314    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3315    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3316    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
3317    }    }
3318  return src2;  return src2;
3319  }  }
3320    
3321  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3322    
3323  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,
3324      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3325  {  {
3326  DEFINE_COMPILER;  DEFINE_COMPILER;
3327  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3328  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3329  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3330  int utf8length;  int utflength;
3331  #endif  #endif
3332    
3333  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2265  if (caseless && char_has_othercase(commo Line 3335  if (caseless && char_has_othercase(commo
3335    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3336    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3337    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3338    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
3339      othercasechar = cc + (othercasebit >> 8);
3340    othercasebit &= 0xff;    othercasebit &= 0xff;
3341    #else
3342    #ifdef COMPILE_PCRE16
3343      othercasechar = cc + (othercasebit >> 9);
3344      if ((othercasebit & 0x100) != 0)
3345        othercasebit = (othercasebit & 0xff) << 8;
3346      else
3347        othercasebit &= 0xff;
3348    #endif
3349    #endif
3350    }    }
3351    
3352  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3353    {    {
3354    #ifdef COMPILE_PCRE8
3355  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3356    if (context->length >= 4)    if (context->length >= 4)
3357      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3358    else if (context->length >= 2)    else if (context->length >= 2)
3359      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3360    else    else
3361  #endif  #endif
3362      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3363    #else
3364    #ifdef COMPILE_PCRE16
3365    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3366      if (context->length >= 4)
3367        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3368      else
3369    #endif
3370        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3371    #endif
3372    #endif /* COMPILE_PCRE8 */
3373    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3374    }    }
3375    
3376  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3377  utf8length = 1;  utflength = 1;
3378  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3379    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3380    
3381  do  do
3382    {    {
3383  #endif  #endif
3384    
3385    context->length--;    context->length -= IN_UCHARS(1);
3386  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3387    
3388    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3389    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3390      {      {
3391      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3392      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3393      }      }
3394    else    else
3395      {      {
3396      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3397      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3398      }      }
3399    context->byteptr++;    context->ucharptr++;
3400    
3401    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
3402      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3403    #else
3404      if (context->ucharptr >= 2 || context->length == 0)
3405    #endif
3406      {      {
3407      if (context->length >= 4)      if (context->length >= 4)
3408        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);
3409    #ifdef COMPILE_PCRE8
3410      else if (context->length >= 2)      else if (context->length >= 2)
3411        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);
3412      else if (context->length >= 1)      else if (context->length >= 1)
3413        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);
3414    #else
3415        else if (context->length >= 2)
3416          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3417    #endif
3418      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3419    
3420      switch(context->byteptr)      switch(context->ucharptr)
3421        {        {
3422        case 4:        case 4 / sizeof(pcre_uchar):
3423        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3424          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);
3425        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));
3426        break;        break;
3427    
3428        case 2:        case 2 / sizeof(pcre_uchar):
3429        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3430          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);
3431        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));
3432        break;        break;
3433    
3434    #ifdef COMPILE_PCRE8
3435        case 1:        case 1:
3436        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3437          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);
3438        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));
3439        break;        break;
3440    #endif
3441    
3442        default:        default:
3443        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3444        break;        break;
3445        }        }
3446      context->byteptr = 0;      context->ucharptr = 0;
3447      }      }
3448    
3449  #else  #else
3450    
3451    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
3452    #ifdef COMPILE_PCRE8
3453    if (context->length > 0)    if (context->length > 0)
3454      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);
3455    #else
3456      if (context->length > 0)
3457        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3458    #endif
3459    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3460    
3461    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3462      {      {
3463      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3464      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));
3465      }      }
3466    else    else
3467      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));
3468    
3469  #endif  #endif
3470    
3471    cc++;    cc++;
3472  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3473    utf8length--;    utflength--;
3474    }    }
3475  while (utf8length > 0);  while (utflength > 0);
3476  #endif  #endif
3477    
3478  return cc;  return cc;
3479  }  }
3480    
3481  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3482    
3483  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
3484    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2393  return cc; Line 3500  return cc;
3500      } \      } \
3501    charoffset = (value);    charoffset = (value);
3502    
3503  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)
3504  {  {
3505  DEFINE_COMPILER;  DEFINE_COMPILER;
3506  jump_list *found = NULL;  jump_list *found = NULL;
3507  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3508  unsigned int c;  unsigned int c;
3509  int compares;  int compares;
3510  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3511  uschar *ccbegin;  pcre_uchar *ccbegin;
3512  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3513  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3514  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2411  unsigned int typeoffset; Line 3518  unsigned int typeoffset;
3518  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3519  unsigned int charoffset;  unsigned int charoffset;
3520    
3521  /* 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. */
3522  check_input_end(common, fallbacks);  detect_partial_match(common, backtracks);
3523  read_char(common);  read_char(common);
3524    
3525  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
3526    {    {
3527    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3528    if (common->utf8)  #ifndef COMPILE_PCRE8
3529      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3530    #elif defined SUPPORT_UTF
3531      if (common->utf)
3532      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3533    #endif
3534    
3535    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3536    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2428  if ((*cc++ & XCL_MAP) != 0) Line 3539  if ((*cc++ & XCL_MAP) != 0)
3539    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);
3540    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3541    
3542    if (common->utf8)  #ifndef COMPILE_PCRE8
3543      JUMPHERE(jump);
3544    #elif defined SUPPORT_UTF
3545      if (common->utf)
3546      JUMPHERE(jump);      JUMPHERE(jump);
3547    #endif
3548    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3549  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3550    charsaved = TRUE;    charsaved = TRUE;
3551  #endif  #endif
3552    cc += 32;    cc += 32 / sizeof(pcre_uchar);
3553    }    }
3554    
3555  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2446  while (*cc != XCL_END) Line 3561  while (*cc != XCL_END)
3561    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3562      {      {
3563      cc += 2;      cc += 2;
3564  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3565      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]);
3566  #endif  #endif
3567  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3568      needschar = TRUE;      needschar = TRUE;
# Line 2456  while (*cc != XCL_END) Line 3571  while (*cc != XCL_END)
3571    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3572      {      {
3573      cc += 2;      cc += 2;
3574  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3575      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]);
3576  #endif  #endif
3577      cc++;      cc++;
3578  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3579      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]);
3580  #endif  #endif
3581  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3582      needschar = TRUE;      needschar = TRUE;
# Line 2531  if (needstype || needsscript) Line 3646  if (needstype || needsscript)
3646      {      {
3647      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3648        {        {
3649        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));
3650        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3651        }        }
3652      else      else
3653        {        {
3654        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3655        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));
3656        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3657        }        }
3658      }      }
# Line 2555  typeoffset = 0; Line 3670  typeoffset = 0;
3670  while (*cc != XCL_END)  while (*cc != XCL_END)
3671    {    {
3672    compares--;    compares--;
3673    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3674    jump = NULL;    jump = NULL;
3675    
3676    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3677      {      {
3678      cc ++;      cc ++;
3679  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3680      if (common->utf8)      if (common->utf)
3681        {        {
3682        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3683        }        }
# Line 2592  while (*cc != XCL_END) Line 3707  while (*cc != XCL_END)
3707    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3708      {      {
3709      cc ++;      cc ++;
3710  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3711      if (common->utf8)      if (common->utf)
3712        {        {
3713        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3714        }        }
# Line 2601  while (*cc != XCL_END) Line 3716  while (*cc != XCL_END)
3716  #endif  #endif
3717        c = *cc++;        c = *cc++;
3718      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3719  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3720      if (common->utf8)      if (common->utf)
3721        {        {
3722        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3723        }        }
# Line 2637  while (*cc != XCL_END) Line 3752  while (*cc != XCL_END)
3752      switch(*cc)      switch(*cc)
3753        {        {
3754        case PT_ANY:        case PT_ANY:
3755        if (list != fallbacks)        if (list != backtracks)
3756          {          {
3757          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))
3758            continue;            continue;
# Line 2658  while (*cc != XCL_END) Line 3773  while (*cc != XCL_END)
3773        break;        break;
3774    
3775        case PT_GC:        case PT_GC:
3776        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3777        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3778        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);
3779        break;        break;
3780    
3781        case PT_PC:        case PT_PC:
# Line 2710  while (*cc != XCL_END) Line 3825  while (*cc != XCL_END)
3825  #endif  #endif
3826    
3827    if (jump != NULL)    if (jump != NULL)
3828      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3829    }    }
3830    
3831  if (found != NULL)  if (found != NULL)
# Line 2722  if (found != NULL) Line 3837  if (found != NULL)
3837    
3838  #endif  #endif
3839    
3840  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)
3841  {  {
3842  DEFINE_COMPILER;  DEFINE_COMPILER;
3843  int length;  int length;
3844  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3845  compare_context context;  compare_context context;
3846  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3847  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3848  struct sljit_label *label;  struct sljit_label *label;
3849  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3850  uschar propdata[5];  pcre_uchar propdata[5];
3851  #endif  #endif
3852  #endif  #endif
3853    
# Line 2741  switch(type) Line 3856  switch(type)
3856    case OP_SOD:    case OP_SOD:
3857    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3858    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));
3859    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));
3860    return cc;    return cc;
3861    
3862    case OP_SOM:    case OP_SOM:
3863    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3864    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));
3865    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));
3866    return cc;    return cc;
3867    
3868    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
3869    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
3870    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3871    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));
3872    return cc;    return cc;
3873    
3874    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3875    case OP_DIGIT:    case OP_DIGIT:
3876    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3877    read_char8_type(common);    read_char8_type(common);
3878    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);
3879    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));
3880    return cc;    return cc;
3881    
3882    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3883    case OP_WHITESPACE:    case OP_WHITESPACE:
3884    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3885    read_char8_type(common);    read_char8_type(common);
3886    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);
3887    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));
3888    return cc;    return cc;
3889    
3890    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3891    case OP_WORDCHAR:    case OP_WORDCHAR:
3892    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3893    read_char8_type(common);    read_char8_type(common);
3894    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);
3895    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));
3896    return cc;    return cc;
3897    
3898    case OP_ANY:    case OP_ANY:
3899    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3900    read_char(common);    read_char(common);
3901    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3902      {      {
3903      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);
3904      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3905      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3906      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      else
3907      JUMPHERE(jump[1]);        jump[1] = check_str_end(common);
3908    
3909        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3910        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3911        if (jump[1] != NULL)
3912          JUMPHERE(jump[1]);
3913      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3914      }      }
3915    else    else
3916      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
3917    return cc;    return cc;
3918    
3919    case OP_ALLANY:    case OP_ALLANY:
3920    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3921  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3922    if (common->utf8)    if (common->utf)
3923      {      {
3924      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3925      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));
3926    #ifdef COMPILE_PCRE8
3927      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3928      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);
3929      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3930    #else /* COMPILE_PCRE8 */
3931    #ifdef COMPILE_PCRE16
3932        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3933        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3934        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3935        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3936        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3937        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3938    #endif /* COMPILE_PCRE16 */
3939    #endif /* COMPILE_PCRE8 */
3940      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3941      return cc;      return cc;
3942      }      }
3943  #endif  #endif
3944    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));
3945    return cc;    return cc;
3946    
3947    case OP_ANYBYTE:    case OP_ANYBYTE:
3948    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3949    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));
3950    return cc;    return cc;
3951    
3952  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3953  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3954    case OP_NOTPROP:    case OP_NOTPROP:
3955    case OP_PROP:    case OP_PROP:
# Line 2827  switch(type) Line 3958  switch(type)
3958    propdata[2] = cc[0];    propdata[2] = cc[0];
3959    propdata[3] = cc[1];    propdata[3] = cc[1];
3960    propdata[4] = XCL_END;    propdata[4] = XCL_END;
3961    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_trypath(common, propdata, backtracks);
3962    return cc + 2;    return cc + 2;
3963  #endif  #endif
3964  #endif  #endif
3965    
3966    case OP_ANYNL:    case OP_ANYNL:
3967    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3968    read_char(common);    read_char(common);
3969    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);
3970    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3971    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3972        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3973      else
3974        jump[1] = check_str_end(common);
3975      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3976    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);
3977    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));
3978    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3979    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3980    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
3981    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3982    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
3983    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 2850  switch(type) Line 3985  switch(type)
3985    
3986    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3987    case OP_HSPACE:    case OP_HSPACE:
3988    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3989    read_char(common);    read_char(common);
3990    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3991    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));
3992    return cc;    return cc;
3993    
3994    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3995    case OP_VSPACE:    case OP_VSPACE:
3996    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3997    read_char(common);    read_char(common);
3998    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3999    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));
4000    return cc;    return cc;
4001    
4002  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4003    case OP_EXTUNI:    case OP_EXTUNI:
4004    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4005    read_char(common);    read_char(common);
4006    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4007    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
4008    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));
4009    
4010    label = LABEL();    label = LABEL();
4011    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 2882  switch(type) Line 4017  switch(type)
4017    
4018    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4019    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4020      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4021        {
4022        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4023        /* Since we successfully read a char above, partial matching must occure. */
4024        check_partial(common, TRUE);
4025        JUMPHERE(jump[0]);
4026        }
4027    return cc;    return cc;
4028  #endif  #endif
4029    
4030    case OP_EODN:    case OP_EODN:
4031      /* Requires rather complex checks. */
4032    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);
4033    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4034      {      {
4035      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4036      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4037      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
4038      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));
4039      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      else
4040      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));        {
4041          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4042          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4043          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4044          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4045          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
4046          add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4047          check_partial(common, TRUE);
4048          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4049          JUMPHERE(jump[1]);
4050          }
4051        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4052        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4053        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4054      }      }
4055    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4056      {      {
4057      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4058      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4059      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));
4060      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));
4061      }      }
4062    else    else
4063      {      {
4064      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4065      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);
4066      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4067      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);
4068      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
4069      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, backtracks, JUMP(SLJIT_C_LESS));
4070      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
4071        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4072      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4073      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4074    
4075      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
4076      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
4077        {        {
4078        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4079        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));
4080        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));
4081        }        }
4082      else      else
4083        {        {
4084        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, STR_PTR, 0);
4085        read_char(common);        read_char(common);
4086        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));
4087        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
4088        add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));        add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4089        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
4090        }        }
4091      JUMPHERE(jump[2]);      JUMPHERE(jump[2]);
4092      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
4093      }      }
4094    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4095      check_partial(common, FALSE);
4096    return cc;    return cc;
4097    
4098    case OP_EOD:    case OP_EOD:
4099    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));
4100      check_partial(common, FALSE);
4101    return cc;    return cc;
4102    
4103    case OP_CIRC:    case OP_CIRC:
4104    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4105    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));
4106    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));
4107    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));
4108    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));
4109    return cc;    return cc;
4110    
4111    case OP_CIRCM:    case OP_CIRCM:
# Line 2954  switch(type) Line 4113  switch(type)
4113    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));
4114    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);    jump[1] = CMP(SLJIT_C_GREATER, STR_PTR, 0, TMP1, 0);
4115    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));
4116    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));
4117    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4118    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4119    
4120    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));  
   
4121    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4122      {      {
4123      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4124      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
4125      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
4126      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
4127      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));
4128      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));
4129      }      }
4130    else    else
4131      {      {
4132      skip_char_back(common);      skip_char_back(common);
4133      read_char(common);      read_char(common);
4134      check_newlinechar(common, common->nltype, fallbacks, FALSE);      check_newlinechar(common, common->nltype, backtracks, FALSE);
4135      }      }
4136    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4137    return cc;    return cc;
# Line 2982  switch(type) Line 4139  switch(type)
4139    case OP_DOLL:    case OP_DOLL:
4140    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4141    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));
4142    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));
4143    
4144    if (!common->endonly)    if (!common->endonly)
4145      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_trypath(common, OP_EODN, cc, backtracks);
4146    else    else
4147      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      {
4148        add_jump(compiler, backtracks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
4149        check_partial(common, FALSE);
4150        }
4151    return cc;    return cc;
4152    
4153    case OP_DOLLM:    case OP_DOLLM:
4154    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4155    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
4156    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));
4157    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));
4158      check_partial(common, FALSE);
4159    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
4160    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4161    
4162    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4163      {      {
4164      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4165      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));
4166      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
4167      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
4168      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      else
4169      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));        {
4170          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
4171          /* STR_PTR = STR_END - IN_UCHARS(1) */
4172          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4173          check_partial(common, TRUE);
4174          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4175          JUMPHERE(jump[1]);
4176          }
4177    
4178        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4179        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4180        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4181      }      }
4182    else    else