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