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

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

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

revision 678 by ph10, Sun Aug 28 15:23:03 2011 UTC revision 989 by zherczeg, Sat Jul 7 11:11:02 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 79  The code generator follows the recursive Line 82  The code generator follows the recursive
82  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
83  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
84  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
85  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
86    
87    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
88    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
89    
90  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
91  for the checker itself and for the actions depending on the result of the checker.  for the checker itself and for the actions depending on the result of the checker.
92  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the try path (expected path), and the other is called as
93  the 'fallback' path. Branch instructions are expesive for all CPUs, so we avoid taken  the 'backtrack' path. Branch instructions are expesive for all CPUs, so we avoid taken
94  branches on the hot path.  branches on the try path.
95    
96   Greedy star operator (*) :   Greedy star operator (*) :
97     Hot path: match happens.     Try path: match happens.
98     Fallback path: match failed.     Backtrack path: match failed.
99   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
100     Hot path: no need to perform a match.     Try path: no need to perform a match.
101     Fallback path: match is required.     Backtrack path: match is required.
102    
103  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
104  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# Line 105  we have the following regular expression Line 108  we have the following regular expression
108    
109  The generated code will be the following:  The generated code will be the following:
110    
111   A hot path   A try path
112   '(' hot path (pushing arguments to the stack)   '(' try path (pushing arguments to the stack)
113   B hot path   B try path
114   ')' hot path (pushing arguments to the stack)   ')' try path (pushing arguments to the stack)
115   D hot path   D try path
116   return with successful match   return with successful match
117    
118   D fallback path   D backtrack path
119   ')' fallback path (If we arrived from "C" jump to the fallback of "C")   ')' backtrack path (If we arrived from "C" jump to the backtrack of "C")
120   B fallback path   B backtrack path
121   C expected path   C expected path
122   jump to D hot path   jump to D try path
123   C fallback path   C backtrack path
124   A fallback path   A backtrack path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of backtrack code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
129   whether there is a next alternative. If so, it needs to jump back to   whether there is a next alternative. If so, it needs to jump back to
130   the hot path eventually. Otherwise it needs to clear out its own stack   the try path eventually. Otherwise it needs to clear out its own stack
131   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
132  */  */
133    
134  /*  /*
135  Saved stack frames:  Saved stack frames:
136    
137  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of local variables
138  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the locals
139  are not necessarly known in compile time, thus we need a dynamic restore  are not necessarly known in compile time, thus we need a dynamic restore
140  mechanism.  mechanism.
141    
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
160    uschar notbol;    pcre_uint8 notbol;
161    uschar noteol;    pcre_uint8 noteol;
162    uschar notempty;    pcre_uint8 notempty;
163    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    pcre_jit_callback callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171    } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
175    struct jump_list *next;    struct jump_list *next;
176  } jump_list;  } jump_list;
177    
178  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
179    
180  typedef struct stub_list {  typedef struct stub_list {
181    enum stub_types type;    enum stub_types type;
# Line 183  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 259  typedef struct recurse_entry { Line 264  typedef struct recurse_entry {
264    int start;    int start;
265  } recurse_entry;  } recurse_entry;
266    
267  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
268    fallback_common common;    backtrack_common common;
269  } recurse_fallback;  } recurse_backtrack;
270    
271  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;
304      sljit_w name_count;
305      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 291  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 310  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_setmaxindex = -1,    frame_setstrbegin = -1,
379    frame_setstrbegin = -2    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 MAX_INDEX     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 353  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 saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  
 /* Number of recursions. */  
 #define CALL_COUNT       (6 * sizeof(sljit_w))  
406  /* Max limit of recursions. */  /* Max limit of recursions. */
407  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * sizeof(sljit_w))  
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    (10 * 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 395  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 405  cc += 1 + LINK_SIZE; Line 459  cc += 1 + LINK_SIZE;
459  return cc;  return cc;
460  }  }
461    
462  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
463   next_opcode   next_opcode
464   get_localspace   get_localspace
465   set_localptrs   set_localptrs
# Line 413  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 466  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:
527    case OP_SKIPZERO:    case OP_SKIPZERO:
528    return cc + 1;    return cc + 1;
529    
530      case OP_ANYBYTE:
531    #ifdef SUPPORT_UTF
532      if (common->utf) return NULL;
533    #endif
534      return cc + 1;
535    
536    case OP_CHAR:    case OP_CHAR:
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 514  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 535  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 550  switch(*cc) Line 612  switch(*cc)
612    case OP_REF:    case OP_REF:
613    case OP_REFI:    case OP_REFI:
614    case OP_CREF:    case OP_CREF:
615      case OP_NCREF:
616      case OP_RREF:
617      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 574  switch(*cc) Line 639  switch(*cc)
639    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
640    case OP_REVERSE:    case OP_REVERSE:
641    case OP_ONCE:    case OP_ONCE:
642      case OP_ONCE_NC:
643    case OP_BRA:    case OP_BRA:
644    case OP_BRAPOS:    case OP_BRAPOS:
645    case OP_COND:    case OP_COND:
# Line 591  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:
770      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
771      case OP_ONCE:      case OP_ONCE:
772        case OP_ONCE_NC:
773      case OP_BRAPOS:      case OP_BRAPOS:
774      case OP_SBRA:      case OP_SBRA:
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 631  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 657  while (cc < ccend) Line 921  while (cc < ccend)
921      case OP_ASSERTBACK:      case OP_ASSERTBACK:
922      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
923      case OP_ONCE:      case OP_ONCE:
924        case OP_ONCE_NC:
925      case OP_BRAPOS:      case OP_BRAPOS:
926      case OP_SBRA:      case OP_SBRA:
927      case OP_SBRAPOS:      case OP_SBRAPOS:
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 681  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;
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;      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);
 uschar *end;  
1048  int length = 0;  int length = 0;
1049  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1050  BOOL needs_frame = FALSE;  BOOL setsom_found = recursive;
1051  BOOL needs_maxindex = FALSE;  BOOL setmark_found = recursive;
 BOOL setsom_found = FALSE;  
1052    
1053  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1054    {    {
1055    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
1056    possessive = TRUE;    possessive = TRUE;
1057    }    }
1058    
# Line 716  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;      break;
1073    
1074      case OP_ASSERT:      case OP_MARK:
1075      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
1076      case OP_ASSERTBACK:      if (!setmark_found)
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
1077        {        {
1078        cc = bracketend(cc);        length += 2;
1079        break;        setmark_found = TRUE;
1080        }        }
1081      /* Check whether a frame must be created. */      cc += 1 + 2 + cc[1];
1082      end = bracketend(cc);      break;
1083      while (cc < end)  
1084        {      case OP_RECURSE:
1085        if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS      if (common->has_set_som && !setsom_found)
1086            || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)        {
1087          needs_frame = TRUE;        length += 2;
1088        cc = next_opcode(common, cc);        setsom_found = TRUE;
1089        SLJIT_ASSERT(cc != NULL);        }
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:
1099      case OP_CBRAPOS:      case OP_CBRAPOS:
1100      case OP_SCBRA:      case OP_SCBRA:
1101      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
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 767  while (cc < ccend) Line 1110  while (cc < ccend)
1110      }      }
1111    
1112  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1113  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
1114    return -1;    return -1;
1115    
1116  if (length > 0)  if (length > 0)
1117    return length + 2;    return length + 1;
1118  return needs_frame ? 0 : -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  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
1123  DEFINE_COMPILER;  DEFINE_COMPILER;
1124  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1125  BOOL needs_maxindex = FALSE;  BOOL setsom_found = recursive;
1126  BOOL setsom_found = FALSE;  BOOL setmark_found = recursive;
1127  int offset;  int offset;
1128    
1129  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
1130    {  SLJIT_UNUSED_ARG(stacktop);
1131    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
1132    
1133  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacktop), TMP1, 0);  
   
1134  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1135    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
1136  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 802  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 812  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;      break;
1153    
1154      case OP_ASSERT:      case OP_MARK:
1155      case OP_ASSERT_NOT:      SLJIT_ASSERT(common->mark_ptr != 0);
1156      case OP_ASSERTBACK:      if (!setmark_found)
1157      case OP_ASSERTBACK_NOT:        {
1158      case OP_ONCE:        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1159      cc = bracketend(cc);        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;      break;
1167    
1168      case OP_CBRA:      case OP_RECURSE:
1169      case OP_CBRAPOS:      if (common->has_set_som && !setsom_found)
1170      case OP_SCBRA:        {
1171      case OP_SCBRAPOS:        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1172      if (!needs_maxindex)        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, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);        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);        stackpos += (int)sizeof(sljit_w);
1183        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1184        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
1185        needs_maxindex = TRUE;        setmark_found = TRUE;
1186        }        }
1187        cc += 1 + LINK_SIZE;
1188        break;
1189    
1190        case OP_CBRA:
1191        case OP_CBRAPOS:
1192        case OP_SCBRA:
1193        case OP_SCBRAPOS:
1194      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1195      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1196      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 845  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 855  while (cc < ccend) Line 1211  while (cc < ccend)
1211      }      }
1212    
1213  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
1214  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  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 872  while (cc < ccend) Line 1230  while (cc < ccend)
1230      case OP_ASSERTBACK:      case OP_ASSERTBACK:
1231      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
1232      case OP_ONCE:      case OP_ONCE:
1233        case OP_ONCE_NC:
1234      case OP_BRAPOS:      case OP_BRAPOS:
1235      case OP_SBRA:      case OP_SBRA:
1236      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 883  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 900  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 / (int)sizeof(pcre_uchar);
1312    #else
1313        size = 1 + 32 / (int)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 910  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 954  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 974  while (status != end) Line 1391  while (status != end)
1391        case OP_ASSERTBACK:        case OP_ASSERTBACK:
1392        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
1393        case OP_ONCE:        case OP_ONCE:
1394          case OP_ONCE_NC:
1395        case OP_BRAPOS:        case OP_BRAPOS:
1396        case OP_SBRA:        case OP_SBRA:
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 988  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 1006  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        default:        CASE_ITERATOR_LOCAL1
1434        cc = next_opcode(common, cc);        if (PRIV_DATA(cc))
1435        SLJIT_ASSERT(cc != NULL);          {
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;        break;
1444        }  
1445      break;        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 / (int)sizeof(pcre_uchar);
1505    #else
1506          size = 1 + 32 / (int)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:
1530          cc = next_opcode(common, cc);
1531          SLJIT_ASSERT(cc != NULL);
1532          break;
1533          }
1534        break;
1535    
1536      case end:      case end:
1537      SLJIT_ASSERT_STOP();      SLJIT_ASSERT_STOP();
# Line 1114  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 1170  while (list_item) Line 1691  while (list_item)
1691      case stack_alloc:      case stack_alloc:
1692      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1693      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1694      }      }
1695    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1696    list_item = list_item->next;    list_item = list_item->next;
# Line 1185  static SLJIT_INLINE void decrease_call_c Line 1702  static SLJIT_INLINE void decrease_call_c
1702  {  {
1703  DEFINE_COMPILER;  DEFINE_COMPILER;
1704    
1705  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_COUNT, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1706  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));  add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1707  }  }
1708    
# Line 1218  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  OP1(SLJIT_MOV, MAX_INDEX, 0, 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));
 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  
1739  if (length < 8)  if (length < 8)
1740    {    {
1741    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1227  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 1236  else Line 1752  else
1752    }    }
1753  }  }
1754    
1755  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1756  {  {
1757  DEFINE_COMPILER;  DEFINE_COMPILER;
1758  struct sljit_label *loop;  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_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1763    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);
1787    
1788    /* Calculate the return value, which is the maximum ovector value. */
1789    if (topbracket > 1)
1790      {
1791      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);
1793    
1794      /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1795      loop = LABEL();
1796      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);
1798      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);
1800      }
1801    else
1802      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 BOOL char_has_othercase(compiler_common *common, uschar* cc)  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, 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 1277  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 1297  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 1326  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 1344  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 1355  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 SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  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;  DEFINE_COMPILER;
1985  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  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 void detect_partial_match(compiler_common *common, jump_list **backtracks)
2043    {
2044    DEFINE_COMPILER;
2045    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 1370  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    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
2085    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    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 1392  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    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
2112    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    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 1413  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    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2143    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  
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 1465  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 1473  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 (>= 192). 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 (>= 192) 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 1595  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);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
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 1618  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 1640  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_UTF
2400    struct sljit_jump *singlechar;
2401    #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 1651  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 1687  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 1699  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  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2477  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2478    if (common->utf)
2479    {    {
2480    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
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);    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      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2490      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);
2495      JUMPHERE(singlechar);
2496    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
2497  #endif  #endif
2498  JUMPHERE(start);  JUMPHERE(start);
2499    
# Line 1732  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 location = 0;
2518    pcre_int32 len, c, bit, caseless;
2519    BOOL must_end;
2520    
2521    #ifdef COMPILE_PCRE8
2522    union {
2523        sljit_uh ascombined;
2524        sljit_ub asuchars[2];
2525    } pair;
2526    #else
2527    union {
2528        sljit_ui ascombined;
2529        sljit_uh asuchars[2];
2530    } pair;
2531    #endif
2532    
2533    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2534      return FALSE;
2535    
2536    while (TRUE)
2537      {
2538      caseless = 0;
2539      must_end = TRUE;
2540      switch(*cc)
2541        {
2542        case OP_CHAR:
2543        must_end = FALSE;
2544        cc++;
2545        break;
2546    
2547        case OP_CHARI:
2548        caseless = 1;
2549        must_end = FALSE;
2550        cc++;
2551        break;
2552    
2553        case OP_SOD:
2554        case OP_SOM:
2555        case OP_SET_SOM:
2556        case OP_NOT_WORD_BOUNDARY:
2557        case OP_WORD_BOUNDARY:
2558        case OP_EODN:
2559        case OP_EOD:
2560        case OP_CIRC:
2561        case OP_CIRCM:
2562        case OP_DOLL:
2563        case OP_DOLLM:
2564        /* Zero width assertions. */
2565        cc++;
2566        continue;
2567    
2568        case OP_PLUS:
2569        case OP_MINPLUS:
2570        case OP_POSPLUS:
2571        cc++;
2572        break;
2573    
2574        case OP_EXACT:
2575        cc += 1 + IMM2_SIZE;
2576        break;
2577    
2578        case OP_PLUSI:
2579        case OP_MINPLUSI:
2580        case OP_POSPLUSI:
2581        caseless = 1;
2582        cc++;
2583        break;
2584    
2585        case OP_EXACTI:
2586        caseless = 1;
2587        cc += 1 + IMM2_SIZE;
2588        break;
2589    
2590        default:
2591        return FALSE;
2592        }
2593    
2594      len = 1;
2595    #ifdef SUPPORT_UTF
2596      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2597    #endif
2598    
2599      if (caseless && char_has_othercase(common, cc))
2600        {
2601        caseless = char_get_othercase_bit(common, cc);
2602        if (caseless == 0)
2603          return FALSE;
2604    #ifdef COMPILE_PCRE8
2605        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2606    #else
2607        if ((caseless & 0x100) != 0)
2608          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2609        else
2610          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2611    #endif
2612        }
2613      else
2614        caseless = 0;
2615    
2616      while (len > 0 && location < 2 * 2)
2617        {
2618        c = *cc;
2619        bit = 0;
2620        if (len == (caseless & 0xff))
2621          {
2622          bit = caseless >> 8;
2623          c |= bit;
2624          }
2625    
2626        chars[location] = c;
2627        chars[location + 1] = bit;
2628    
2629        len--;
2630        location += 2;
2631        cc++;
2632        }
2633    
2634      if (location == 2 * 2)
2635        break;
2636      else if (must_end)
2637        return FALSE;
2638      }
2639    
2640    if (firstline)
2641      {
2642      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2643      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);
2644      }
2645    else
2646      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2647    
2648    start = LABEL();
2649    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2650    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2651    #ifdef COMPILE_PCRE8
2652    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2653    #else /* COMPILE_PCRE8 */
2654    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2655    #endif
2656    
2657    #else /* SLJIT_UNALIGNED */
2658    
2659    #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN
2660    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2661    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2662    #else /* SLJIT_BIG_ENDIAN */
2663    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2664    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2665    #endif /* SLJIT_BIG_ENDIAN */
2666    
2667    #ifdef COMPILE_PCRE8
2668    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);
2669    #else /* COMPILE_PCRE8 */
2670    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);
2671    #endif
2672    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
2673    
2674    #endif
2675    
2676    if (chars[1] != 0 || chars[3] != 0)
2677      {
2678      pair.asuchars[0] = chars[1];
2679      pair.asuchars[1] = chars[3];
2680      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);
2681      }
2682    
2683    pair.asuchars[0] = chars[0];
2684    pair.asuchars[1] = chars[2];
2685    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);
2686    
2687    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2688    JUMPTO(SLJIT_JUMP, start);
2689    JUMPHERE(found);
2690    JUMPHERE(leave);
2691    
2692    if (firstline)
2693      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2694    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);
2695    return TRUE;
2696    }
2697    
2698    static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2699  {  {
2700  DEFINE_COMPILER;  DEFINE_COMPILER;
2701  struct sljit_label *start;  struct sljit_label *start;
2702  struct sljit_jump *leave;  struct sljit_jump *leave;
2703  struct sljit_jump *found;  struct sljit_jump *found;
2704  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2705    
2706  if (firstline)  if (firstline)
2707    {    {
2708    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2709    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);
2710    }    }
2711    
2712  start = LABEL();  start = LABEL();
2713  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2714  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2715    
2716  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2717    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2718      {
2719      oc = TABLE_GET(first_char, common->fcc, first_char);
2720    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2721      if (first_char > 127 && common->utf)
2722        oc = UCD_OTHERCASE(first_char);
2723    #endif
2724      }
2725    if (first_char == oc)
2726      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2727  else  else
2728    {    {
2729    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2730    if (ispowerof2(bit))    if (ispowerof2(bit))
2731      {      {
2732      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2733      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2734      }      }
2735    else    else
2736      {      {
2737      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);
2738      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2739      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);
2740      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 1772  else Line 2742  else
2742      }      }
2743    }    }
2744    
2745  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 if (common->utf8)  
   {  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #endif  
2746  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2747  JUMPHERE(found);  JUMPHERE(found);
2748  JUMPHERE(leave);  JUMPHERE(leave);
# Line 1805  jump_list *newline = NULL; Line 2765  jump_list *newline = NULL;
2765  if (firstline)  if (firstline)
2766    {    {
2767    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2768    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);
2769    }    }
2770    
2771  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1816  if (common->nltype == NLTYPE_FIXED && co Line 2776  if (common->nltype == NLTYPE_FIXED && co
2776    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));
2777    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2778    
2779    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2780    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);
2781    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2782    #ifdef COMPILE_PCRE16
2783      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2784    #endif
2785    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2786    
2787    loop = LABEL();    loop = LABEL();
2788    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));
2789    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2790    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2791    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2792    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);
2793    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);
2794    
# Line 1856  if (common->nltype == NLTYPE_ANY || comm Line 2819  if (common->nltype == NLTYPE_ANY || comm
2819    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2820    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2821    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2822    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2823    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);
2824    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2825    #ifdef COMPILE_PCRE16
2826      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2827    #endif
2828    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2829    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2830    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1876  DEFINE_COMPILER; Line 2842  DEFINE_COMPILER;
2842  struct sljit_label *start;  struct sljit_label *start;
2843  struct sljit_jump *leave;  struct sljit_jump *leave;
2844  struct sljit_jump *found;  struct sljit_jump *found;
2845    #ifndef COMPILE_PCRE8
2846    struct sljit_jump *jump;
2847    #endif
2848    
2849  if (firstline)  if (firstline)
2850    {    {
2851    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2852    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);
2853    }    }
2854    
2855  start = LABEL();  start = LABEL();
2856  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2857  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2858  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2859  if (common->utf8)  if (common->utf)
2860    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2861    #endif
2862    #ifndef COMPILE_PCRE8
2863    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2864    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2865    JUMPHERE(jump);
2866  #endif  #endif
2867  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2868  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1897  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2871  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2871  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);
2872  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2873    
2874  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2875  if (common->utf8)  if (common->utf)
2876    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2877  else  #endif
2878    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));
2879  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2880  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2881      {
2882      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2883      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2884      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2885      }
2886    #endif
2887    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2888    if (common->utf)
2889      {
2890      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2891      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2892      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2893      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2894      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2895      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2896      }
2897  #endif  #endif
2898  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2899  JUMPHERE(found);  JUMPHERE(found);
# Line 1913  if (firstline) Line 2903  if (firstline)
2903    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2904  }  }
2905    
2906  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)
2907  {  {
2908  DEFINE_COMPILER;  DEFINE_COMPILER;
2909  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1922  struct sljit_jump *alreadyfound; Line 2912  struct sljit_jump *alreadyfound;
2912  struct sljit_jump *found;  struct sljit_jump *found;
2913  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2914  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2915  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2916    
2917  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2918    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2919  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);
2920  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2921  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2922    
2923  if (has_firstbyte)  if (has_firstchar)
2924    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2925  else  else
2926    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2927    
2928  loop = LABEL();  loop = LABEL();
2929  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2930    
2931  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2932  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2933    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2934      {
2935      oc = TABLE_GET(req_char, common->fcc, req_char);
2936    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2937      if (req_char > 127 && common->utf)
2938        oc = UCD_OTHERCASE(req_char);
2939    #endif
2940      }
2941    if (req_char == oc)
2942      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2943  else  else
2944    {    {
2945    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2946    if (ispowerof2(bit))    if (ispowerof2(bit))
2947      {      {
2948      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2949      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2950      }      }
2951    else    else
2952      {      {
2953      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2954      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2955      }      }
2956    }    }
2957  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2958  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2959    
2960  JUMPHERE(found);  JUMPHERE(found);
2961  if (foundoc)  if (foundoc)
2962    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2963  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);
2964  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2965  JUMPHERE(toolong);  JUMPHERE(toolong);
2966  return notfound;  return notfound;
# Line 1971  return notfound; Line 2969  return notfound;
2969  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2970  {  {
2971  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2972  struct sljit_jump *jump;  struct sljit_jump *jump;
2973  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2974    
2975  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2976  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2977    GET_LOCAL_BASE(TMP3, 0, 0);
2978    
2979  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2980  mainloop = LABEL();  mainloop = LABEL();
2981  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2982  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);
2983  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
2984  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));
2985  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));
2986  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 1992  JUMPTO(SLJIT_JUMP, mainloop); Line 2989  JUMPTO(SLJIT_JUMP, mainloop);
2989  JUMPHERE(jump);  JUMPHERE(jump);
2990  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2991  /* End of dropping frames. */  /* End of dropping frames. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
 CMPTO(SLJIT_C_GREATER_EQUAL, TMP1, 0, STACK_TOP, 0, mainloop);  
 JUMPHERE(earlyexit);  
2992  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2993    
2994  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
2995  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2996  /* Set max index. */  /* Set string begin. */
2997  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2998  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));
2999  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
3000  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3001    
3002  JUMPHERE(jump);  JUMPHERE(jump);
3003    if (common->mark_ptr != 0)
3004      {
3005      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3006      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
3007      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
3008      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3009      JUMPTO(SLJIT_JUMP, mainloop);
3010    
3011      JUMPHERE(jump);
3012      }
3013    
3014  /* Unknown command. */  /* Unknown command. */
3015  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));
3016  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 2022  JUMPTO(SLJIT_JUMP, mainloop); Line 3019  JUMPTO(SLJIT_JUMP, mainloop);
3019  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3020  {  {
3021  DEFINE_COMPILER;  DEFINE_COMPILER;
3022  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3023  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3024  struct sljit_jump *jump;  struct sljit_jump *jump;
3025  #endif  #endif
3026    
3027  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3028    
3029  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);
3030  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3031  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3032  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));
3033  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3034  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3035  skip_char_back(common);  skip_char_back(common);
3036    check_start_used_ptr(common);
3037  read_char(common);  read_char(common);
3038    
3039  /* Testing char type. */  /* Testing char type. */
3040  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3041  if (common->useucp)  if (common->use_ucp)
3042    {    {
3043    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3044    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2057  if (common->useucp) Line 3055  if (common->useucp)
3055  else  else
3056  #endif  #endif
3057    {    {
3058  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3059      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3060    #elif defined SUPPORT_UTF
3061    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
3062    jump = NULL;    jump = NULL;
3063    if (common->utf8)    if (common->utf)
3064      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3065  #endif  #endif /* COMPILE_PCRE8 */
3066    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
3067    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
3068    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3069    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
3070  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3071      JUMPHERE(jump);
3072    #elif defined SUPPORT_UTF
3073    if (jump != NULL)    if (jump != NULL)
3074      JUMPHERE(jump);      JUMPHERE(jump);
3075  #endif  #endif /* COMPILE_PCRE8 */
3076    }    }
3077  JUMPHERE(beginend);  JUMPHERE(skipread);
3078    
3079  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3080  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3081  peek_char(common);  peek_char(common);
3082    
3083  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3084  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3085  if (common->useucp)  if (common->use_ucp)
3086    {    {
3087    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3088    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2096  if (common->useucp) Line 3098  if (common->useucp)
3098  else  else
3099  #endif  #endif
3100    {    {
3101  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3102      /* TMP2 may be destroyed by peek_char. */
3103      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3104      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3105    #elif defined SUPPORT_UTF
3106    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3107    jump = NULL;    jump = NULL;
3108    if (common->utf8)    if (common->utf)
3109      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3110  #endif  #endif
3111    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3112    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3113    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3114  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
3115      JUMPHERE(jump);
3116    #elif defined SUPPORT_UTF
3117    if (jump != NULL)    if (jump != NULL)
3118      JUMPHERE(jump);      JUMPHERE(jump);
3119  #endif  #endif /* COMPILE_PCRE8 */
3120    }    }
3121  JUMPHERE(beginend);  JUMPHERE(skipread);
3122    
3123  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);
3124  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2121  static void check_anynewline(compiler_co Line 3129  static void check_anynewline(compiler_co
3129  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3130  DEFINE_COMPILER;  DEFINE_COMPILER;
3131    
3132  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3133    
3134  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3135  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);
3136  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3137  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);
3138  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3139  if (common->utf8)  #ifdef COMPILE_PCRE8
3140    if (common->utf)
3141    {    {
3142    #endif
3143    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3144    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3145    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);
3146    #ifdef COMPILE_PCRE8
3147    }    }
3148  #endif  #endif
3149    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3150  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3151  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3152  }  }
# Line 2144  static void check_hspace(compiler_common Line 3156  static void check_hspace(compiler_common
3156  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3157  DEFINE_COMPILER;  DEFINE_COMPILER;
3158    
3159  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3160    
3161  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);
3162  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3163  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);
3164  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3165  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);
3166  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3167  if (common->utf8)  #ifdef COMPILE_PCRE8
3168    if (common->utf)
3169    {    {
3170    #endif
3171    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3172    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);
3173    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2167  if (common->utf8) Line 3181  if (common->utf8)
3181    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);
3182    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
3183    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);
3184    #ifdef COMPILE_PCRE8
3185    }    }
3186  #endif  #endif
3187    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3188  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3189    
3190  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2179  static void check_vspace(compiler_common Line 3195  static void check_vspace(compiler_common
3195  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3196  DEFINE_COMPILER;  DEFINE_COMPILER;
3197    
3198  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3199    
3200  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3201  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);
3202  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
3203  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);
3204  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3205  if (common->utf8)  #ifdef COMPILE_PCRE8
3206    if (common->utf)
3207    {    {
3208    #endif
3209    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3210    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3211    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);
3212    #ifdef COMPILE_PCRE8
3213    }    }
3214  #endif  #endif
3215    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
3216  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
3217    
3218  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2207  DEFINE_COMPILER; Line 3227  DEFINE_COMPILER;
3227  struct sljit_jump *jump;  struct sljit_jump *jump;
3228  struct sljit_label *label;  struct sljit_label *label;
3229    
3230  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3231  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3232  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3233  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
3234  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3235  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));
3236    
3237  label = LABEL();  label = LABEL();
3238  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3239  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3240  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3241  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));
3242  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3243    
3244  JUMPHERE(jump);  JUMPHERE(jump);
3245  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));
3246  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
3247  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3248  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2236  DEFINE_COMPILER; Line 3256  DEFINE_COMPILER;
3256  struct sljit_jump *jump;  struct sljit_jump *jump;
3257  struct sljit_label *label;  struct sljit_label *label;
3258    
3259  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3260  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3261    
3262  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
3263  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
3264  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
3265  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
3266  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
3267  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));
3268    
3269  label = LABEL();  label = LABEL();
3270  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
3271  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3272    #ifndef COMPILE_PCRE8
3273    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
3274    #endif
3275  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
3276    #ifndef COMPILE_PCRE8
3277    JUMPHERE(jump);
3278    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
3279    #endif
3280  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
3281    #ifndef COMPILE_PCRE8
3282    JUMPHERE(jump);
3283    #endif
3284  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
3285  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));
3286  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
3287    
3288  JUMPHERE(jump);  JUMPHERE(jump);
3289  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));
3290  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
3291  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3292  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2267  sljit_emit_fast_return(compiler, RETURN_ Line 3297  sljit_emit_fast_return(compiler, RETURN_
3297  #undef CHAR1  #undef CHAR1
3298  #undef CHAR2  #undef CHAR2
3299    
3300  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
3301    
3302  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)
3303  {  {
3304  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3305  int c1, c2;  int c1, c2;
3306  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3307  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
3308    
3309  while (src1 < end1)  while (src1 < end1)
3310    {    {
3311    if (src2 >= end2)    if (src2 >= end2)
3312      return 0;      return (pcre_uchar*)1;
3313    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3314    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3315    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
3316    }    }
3317  return src2;  return src2;
3318  }  }
3319    
3320  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3321    
3322  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,
3323      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3324  {  {
3325  DEFINE_COMPILER;  DEFINE_COMPILER;
3326  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
3327  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
3328  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3329  int utf8length;  int utflength;
3330  #endif  #endif
3331    
3332  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2306  if (caseless && char_has_othercase(commo Line 3334  if (caseless && char_has_othercase(commo
3334    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3335    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3336    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3337    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
3338      othercasechar = cc + (othercasebit >> 8);
3339    othercasebit &= 0xff;    othercasebit &= 0xff;
3340    #else
3341    #ifdef COMPILE_PCRE16
3342      othercasechar = cc + (othercasebit >> 9);
3343      if ((othercasebit & 0x100) != 0)
3344        othercasebit = (othercasebit & 0xff) << 8;
3345      else
3346        othercasebit &= 0xff;
3347    #endif
3348    #endif
3349    }    }
3350    
3351  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3352    {    {
3353    #ifdef COMPILE_PCRE8
3354  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3355    if (context->length >= 4)    if (context->length >= 4)
3356      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3357    else if (context->length >= 2)    else if (context->length >= 2)
3358      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3359    else    else
3360  #endif  #endif
3361      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3362    #else
3363    #ifdef COMPILE_PCRE16
3364    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3365      if (context->length >= 4)
3366        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3367      else
3368    #endif
3369        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3370    #endif
3371    #endif /* COMPILE_PCRE8 */
3372    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3373    }    }
3374    
3375  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3376  utf8length = 1;  utflength = 1;
3377  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
3378    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
3379    
3380  do  do
3381    {    {
3382  #endif  #endif
3383    
3384    context->length--;    context->length -= IN_UCHARS(1);
3385  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3386    
3387    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3388    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3389      {      {
3390      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
3391      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
3392      }      }
3393    else    else
3394      {      {
3395      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
3396      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
3397      }      }
3398    context->byteptr++;    context->ucharptr++;
3399    
3400    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
3401      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3402    #else
3403      if (context->ucharptr >= 2 || context->length == 0)
3404    #endif
3405      {      {
3406      if (context->length >= 4)      if (context->length >= 4)
3407        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);
3408    #ifdef COMPILE_PCRE8
3409      else if (context->length >= 2)      else if (context->length >= 2)
3410        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);
3411      else if (context->length >= 1)      else if (context->length >= 1)
3412        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);
3413    #else
3414        else if (context->length >= 2)
3415          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3416    #endif
3417      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3418    
3419      switch(context->byteptr)      switch(context->ucharptr)
3420        {        {
3421        case 4:        case 4 / sizeof(pcre_uchar):
3422        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3423          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);
3424        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));
3425        break;        break;
3426    
3427        case 2:        case 2 / sizeof(pcre_uchar):
3428        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3429          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);
3430        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));
3431        break;        break;
3432    
3433    #ifdef COMPILE_PCRE8
3434        case 1:        case 1:
3435        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3436          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);
3437        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));
3438        break;        break;
3439    #endif
3440    
3441        default:        default:
3442        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3443        break;        break;
3444        }        }
3445      context->byteptr = 0;      context->ucharptr = 0;
3446      }      }
3447    
3448  #else  #else
3449    
3450    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
3451    #ifdef COMPILE_PCRE8
3452    if (context->length > 0)    if (context->length > 0)
3453      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);
3454    #else
3455      if (context->length > 0)
3456        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3457    #endif
3458    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3459    
3460    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
3461      {      {
3462      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3463      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));
3464      }      }
3465    else    else
3466      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));
3467    
3468  #endif  #endif
3469    
3470    cc++;    cc++;
3471  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3472    utf8length--;    utflength--;
3473    }    }
3474  while (utf8length > 0);  while (utflength > 0);
3475  #endif  #endif
3476    
3477  return cc;  return cc;
3478  }  }
3479    
3480  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3481    
3482  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
3483    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2434  return cc; Line 3499  return cc;
3499      } \      } \
3500    charoffset = (value);    charoffset = (value);
3501    
3502  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)
3503  {  {
3504  DEFINE_COMPILER;  DEFINE_COMPILER;
3505  jump_list *found = NULL;  jump_list *found = NULL;
3506  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3507  unsigned int c;  unsigned int c;
3508  int compares;  int compares;
3509  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3510  uschar *ccbegin;  pcre_uchar *ccbegin;
3511  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3512  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3513  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3514  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
3515    unsigned int typeoffset;
3516  #endif  #endif
3517  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
3518    unsigned int charoffset;
3519    
3520  /* 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. */
3521  check_input_end(common, fallbacks);  detect_partial_match(common, backtracks);
3522  read_char(common);  read_char(common);
3523    
3524  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
3525    {    {
3526    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3527    if (common->utf8)  #ifndef COMPILE_PCRE8
3528      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3529    #elif defined SUPPORT_UTF
3530      if (common->utf)
3531      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3532    #endif
3533    
3534    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3535    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2467  if ((*cc++ & XCL_MAP) != 0) Line 3538  if ((*cc++ & XCL_MAP) != 0)
3538    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);
3539    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3540    
3541    if (common->utf8)  #ifndef COMPILE_PCRE8
3542      JUMPHERE(jump);
3543    #elif defined SUPPORT_UTF
3544      if (common->utf)
3545      JUMPHERE(jump);      JUMPHERE(jump);
3546    #endif
3547    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3548  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3549    charsaved = TRUE;    charsaved = TRUE;
3550  #endif  #endif
3551    cc += 32;    cc += 32 / sizeof(pcre_uchar);
3552    }    }
3553    
3554  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2485  while (*cc != XCL_END) Line 3560  while (*cc != XCL_END)
3560    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3561      {      {
3562      cc += 2;      cc += 2;
3563  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3564      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]);
3565  #endif  #endif
3566  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3567      needschar = TRUE;      needschar = TRUE;
# Line 2495  while (*cc != XCL_END) Line 3570  while (*cc != XCL_END)
3570    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3571      {      {
3572      cc += 2;      cc += 2;
3573  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3574      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]);
3575  #endif  #endif
3576      cc++;      cc++;
3577  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3578      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]);
3579  #endif  #endif
3580  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3581      needschar = TRUE;      needschar = TRUE;
# Line 2570  if (needstype || needsscript) Line 3645  if (needstype || needsscript)
3645      {      {
3646      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3647        {        {
3648        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));
3649        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3650        }        }
3651      else      else
3652        {        {
3653        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3654        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));
3655        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3656        }        }
3657      }      }
# Line 2594  typeoffset = 0; Line 3669  typeoffset = 0;
3669  while (*cc != XCL_END)  while (*cc != XCL_END)
3670    {    {
3671    compares--;    compares--;
3672    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3673    jump = NULL;    jump = NULL;
3674    
3675    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3676      {      {
3677      cc ++;      cc ++;
3678  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3679      if (common->utf8)      if (common->utf)
3680        {        {
3681        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3682        }        }
# Line 2631  while (*cc != XCL_END) Line 3706  while (*cc != XCL_END)
3706    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3707      {      {
3708      cc ++;      cc ++;
3709  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3710      if (common->utf8)      if (common->utf)
3711        {        {
3712        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3713        }        }
# Line 2640  while (*cc != XCL_END) Line 3715  while (*cc != XCL_END)
3715  #endif  #endif
3716        c = *cc++;        c = *cc++;
3717      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3718  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3719      if (common->utf8)      if (common->utf)
3720        {        {
3721        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3722        }        }
# Line 2676  while (*cc != XCL_END) Line 3751  while (*cc != XCL_END)
3751      switch(*cc)      switch(*cc)
3752        {        {
3753        case PT_ANY:        case PT_ANY:
3754        if (list != fallbacks)        if (list != backtracks)
3755          {          {
3756          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))
3757            continue;            continue;
# Line 2697  while (*cc != XCL_END) Line 3772  while (*cc != XCL_END)
3772        break;        break;
3773    
3774        case PT_GC:        case PT_GC:
3775        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3776        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3777        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);
3778        break;        break;
3779    
3780        case PT_PC:        case PT_PC:
# Line 2749  while (*cc != XCL_END) Line 3824  while (*cc != XCL_END)
3824  #endif  #endif
3825    
3826    if (jump != NULL)    if (jump != NULL)
3827      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
3828    }    }
3829    
3830  if (found != NULL)  if (found != NULL)
# Line 2761  if (found != NULL) Line 3836  if (found != NULL)
3836    
3837  #endif  #endif
3838    
3839  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)
3840  {  {
3841  DEFINE_COMPILER;  DEFINE_COMPILER;
3842  int length;  int length;
3843  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3844  compare_context context;  compare_context context;
3845  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3846  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3847  struct sljit_label *label;  struct sljit_label *label;
3848  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3849  uschar propdata[5];  pcre_uchar propdata[5];
3850  #endif  #endif
3851  #endif  #endif
3852    
# Line 2780  switch(type) Line 3855  switch(type)
3855    case OP_SOD:    case OP_SOD:
3856    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3857    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));
3858    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));
3859    return cc;    return cc;
3860    
3861    case OP_SOM:    case OP_SOM:
3862    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3863    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));
3864    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));
3865    return cc;    return cc;
3866    
3867    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
3868    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
3869    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
3870    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));
3871    return cc;    return cc;
3872    
3873    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3874    case OP_DIGIT:    case OP_DIGIT:
3875    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3876    read_char8_type(common);    read_char8_type(common);
3877    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);
3878    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));
3879    return cc;    return cc;
3880    
3881    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3882    case OP_WHITESPACE:    case OP_WHITESPACE:
3883    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3884    read_char8_type(common);    read_char8_type(common);
3885    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);
3886    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));
3887    return cc;    return cc;
3888    
3889    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3890    case OP_WORDCHAR:    case OP_WORDCHAR:
3891    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3892    read_char8_type(common);    read_char8_type(common);
3893    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);
3894    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));
3895    return cc;    return cc;
3896    
3897    case OP_ANY:    case OP_ANY:
3898    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3899    read_char(common);    read_char(common);
3900    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3901      {      {
3902      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);
3903      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3904      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3905      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      else
3906      JUMPHERE(jump[1]);        jump[1] = check_str_end(common);
3907    
3908        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3909        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3910        if (jump[1] != NULL)
3911          JUMPHERE(jump[1]);
3912      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3913      }      }
3914    else    else
3915      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
3916    return cc;    return cc;
3917    
3918    case OP_ALLANY:    case OP_ALLANY:
3919    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3920  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3921    if (common->utf8)    if (common->utf)
3922      {      {
3923      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3924      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3925    #ifdef COMPILE_PCRE8
3926        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3927        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3928      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3929    #else /* COMPILE_PCRE8 */
3930    #ifdef COMPILE_PCRE16
3931        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3932        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3933        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3934        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3935        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3936        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3937    #endif /* COMPILE_PCRE16 */
3938    #endif /* COMPILE_PCRE8 */
3939        JUMPHERE(jump[0]);
3940      return cc;      return cc;
3941      }      }
3942  #endif  #endif
3943    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));
3944    return cc;    return cc;
3945    
3946  #ifdef SUPPORT_UTF8    case OP_ANYBYTE:
3947      detect_partial_match(common, backtracks);
3948      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3949      return cc;
3950    
3951    #ifdef SUPPORT_UTF
3952  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3953    case OP_NOTPROP:    case OP_NOTPROP:
3954    case OP_PROP:    case OP_PROP:
# Line 2858  switch(type) Line 3957  switch(type)
3957    propdata[2] = cc[0];    propdata[2] = cc[0];
3958    propdata[3] = cc[1];    propdata[3] = cc[1];
3959    propdata[4] = XCL_END;    propdata[4] = XCL_END;
3960    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_trypath(common, propdata, backtracks);
3961    return cc + 2;    return cc + 2;
3962  #endif  #endif
3963  #endif  #endif
3964    
3965    case OP_ANYNL:    case OP_ANYNL:
3966    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3967    read_char(common);    read_char(common);
3968    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);
3969    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3970    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3971        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3972      else
3973        jump[1] = check_str_end(common);
3974      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3975    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);
3976    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));
3977    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3978    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3979    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
3980    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3981    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
3982    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 2881  switch(type) Line 3984  switch(type)
3984    
3985    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3986    case OP_HSPACE:    case OP_HSPACE:
3987    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3988    read_char(common);    read_char(common);
3989    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3990    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));
3991    return cc;    return cc;
3992    
3993    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3994    case OP_VSPACE:    case OP_VSPACE:
3995    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
3996    read_char(common);    read_char(common);
3997    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3998    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));
3999    return cc;    return cc;
4000    
4001  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4002    case OP_EXTUNI:    case OP_EXTUNI:
4003    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4004    read_char(common);    read_char(common);
4005    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4006    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
4007    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));
4008    
4009    label = LABEL();    label = LABEL();
4010    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 2913  switch(type) Line 4016  switch(type)
4016    
4017    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4018    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4019      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4020        {
4021        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4022        /* Since we successfully read a char above, partial matching must occure. */
4023        check_partial(common, TRUE);
4024        JUMPHERE(jump[0]);
4025        }
4026    return cc;    return cc;
4027  #endif  #endif
4028    
4029    case OP_EODN:    case OP_EODN:
4030      /* Requires rather complex checks. */
4031    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);
4032    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4033      {      {
4034      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4035      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4036      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
4037      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));
4038      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      else
4039      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));        {
4040          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4041          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4042          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
4043          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4044          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
4045          add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4046          check_partial(common, TRUE);
4047          add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
4048          JUMPHERE(jump[1]);
4049          }
4050        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
4051        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
4052        add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
4053      }      }
4054    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
4055      {      {
4056      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4057      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4058      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));
4059      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));
4060      }      }
4061    else    else
4062      {      {
4063      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
4064      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);
4065      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
4066      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);
4067      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);