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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 836 by ph10, Wed Dec 28 17:16:11 2011 UTC revision 1245 by zherczeg, Sat Feb 9 11:30:51 2013 UTC
# Line 46  POSSIBILITY OF SUCH DAMAGE. Line 46  POSSIBILITY OF SUCH DAMAGE.
46    
47  #include "pcre_internal.h"  #include "pcre_internal.h"
48    
49  #ifdef SUPPORT_JIT  #if defined SUPPORT_JIT
50    
51  /* All-in-one: Since we use the JIT compiler only from here,  /* All-in-one: Since we use the JIT compiler only from here,
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
# Line 65  system files. */ Line 65  system files. */
65  #error Unsupported architecture  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory for the regex stack on the real machine stack.
69  #define LOCAL_SPACE_SIZE 32768  Fast, but limited size. */
70    #define MACHINE_STACK_SIZE 32768
71    
72    /* Growth rate for stack allocated by the OS. Should be the multiply
73    of page size. */
74  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
75    
76  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 82  The code generator follows the recursive Line 85  The code generator follows the recursive
85  expressions. The basic blocks of regular expressions are condition checkers  expressions. The basic blocks of regular expressions are condition checkers
86  whose execute different commands depending on the result of the condition check.  whose execute different commands depending on the result of the condition check.
87  The relationship between the operators can be horizontal (concatenation) and  The relationship between the operators can be horizontal (concatenation) and
88  vertical (sub-expression) (See struct fallback_common for more details).  vertical (sub-expression) (See struct backtrack_common for more details).
89    
90    'ab' - 'a' and 'b' regexps are concatenated    'ab' - 'a' and 'b' regexps are concatenated
91    'a+' - 'a' is the sub-expression of the '+' operator    'a+' - 'a' is the sub-expression of the '+' operator
92    
93  The condition checkers are boolean (true/false) checkers. Machine code is generated  The condition checkers are boolean (true/false) checkers. Machine code is generated
94  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.
95  The 'true' case is called as the hot path (expected path), and the other is called as  The 'true' case is called as the matching path (expected path), and the other is called as
96  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
97  branches on the hot path.  branches on the matching path.
98    
99   Greedy star operator (*) :   Greedy star operator (*) :
100     Hot path: match happens.     Matching path: match happens.
101     Fallback path: match failed.     Backtrack path: match failed.
102   Non-greedy star operator (*?) :   Non-greedy star operator (*?) :
103     Hot path: no need to perform a match.     Matching path: no need to perform a match.
104     Fallback path: match is required.     Backtrack path: match is required.
105    
106  The following example shows how the code generated for a capturing bracket  The following example shows how the code generated for a capturing bracket
107  with two alternatives. Let A, B, C, D are arbirary regular expressions, and  with two alternatives. Let A, B, C, D are arbirary regular expressions, and
# Line 108  we have the following regular expression Line 111  we have the following regular expression
111    
112  The generated code will be the following:  The generated code will be the following:
113    
114   A hot path   A matching path
115   '(' hot path (pushing arguments to the stack)   '(' matching path (pushing arguments to the stack)
116   B hot path   B matching path
117   ')' hot path (pushing arguments to the stack)   ')' matching path (pushing arguments to the stack)
118   D hot path   D matching path
119   return with successful match   return with successful match
120    
121   D fallback path   D backtrack path
122   ')' 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")
123   B fallback path   B backtrack path
124   C expected path   C expected path
125   jump to D hot path   jump to D matching path
126   C fallback path   C backtrack path
127   A fallback path   A backtrack path
128    
129   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
130   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
131   to the current fallback code path. The fallback code path must check   to the current backtrack code path. The backtrack path must check
132   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
133   the hot path eventually. Otherwise it needs to clear out its own stack   the matching path eventually. Otherwise it needs to clear out its own stack
134   frame and continue the execution on the fallback code paths.   frame and continue the execution on the backtrack code paths.
135  */  */
136    
137  /*  /*
138  Saved stack frames:  Saved stack frames:
139    
140  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
141  when the fallback mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
142  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
143  mechanism.  mechanism.
144    
145  The stack frames are stored in a chain list, and have the following format:  The stack frames are stored in a chain list, and have the following format:
146  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
147    
148  Thus we can restore the locals to a particular point in the stack.  Thus we can restore the private data to a particular point in the stack.
149  */  */
150    
151  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 152  typedef struct jit_arguments { Line 155  typedef struct jit_arguments {
155    const pcre_uchar *begin;    const pcre_uchar *begin;
156    const pcre_uchar *end;    const pcre_uchar *end;
157    int *offsets;    int *offsets;
158    pcre_uchar *ptr;    pcre_uchar *uchar_ptr;
159      pcre_uchar *mark_ptr;
160      void *callout_data;
161    /* Everything else after. */    /* Everything else after. */
162    int offsetcount;    int offset_count;
163    int calllimit;    int call_limit;
164    pcre_uint8 notbol;    pcre_uint8 notbol;
165    pcre_uint8 noteol;    pcre_uint8 noteol;
166    pcre_uint8 notempty;    pcre_uint8 notempty;
167    pcre_uint8 notempty_atstart;    pcre_uint8 notempty_atstart;
168  } jit_arguments;  } jit_arguments;
169    
170  typedef struct executable_function {  typedef struct executable_functions {
171    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
172    pcre_jit_callback callback;    PUBL(jit_callback) callback;
173    void *userdata;    void *userdata;
174    sljit_uw executable_size;    pcre_uint32 top_bracket;
175  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
176    } executable_functions;
177    
178  typedef struct jump_list {  typedef struct jump_list {
179    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 180  typedef struct stub_list { Line 186  typedef struct stub_list {
186    enum stub_types type;    enum stub_types type;
187    int data;    int data;
188    struct sljit_jump *start;    struct sljit_jump *start;
189    struct sljit_label *leave;    struct sljit_label *quit;
190    struct stub_list *next;    struct stub_list *next;
191  } stub_list;  } stub_list;
192    
193  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
194    
195  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
196  code generator. It is allocated by compile_hotpath, and contains  code generator. It is allocated by compile_matchingpath, and contains
197  the aguments for compile_fallbackpath. Must be the first member  the aguments for compile_backtrackingpath. Must be the first member
198  of its descendants. */  of its descendants. */
199  typedef struct fallback_common {  typedef struct backtrack_common {
200    /* Concatenation stack. */    /* Concatenation stack. */
201    struct fallback_common *prev;    struct backtrack_common *prev;
202    jump_list *nextfallbacks;    jump_list *nextbacktracks;
203    /* Internal stack (for component operators). */    /* Internal stack (for component operators). */
204    struct fallback_common *top;    struct backtrack_common *top;
205    jump_list *topfallbacks;    jump_list *topbacktracks;
206    /* Opcode pointer. */    /* Opcode pointer. */
207    pcre_uchar *cc;    pcre_uchar *cc;
208  } fallback_common;  } backtrack_common;
209    
210  typedef struct assert_fallback {  typedef struct assert_backtrack {
211    fallback_common common;    backtrack_common common;
212    jump_list *condfailed;    jump_list *condfailed;
213    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 (-1) if a frame is not needed. */
214    int framesize;    int framesize;
215    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
216    int localptr;    int private_data_ptr;
217    /* For iterators. */    /* For iterators. */
218    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
219  } assert_fallback;  } assert_backtrack;
220    
221  typedef struct bracket_fallback {  typedef struct bracket_backtrack {
222    fallback_common common;    backtrack_common common;
223    /* Where to coninue if an alternative is successfully matched. */    /* Where to coninue if an alternative is successfully matched. */
224    struct sljit_label *althotpath;    struct sljit_label *alternative_matchingpath;
225    /* For rmin and rmax iterators. */    /* For rmin and rmax iterators. */
226    struct sljit_label *recursivehotpath;    struct sljit_label *recursive_matchingpath;
227    /* For greedy ? operator. */    /* For greedy ? operator. */
228    struct sljit_label *zerohotpath;    struct sljit_label *zero_matchingpath;
229    /* Contains the branches of a failed condition. */    /* Contains the branches of a failed condition. */
230    union {    union {
231      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
232      jump_list *condfailed;      jump_list *condfailed;
233      assert_fallback *assert;      assert_backtrack *assert;
234      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. -1 if not needed. */
235      int framesize;      int framesize;
236    } u;    } u;
237    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
238    int localptr;    int private_data_ptr;
239  } bracket_fallback;  } bracket_backtrack;
240    
241  typedef struct bracketpos_fallback {  typedef struct bracketpos_backtrack {
242    fallback_common common;    backtrack_common common;
243    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
244    int localptr;    int private_data_ptr;
245    /* Reverting stack is needed. */    /* Reverting stack is needed. */
246    int framesize;    int framesize;
247    /* Allocated stack size. */    /* Allocated stack size. */
248    int stacksize;    int stacksize;
249  } bracketpos_fallback;  } bracketpos_backtrack;
250    
251  typedef struct braminzero_fallback {  typedef struct braminzero_backtrack {
252    fallback_common common;    backtrack_common common;
253    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
254  } braminzero_fallback;  } braminzero_backtrack;
255    
256  typedef struct iterator_fallback {  typedef struct iterator_backtrack {
257    fallback_common common;    backtrack_common common;
258    /* Next iteration. */    /* Next iteration. */
259    struct sljit_label *hotpath;    struct sljit_label *matchingpath;
260  } iterator_fallback;  } iterator_backtrack;
261    
262  typedef struct recurse_entry {  typedef struct recurse_entry {
263    struct recurse_entry *next;    struct recurse_entry *next;
# Line 263  typedef struct recurse_entry { Line 269  typedef struct recurse_entry {
269    int start;    int start;
270  } recurse_entry;  } recurse_entry;
271    
272  typedef struct recurse_fallback {  typedef struct recurse_backtrack {
273    fallback_common common;    backtrack_common common;
274  } recurse_fallback;  } recurse_backtrack;
275    
276    #define MAX_RANGE_SIZE 6
277    
278  typedef struct compiler_common {  typedef struct compiler_common {
279    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
280    pcre_uchar *start;    pcre_uchar *start;
281    int localsize;  
282    int *localptrs;    /* Maps private data offset to each opcode. */
283    const pcre_uint8 *fcc;    int *private_data_ptrs;
284    sljit_w lcc;    /* Tells whether the capturing bracket is optimized. */
285      pcre_uint8 *optimized_cbracket;
286      /* Starting offset of private data for capturing brackets. */
287    int cbraptr;    int cbraptr;
288      /* OVector starting point. Must be divisible by 2. */
289      int ovector_start;
290      /* Last known position of the requested byte. */
291      int req_char_ptr;
292      /* Head of the last recursion. */
293      int recursive_head_ptr;
294      /* First inspected character for partial matching. */
295      int start_used_ptr;
296      /* Starting pointer for partial soft matches. */
297      int hit_start;
298      /* End pointer of the first line. */
299      int first_line_end;
300      /* Points to the marked string. */
301      int mark_ptr;
302      /* Points to the last matched capture block index. */
303      int capture_last_ptr;
304    
305      /* Flipped and lower case tables. */
306      const pcre_uint8 *fcc;
307      sljit_sw lcc;
308      /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
309      int mode;
310      /* Newline control. */
311    int nltype;    int nltype;
312    int newline;    int newline;
313    int bsr_nltype;    int bsr_nltype;
314      /* Dollar endonly. */
315    int endonly;    int endonly;
316    sljit_w ctypes;    BOOL has_set_som;
317      /* Tables. */
318      sljit_sw ctypes;
319      int digits[2 + MAX_RANGE_SIZE];
320      /* Named capturing brackets. */
321    sljit_uw name_table;    sljit_uw name_table;
322    sljit_w name_count;    sljit_sw name_count;
323    sljit_w name_entry_size;    sljit_sw name_entry_size;
324    struct sljit_label *acceptlabel;  
325      /* Labels and jump lists. */
326      struct sljit_label *partialmatchlabel;
327      struct sljit_label *quit_label;
328      struct sljit_label *forced_quit_label;
329      struct sljit_label *accept_label;
330    stub_list *stubs;    stub_list *stubs;
331    recurse_entry *entries;    recurse_entry *entries;
332    recurse_entry *currententry;    recurse_entry *currententry;
333      jump_list *partialmatch;
334      jump_list *quit;
335      jump_list *forced_quit;
336    jump_list *accept;    jump_list *accept;
337    jump_list *calllimit;    jump_list *calllimit;
338    jump_list *stackalloc;    jump_list *stackalloc;
# Line 303  typedef struct compiler_common { Line 349  typedef struct compiler_common {
349  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
350    BOOL use_ucp;    BOOL use_ucp;
351  #endif  #endif
352    #ifndef COMPILE_PCRE32
353    jump_list *utfreadchar;    jump_list *utfreadchar;
354    #endif
355  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
356    jump_list *utfreadtype8;    jump_list *utfreadtype8;
357  #endif  #endif
# Line 321  typedef struct compare_context { Line 369  typedef struct compare_context {
369  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
370    int ucharptr;    int ucharptr;
371    union {    union {
372      sljit_i asint;      sljit_si asint;
373      sljit_h asshort;      sljit_uh asushort;
374  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
375      sljit_ub asbyte;      sljit_ub asbyte;
376      sljit_ub asuchars[4];      sljit_ub asuchars[4];
377  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
378      sljit_uh asuchars[2];      sljit_uh asuchars[2];
379  #endif  #elif defined COMPILE_PCRE32
380        sljit_ui asuchars[1];
381  #endif  #endif
382    } c;    } c;
383    union {    union {
384      sljit_i asint;      sljit_si asint;
385      sljit_h asshort;      sljit_uh asushort;
386  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
387      sljit_ub asbyte;      sljit_ub asbyte;
388      sljit_ub asuchars[4];      sljit_ub asuchars[4];
389  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
390      sljit_uh asuchars[2];      sljit_uh asuchars[2];
391  #endif  #elif defined COMPILE_PCRE32
392        sljit_ui asuchars[1];
393  #endif  #endif
394    } oc;    } oc;
395  #endif  #endif
# Line 349  typedef struct compare_context { Line 397  typedef struct compare_context {
397    
398  enum {  enum {
399    frame_end = 0,    frame_end = 0,
400    frame_setstrbegin = -1    frame_setstrbegin = -1,
401      frame_setmark = -2
402  };  };
403    
404    /* Undefine sljit macros. */
405    #undef CMP
406    
407  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
408  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
409    
410  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
411  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
412  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
413  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
414  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
415  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
416  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
417  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
418  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
419  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
420    
421  /* Locals layout. */  /* Local space layout. */
422  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
423  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
424  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
425  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
426  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
427  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
428  /* Max limit of recursions. */  /* Max limit of recursions. */
429  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
 /* Last known position of the requested byte. */  
 #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
430  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
431  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
432  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
433  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. */
434  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
435  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
436  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_sw))
437  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
438    
439  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
440  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
441  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
442  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
443  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
444  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
445    #elif defined COMPILE_PCRE32
446    #define MOV_UCHAR  SLJIT_MOV_UI
447    #define MOVU_UCHAR SLJIT_MOVU_UI
448  #else  #else
449  #error Unsupported compiling mode  #error Unsupported compiling mode
450  #endif  #endif
 #endif  
451    
452  /* Shortcuts. */  /* Shortcuts. */
453  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 421  the start pointers when the end of the c Line 468  the start pointers when the end of the c
468    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
469  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
470    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))
471  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
472    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
473    #define GET_LOCAL_BASE(dst, dstw, offset) \
474      sljit_get_local_base(compiler, (dst), (dstw), (offset))
475    
476  static pcre_uchar* bracketend(pcre_uchar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
477  {  {
# Line 435  return cc; Line 484  return cc;
484    
485  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
486   next_opcode   next_opcode
487   get_localspace   get_private_data_length
488   set_localptrs   set_private_data_ptrs
489   get_framesize   get_framesize
490   init_frame   init_frame
491   get_localsize   get_private_data_length_for_copy
492   copy_locals   copy_private_data
493   compile_hotpath   compile_matchingpath
494   compile_fallbackpath   compile_backtrackingpath
495  */  */
496    
497  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
# Line 494  switch(*cc) Line 543  switch(*cc)
543    case OP_BRAZERO:    case OP_BRAZERO:
544    case OP_BRAMINZERO:    case OP_BRAMINZERO:
545    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
546      case OP_COMMIT:
547    case OP_FAIL:    case OP_FAIL:
548    case OP_ACCEPT:    case OP_ACCEPT:
549    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
# Line 632  switch(*cc) Line 682  switch(*cc)
682    case OP_SCBRAPOS:    case OP_SCBRAPOS:
683    return cc + 1 + LINK_SIZE + IMM2_SIZE;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
684    
685      case OP_MARK:
686      return cc + 1 + 2 + cc[1];
687    
688      case OP_CALLOUT:
689      return cc + 2 + 2 * LINK_SIZE;
690    
691    default:    default:
692    return NULL;    return NULL;
693    }    }
694  }  }
695    
696  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  #define CASE_ITERATOR_PRIVATE_DATA_1 \
697        case OP_MINSTAR: \
698        case OP_MINPLUS: \
699        case OP_QUERY: \
700        case OP_MINQUERY: \
701        case OP_MINSTARI: \
702        case OP_MINPLUSI: \
703        case OP_QUERYI: \
704        case OP_MINQUERYI: \
705        case OP_NOTMINSTAR: \
706        case OP_NOTMINPLUS: \
707        case OP_NOTQUERY: \
708        case OP_NOTMINQUERY: \
709        case OP_NOTMINSTARI: \
710        case OP_NOTMINPLUSI: \
711        case OP_NOTQUERYI: \
712        case OP_NOTMINQUERYI:
713    
714    #define CASE_ITERATOR_PRIVATE_DATA_2A \
715        case OP_STAR: \
716        case OP_PLUS: \
717        case OP_STARI: \
718        case OP_PLUSI: \
719        case OP_NOTSTAR: \
720        case OP_NOTPLUS: \
721        case OP_NOTSTARI: \
722        case OP_NOTPLUSI:
723    
724    #define CASE_ITERATOR_PRIVATE_DATA_2B \
725        case OP_UPTO: \
726        case OP_MINUPTO: \
727        case OP_UPTOI: \
728        case OP_MINUPTOI: \
729        case OP_NOTUPTO: \
730        case OP_NOTMINUPTO: \
731        case OP_NOTUPTOI: \
732        case OP_NOTMINUPTOI:
733    
734    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
735        case OP_TYPEMINSTAR: \
736        case OP_TYPEMINPLUS: \
737        case OP_TYPEQUERY: \
738        case OP_TYPEMINQUERY:
739    
740    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
741        case OP_TYPESTAR: \
742        case OP_TYPEPLUS:
743    
744    #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
745        case OP_TYPEUPTO: \
746        case OP_TYPEMINUPTO:
747    
748    static int get_class_iterator_size(pcre_uchar *cc)
749  {  {
750  int localspace = 0;  switch(*cc)
751      {
752      case OP_CRSTAR:
753      case OP_CRPLUS:
754      return 2;
755    
756      case OP_CRMINSTAR:
757      case OP_CRMINPLUS:
758      case OP_CRQUERY:
759      case OP_CRMINQUERY:
760      return 1;
761    
762      case OP_CRRANGE:
763      case OP_CRMINRANGE:
764      if (GET2(cc, 1) == GET2(cc, 1 + IMM2_SIZE))
765        return 0;
766      return 2;
767    
768      default:
769      return 0;
770      }
771    }
772    
773    static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
774    {
775    int private_data_length = 0;
776  pcre_uchar *alternative;  pcre_uchar *alternative;
777    pcre_uchar *name;
778    pcre_uchar *end = NULL;
779    int space, size, i;
780    pcre_uint32 bracketlen;
781    
782  /* 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. */
783  while (cc < ccend)  while (cc < ccend)
784    {    {
785      space = 0;
786      size = 0;
787      bracketlen = 0;
788    switch(*cc)    switch(*cc)
789      {      {
790        case OP_SET_SOM:
791        common->has_set_som = TRUE;
792        cc += 1;
793        break;
794    
795        case OP_REF:
796        case OP_REFI:
797        common->optimized_cbracket[GET2(cc, 1)] = 0;
798        cc += 1 + IMM2_SIZE;
799        break;
800    
801      case OP_ASSERT:      case OP_ASSERT:
802      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
803      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 655  while (cc < ccend) Line 807  while (cc < ccend)
807      case OP_BRAPOS:      case OP_BRAPOS:
808      case OP_SBRA:      case OP_SBRA:
809      case OP_SBRAPOS:      case OP_SBRAPOS:
810      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
811      localspace += sizeof(sljit_w);      bracketlen = 1 + LINK_SIZE;
     cc += 1 + LINK_SIZE;  
812      break;      break;
813    
814      case OP_CBRAPOS:      case OP_CBRAPOS:
815      case OP_SCBRAPOS:      case OP_SCBRAPOS:
816      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
817      cc += 1 + LINK_SIZE + IMM2_SIZE;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
818        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
819      break;      break;
820    
821      case OP_COND:      case OP_COND:
822      /* Might be a hidden SCOND. */      case OP_SCOND:
823      alternative = cc + GET(cc, 1);      /* Only AUTO_CALLOUT can insert this opcode. We do
824      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)         not intend to support this case. */
825        localspace += sizeof(sljit_w);      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
826          return -1;
827    
828        if (*cc == OP_COND)
829          {
830          /* Might be a hidden SCOND. */
831          alternative = cc + GET(cc, 1);
832          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
833            private_data_length += sizeof(sljit_sw);
834          }
835        else
836          private_data_length += sizeof(sljit_sw);
837        bracketlen = 1 + LINK_SIZE;
838        break;
839    
840        case OP_CREF:
841        i = GET2(cc, 1);
842        common->optimized_cbracket[i] = 0;
843        cc += 1 + IMM2_SIZE;
844        break;
845    
846        case OP_NCREF:
847        bracketlen = GET2(cc, 1);
848        name = (pcre_uchar *)common->name_table;
849        alternative = name;
850        for (i = 0; i < common->name_count; i++)
851          {
852          if (GET2(name, 0) == bracketlen) break;
853          name += common->name_entry_size;
854          }
855        SLJIT_ASSERT(i != common->name_count);
856    
857        for (i = 0; i < common->name_count; i++)
858          {
859          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
860            common->optimized_cbracket[GET2(alternative, 0)] = 0;
861          alternative += common->name_entry_size;
862          }
863        bracketlen = 0;
864        cc += 1 + IMM2_SIZE;
865        break;
866    
867        case OP_BRA:
868        bracketlen = 1 + LINK_SIZE;
869        break;
870    
871        case OP_CBRA:
872        case OP_SCBRA:
873        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
874        break;
875    
876        CASE_ITERATOR_PRIVATE_DATA_1
877        space = 1;
878        size = -2;
879        break;
880    
881        CASE_ITERATOR_PRIVATE_DATA_2A
882        space = 2;
883        size = -2;
884        break;
885    
886        CASE_ITERATOR_PRIVATE_DATA_2B
887        space = 2;
888        size = -(2 + IMM2_SIZE);
889        break;
890    
891        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
892        space = 1;
893        size = 1;
894        break;
895    
896        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
897        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
898          space = 2;
899        size = 1;
900        break;
901    
902        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
903        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
904          space = 2;
905        size = 1 + IMM2_SIZE;
906        break;
907    
908        case OP_CLASS:
909        case OP_NCLASS:
910        size += 1 + 32 / sizeof(pcre_uchar);
911        space = get_class_iterator_size(cc + size);
912        break;
913    
914    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
915        case OP_XCLASS:
916        size = GET(cc, 1);
917        space = get_class_iterator_size(cc + size);
918        break;
919    #endif
920    
921        case OP_RECURSE:
922        /* Set its value only once. */
923        if (common->recursive_head_ptr == 0)
924          {
925          common->recursive_head_ptr = common->ovector_start;
926          common->ovector_start += sizeof(sljit_sw);
927          }
928      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
929      break;      break;
930    
931        case OP_CALLOUT:
932        if (common->capture_last_ptr == 0)
933          {
934          common->capture_last_ptr = common->ovector_start;
935          common->ovector_start += sizeof(sljit_sw);
936          }
937        cc += 2 + 2 * LINK_SIZE;
938        break;
939    
940        case OP_MARK:
941        if (common->mark_ptr == 0)
942          {
943          common->mark_ptr = common->ovector_start;
944          common->ovector_start += sizeof(sljit_sw);
945          }
946        cc += 1 + 2 + cc[1];
947        break;
948    
949      default:      default:
950      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
951      if (cc == NULL)      if (cc == NULL)
952        return -1;        return -1;
953      break;      break;
954      }      }
955    
956      if (space > 0 && cc >= end)
957        private_data_length += sizeof(sljit_sw) * space;
958    
959      if (size != 0)
960        {
961        if (size < 0)
962          {
963          cc += -size;
964    #ifdef SUPPORT_UTF
965          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
966    #endif
967          }
968        else
969          cc += size;
970        }
971    
972      if (bracketlen != 0)
973        {
974        if (cc >= end)
975          {
976          end = bracketend(cc);
977          if (end[-1 - LINK_SIZE] == OP_KET)
978            end = NULL;
979          }
980        cc += bracketlen;
981        }
982    }    }
983  return localspace;  return private_data_length;
984  }  }
985    
986  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)  static void set_private_data_ptrs(compiler_common *common, int private_data_ptr, pcre_uchar *ccend)
987  {  {
988  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
989  pcre_uchar *alternative;  pcre_uchar *alternative;
990    pcre_uchar *end = NULL;
991    int space, size, bracketlen;
992    
993  while (cc < ccend)  while (cc < ccend)
994    {    {
995      space = 0;
996      size = 0;
997      bracketlen = 0;
998    switch(*cc)    switch(*cc)
999      {      {
1000      case OP_ASSERT:      case OP_ASSERT:
# Line 702  while (cc < ccend) Line 1007  while (cc < ccend)
1007      case OP_SBRA:      case OP_SBRA:
1008      case OP_SBRAPOS:      case OP_SBRAPOS:
1009      case OP_SCOND:      case OP_SCOND:
1010      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1011      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1012      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1013      break;      break;
1014    
1015      case OP_CBRAPOS:      case OP_CBRAPOS:
1016      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1017      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1018      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1019      cc += 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1020      break;      break;
1021    
1022      case OP_COND:      case OP_COND:
# Line 719  while (cc < ccend) Line 1024  while (cc < ccend)
1024      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1025      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1026        {        {
1027        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1028        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1029        }        }
1030      cc += 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1031        break;
1032    
1033        case OP_BRA:
1034        bracketlen = 1 + LINK_SIZE;
1035        break;
1036    
1037        case OP_CBRA:
1038        case OP_SCBRA:
1039        bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1040        break;
1041    
1042        CASE_ITERATOR_PRIVATE_DATA_1
1043        space = 1;
1044        size = -2;
1045        break;
1046    
1047        CASE_ITERATOR_PRIVATE_DATA_2A
1048        space = 2;
1049        size = -2;
1050        break;
1051    
1052        CASE_ITERATOR_PRIVATE_DATA_2B
1053        space = 2;
1054        size = -(2 + IMM2_SIZE);
1055        break;
1056    
1057        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1058        space = 1;
1059        size = 1;
1060      break;      break;
1061    
1062        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1063        if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1064          space = 2;
1065        size = 1;
1066        break;
1067    
1068        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1069        if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1070          space = 2;
1071        size = 1 + IMM2_SIZE;
1072        break;
1073    
1074        case OP_CLASS:
1075        case OP_NCLASS:
1076        size += 1 + 32 / sizeof(pcre_uchar);
1077        space = get_class_iterator_size(cc + size);
1078        break;
1079    
1080    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1081        case OP_XCLASS:
1082        size = GET(cc, 1);
1083        space = get_class_iterator_size(cc + size);
1084        break;
1085    #endif
1086    
1087      default:      default:
1088      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1089      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1090      break;      break;
1091      }      }
1092    
1093      if (space > 0 && cc >= end)
1094        {
1095        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1096        private_data_ptr += sizeof(sljit_sw) * space;
1097        }
1098    
1099      if (size != 0)
1100        {
1101        if (size < 0)
1102          {
1103          cc += -size;
1104    #ifdef SUPPORT_UTF
1105          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1106    #endif
1107          }
1108        else
1109          cc += size;
1110        }
1111    
1112      if (bracketlen > 0)
1113        {
1114        if (cc >= end)
1115          {
1116          end = bracketend(cc);
1117          if (end[-1 - LINK_SIZE] == OP_KET)
1118            end = NULL;
1119          }
1120        cc += bracketlen;
1121        }
1122    }    }
1123  }  }
1124    
# Line 739  static int get_framesize(compiler_common Line 1128  static int get_framesize(compiler_common
1128  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1129  int length = 0;  int length = 0;
1130  BOOL possessive = FALSE;  BOOL possessive = FALSE;
1131  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1132    BOOL setmark_found = recursive;
1133    
1134  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1135    {    {
# Line 753  while (cc < ccend) Line 1143  while (cc < ccend)
1143    switch(*cc)    switch(*cc)
1144      {      {
1145      case OP_SET_SOM:      case OP_SET_SOM:
1146      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1147      if (!setsom_found)      if (!setsom_found)
1148        {        {
1149        length += 2;        length += 2;
1150        setsom_found = TRUE;        setsom_found = TRUE;
1151        }        }
1152      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1153        break;
1154    
1155        case OP_MARK:
1156        SLJIT_ASSERT(common->mark_ptr != 0);
1157        if (!setmark_found)
1158          {
1159          length += 2;
1160          setmark_found = TRUE;
1161          }
1162        cc += 1 + 2 + cc[1];
1163        break;
1164    
1165        case OP_RECURSE:
1166        if (common->has_set_som && !setsom_found)
1167          {
1168          length += 2;
1169          setsom_found = TRUE;
1170          }
1171        if (common->mark_ptr != 0 && !setmark_found)
1172          {
1173          length += 2;
1174          setmark_found = TRUE;
1175          }
1176        cc += 1 + LINK_SIZE;
1177      break;      break;
1178    
1179      case OP_CBRA:      case OP_CBRA:
# Line 789  static void init_frame(compiler_common * Line 1203  static void init_frame(compiler_common *
1203  {  {
1204  DEFINE_COMPILER;  DEFINE_COMPILER;
1205  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
1206  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
1207    BOOL setmark_found = recursive;
1208  int offset;  int offset;
1209    
1210  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
1211    SLJIT_UNUSED_ARG(stacktop);
1212  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1213    
1214  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 803  while (cc < ccend) Line 1219  while (cc < ccend)
1219    switch(*cc)    switch(*cc)
1220      {      {
1221      case OP_SET_SOM:      case OP_SET_SOM:
1222      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
1223      if (!setsom_found)      if (!setsom_found)
1224        {        {
1225        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1226        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1227        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1228        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1229        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1230        setsom_found = TRUE;        setsom_found = TRUE;
1231        }        }
1232      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
1233        break;
1234    
1235        case OP_MARK:
1236        SLJIT_ASSERT(common->mark_ptr != 0);
1237        if (!setmark_found)
1238          {
1239          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1240          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1241          stackpos += (int)sizeof(sljit_sw);
1242          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1243          stackpos += (int)sizeof(sljit_sw);
1244          setmark_found = TRUE;
1245          }
1246        cc += 1 + 2 + cc[1];
1247        break;
1248    
1249        case OP_RECURSE:
1250        if (common->has_set_som && !setsom_found)
1251          {
1252          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1253          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
1254          stackpos += (int)sizeof(sljit_sw);
1255          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1256          stackpos += (int)sizeof(sljit_sw);
1257          setsom_found = TRUE;
1258          }
1259        if (common->mark_ptr != 0 && !setmark_found)
1260          {
1261          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1262          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
1263          stackpos += (int)sizeof(sljit_sw);
1264          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1265          stackpos += (int)sizeof(sljit_sw);
1266          setmark_found = TRUE;
1267          }
1268        cc += 1 + LINK_SIZE;
1269      break;      break;
1270    
1271      case OP_CBRA:      case OP_CBRA:
# Line 822  while (cc < ccend) Line 1274  while (cc < ccend)
1274      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1275      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1276      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1277      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1278      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1279      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
1280      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1281      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1282      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1283      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1284    
1285      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1286      break;      break;
# Line 843  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 1295  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
1295  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1296  }  }
1297    
1298  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_length_for_copy(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
1299  {  {
1300  int localsize = 2;  int private_data_length = 2;
1301    int size;
1302  pcre_uchar *alternative;  pcre_uchar *alternative;
1303  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1304  while (cc < ccend)  while (cc < ccend)
1305    {    {
1306      size = 0;
1307    switch(*cc)    switch(*cc)
1308      {      {
1309      case OP_ASSERT:      case OP_ASSERT:
# Line 862  while (cc < ccend) Line 1316  while (cc < ccend)
1316      case OP_SBRA:      case OP_SBRA:
1317      case OP_SBRAPOS:      case OP_SBRAPOS:
1318      case OP_SCOND:      case OP_SCOND:
1319      localsize++;      private_data_length++;
1320      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1321      break;      break;
1322    
1323      case OP_CBRA:      case OP_CBRA:
1324      case OP_SCBRA:      case OP_SCBRA:
1325      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1326          private_data_length++;
1327      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1328      break;      break;
1329    
1330      case OP_CBRAPOS:      case OP_CBRAPOS:
1331      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1332      localsize += 2;      private_data_length += 2;
1333      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1334      break;      break;
1335    
# Line 882  while (cc < ccend) Line 1337  while (cc < ccend)
1337      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1338      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1339      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1340        localsize++;        private_data_length++;
1341      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1342      break;      break;
1343    
1344        CASE_ITERATOR_PRIVATE_DATA_1
1345        if (PRIVATE_DATA(cc))
1346          private_data_length++;
1347        cc += 2;
1348    #ifdef SUPPORT_UTF
1349        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1350    #endif
1351        break;
1352    
1353        CASE_ITERATOR_PRIVATE_DATA_2A
1354        if (PRIVATE_DATA(cc))
1355          private_data_length += 2;
1356        cc += 2;
1357    #ifdef SUPPORT_UTF
1358        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1359    #endif
1360        break;
1361    
1362        CASE_ITERATOR_PRIVATE_DATA_2B
1363        if (PRIVATE_DATA(cc))
1364          private_data_length += 2;
1365        cc += 2 + IMM2_SIZE;
1366    #ifdef SUPPORT_UTF
1367        if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1368    #endif
1369        break;
1370    
1371        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1372        if (PRIVATE_DATA(cc))
1373          private_data_length++;
1374        cc += 1;
1375        break;
1376    
1377        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1378        if (PRIVATE_DATA(cc))
1379          private_data_length += 2;
1380        cc += 1;
1381        break;
1382    
1383        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1384        if (PRIVATE_DATA(cc))
1385          private_data_length += 2;
1386        cc += 1 + IMM2_SIZE;
1387        break;
1388    
1389        case OP_CLASS:
1390        case OP_NCLASS:
1391    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1392        case OP_XCLASS:
1393        size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1394    #else
1395        size = 1 + 32 / (int)sizeof(pcre_uchar);
1396    #endif
1397        if (PRIVATE_DATA(cc))
1398          private_data_length += get_class_iterator_size(cc + size);
1399        cc += size;
1400        break;
1401    
1402      default:      default:
1403      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1404      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
# Line 893  while (cc < ccend) Line 1406  while (cc < ccend)
1406      }      }
1407    }    }
1408  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1409  return localsize;  return private_data_length;
1410  }  }
1411    
1412  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1413    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1414  {  {
1415  DEFINE_COMPILER;  DEFINE_COMPILER;
1416  int srcw[2];  int srcw[2];
1417  int count;  int count, size;
1418  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1419  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1420  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
# Line 918  stacktop = STACK(stacktop - 1); Line 1431  stacktop = STACK(stacktop - 1);
1431    
1432  if (!save)  if (!save)
1433    {    {
1434    stackptr += sizeof(sljit_w);    stackptr += sizeof(sljit_sw);
1435    if (stackptr < stacktop)    if (stackptr < stacktop)
1436      {      {
1437      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1438      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1439      tmp1empty = FALSE;      tmp1empty = FALSE;
1440      }      }
1441    if (stackptr < stacktop)    if (stackptr < stacktop)
1442      {      {
1443      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1444      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1445      tmp2empty = FALSE;      tmp2empty = FALSE;
1446      }      }
1447    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
# Line 940  while (status != end) Line 1453  while (status != end)
1453    switch(status)    switch(status)
1454      {      {
1455      case start:      case start:
1456      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1457      count = 1;      count = 1;
1458      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head_ptr;
1459      status = loop;      status = loop;
1460      break;      break;
1461    
# Line 966  while (status != end) Line 1479  while (status != end)
1479        case OP_SBRAPOS:        case OP_SBRAPOS:
1480        case OP_SCOND:        case OP_SCOND:
1481        count = 1;        count = 1;
1482        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1483        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1484        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1485        break;        break;
1486    
1487        case OP_CBRA:        case OP_CBRA:
1488        case OP_SCBRA:        case OP_SCBRA:
1489        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1490        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1491            count = 1;
1492            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1493            }
1494        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1495        break;        break;
1496    
1497        case OP_CBRAPOS:        case OP_CBRAPOS:
1498        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1499        count = 2;        count = 2;
1500          srcw[0] = PRIVATE_DATA(cc);
1501        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1502        srcw[0] = PRIV_DATA(cc);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
       SLJIT_ASSERT(srcw[0] != 0);  
1503        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1504        break;        break;
1505    
# Line 993  while (status != end) Line 1509  while (status != end)
1509        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1510          {          {
1511          count = 1;          count = 1;
1512          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1513          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1514          }          }
1515        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1516        break;        break;
1517    
1518          CASE_ITERATOR_PRIVATE_DATA_1
1519          if (PRIVATE_DATA(cc))
1520            {
1521            count = 1;
1522            srcw[0] = PRIVATE_DATA(cc);
1523            }
1524          cc += 2;
1525    #ifdef SUPPORT_UTF
1526          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1527    #endif
1528          break;
1529    
1530          CASE_ITERATOR_PRIVATE_DATA_2A
1531          if (PRIVATE_DATA(cc))
1532            {
1533            count = 2;
1534            srcw[0] = PRIVATE_DATA(cc);
1535            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1536            }
1537          cc += 2;
1538    #ifdef SUPPORT_UTF
1539          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1540    #endif
1541          break;
1542    
1543          CASE_ITERATOR_PRIVATE_DATA_2B
1544          if (PRIVATE_DATA(cc))
1545            {
1546            count = 2;
1547            srcw[0] = PRIVATE_DATA(cc);
1548            srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1549            }
1550          cc += 2 + IMM2_SIZE;
1551    #ifdef SUPPORT_UTF
1552          if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1553    #endif
1554          break;
1555    
1556          CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1557          if (PRIVATE_DATA(cc))
1558            {
1559            count = 1;
1560            srcw[0] = PRIVATE_DATA(cc);
1561            }
1562          cc += 1;
1563          break;
1564    
1565          CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1566          if (PRIVATE_DATA(cc))
1567            {
1568            count = 2;
1569            srcw[0] = PRIVATE_DATA(cc);
1570            srcw[1] = srcw[0] + sizeof(sljit_sw);
1571            }
1572          cc += 1;
1573          break;
1574    
1575          CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1576          if (PRIVATE_DATA(cc))
1577            {
1578            count = 2;
1579            srcw[0] = PRIVATE_DATA(cc);
1580            srcw[1] = srcw[0] + sizeof(sljit_sw);
1581            }
1582          cc += 1 + IMM2_SIZE;
1583          break;
1584    
1585          case OP_CLASS:
1586          case OP_NCLASS:
1587    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
1588          case OP_XCLASS:
1589          size = (*cc == OP_XCLASS) ? GET(cc, 1) : 1 + 32 / (int)sizeof(pcre_uchar);
1590    #else
1591          size = 1 + 32 / (int)sizeof(pcre_uchar);
1592    #endif
1593          if (PRIVATE_DATA(cc))
1594            switch(get_class_iterator_size(cc + size))
1595              {
1596              case 1:
1597              count = 1;
1598              srcw[0] = PRIVATE_DATA(cc);
1599              break;
1600    
1601              case 2:
1602              count = 2;
1603              srcw[0] = PRIVATE_DATA(cc);
1604              srcw[1] = srcw[0] + sizeof(sljit_sw);
1605              break;
1606    
1607              default:
1608              SLJIT_ASSERT_STOP();
1609              break;
1610              }
1611          cc += size;
1612          break;
1613    
1614        default:        default:
1615        cc = next_opcode(common, cc);        cc = next_opcode(common, cc);
1616        SLJIT_ASSERT(cc != NULL);        SLJIT_ASSERT(cc != NULL);
# Line 1021  while (status != end) Line 1633  while (status != end)
1633          if (!tmp1empty)          if (!tmp1empty)
1634            {            {
1635            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1636            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1637            }            }
1638          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1639          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1032  while (status != end) Line 1644  while (status != end)
1644          if (!tmp2empty)          if (!tmp2empty)
1645            {            {
1646            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1647            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1648            }            }
1649          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1650          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1049  while (status != end) Line 1661  while (status != end)
1661          if (!tmp1empty)          if (!tmp1empty)
1662            {            {
1663            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1664            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1665            }            }
1666          tmp1next = FALSE;          tmp1next = FALSE;
1667          }          }
# Line 1061  while (status != end) Line 1673  while (status != end)
1673          if (!tmp2empty)          if (!tmp2empty)
1674            {            {
1675            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1676            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1677            }            }
1678          tmp1next = TRUE;          tmp1next = TRUE;
1679          }          }
# Line 1076  if (save) Line 1688  if (save)
1688      if (!tmp1empty)      if (!tmp1empty)
1689        {        {
1690        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1691        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1692        }        }
1693      if (!tmp2empty)      if (!tmp2empty)
1694        {        {
1695        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1696        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1697        }        }
1698      }      }
1699    else    else
# Line 1089  if (save) Line 1701  if (save)
1701      if (!tmp2empty)      if (!tmp2empty)
1702        {        {
1703        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1704        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1705        }        }
1706      if (!tmp1empty)      if (!tmp1empty)
1707        {        {
1708        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1709        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1710        }        }
1711      }      }
1712    }    }
1713  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1714  }  }
1715    
1716  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  #undef CASE_ITERATOR_PRIVATE_DATA_1
1717    #undef CASE_ITERATOR_PRIVATE_DATA_2A
1718    #undef CASE_ITERATOR_PRIVATE_DATA_2B
1719    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1720    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1721    #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1722    
1723    static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1724  {  {
1725  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1726  }  }
# Line 1111  static SLJIT_INLINE void set_jumps(jump_ Line 1730  static SLJIT_INLINE void set_jumps(jump_
1730  while (list)  while (list)
1731    {    {
1732    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1733    if either the jump or the label is NULL */    if either the jump or the label is NULL. */
1734    sljit_set_label(list->jump, label);    sljit_set_label(list->jump, label);
1735    list = list->next;    list = list->next;
1736    }    }
# Line 1138  if (list_item) Line 1757  if (list_item)
1757    list_item->type = type;    list_item->type = type;
1758    list_item->data = data;    list_item->data = data;
1759    list_item->start = start;    list_item->start = start;
1760    list_item->leave = LABEL();    list_item->quit = LABEL();
1761    list_item->next = common->stubs;    list_item->next = common->stubs;
1762    common->stubs = list_item;    common->stubs = list_item;
1763    }    }
# Line 1158  while (list_item) Line 1777  while (list_item)
1777      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1778      break;      break;
1779      }      }
1780    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->quit);
1781    list_item = list_item->next;    list_item = list_item->next;
1782    }    }
1783  common->stubs = NULL;  common->stubs = NULL;
# Line 1177  static SLJIT_INLINE void allocate_stack( Line 1796  static SLJIT_INLINE void allocate_stack(
1796  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
1797  DEFINE_COMPILER;  DEFINE_COMPILER;
1798    
1799  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1800  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
1801  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1802  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1191  add_stub(common, stack_alloc, 0, CMP(SLJ Line 1810  add_stub(common, stack_alloc, 0, CMP(SLJ
1810  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1811  {  {
1812  DEFINE_COMPILER;  DEFINE_COMPILER;
1813  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_w));  OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, size * sizeof(sljit_sw));
1814  }  }
1815    
1816  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1201  struct sljit_label *loop; Line 1820  struct sljit_label *loop;
1820  int i;  int i;
1821  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1822  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1823  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1824  if (length < 8)  if (length < 8)
1825    {    {
1826    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
1827      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1828    }    }
1829  else  else
1830    {    {
1831    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START - sizeof(sljit_sw));
1832    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length);
1833    loop = LABEL();    loop = LABEL();
1834    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1835    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
1836    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
1837    }    }
1838  }  }
# Line 1222  static SLJIT_INLINE void copy_ovector(co Line 1841  static SLJIT_INLINE void copy_ovector(co
1841  {  {
1842  DEFINE_COMPILER;  DEFINE_COMPILER;
1843  struct sljit_label *loop;  struct sljit_label *loop;
1844  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
1845    
1846  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1847  OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1848  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1849    
1850  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
1851  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  if (common->mark_ptr != 0)
1852  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1853  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
1854  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  if (common->mark_ptr != 0)
1855      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
1856    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1857    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1858    GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
1859  /* Unlikely, but possible */  /* Unlikely, but possible */
1860  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  early_quit = CMP(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 0);
1861  loop = LABEL();  loop = LABEL();
1862  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_SCRATCH_REG1, 0);
1863  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_sw));
1864  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1865  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1866  OP2(SLJIT_ASHR, SLJIT_GENERAL_REG2, 0, SLJIT_GENERAL_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1867  #endif  #endif
1868  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1869  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1870  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1871  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
1872    
1873  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
1874  if (topbracket > 1)  if (topbracket > 1)
1875    {    {
1876    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
1877    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
1878    
1879    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1880    loop = LABEL();    loop = LABEL();
1881    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), -(2 * (sljit_sw)sizeof(sljit_sw)));
1882    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, 1);
1883    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1884    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
1885    }    }
1886  else  else
1887    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1888  }  }
1889    
1890    static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
1891    {
1892    DEFINE_COMPILER;
1893    
1894    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1895    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1896    
1897    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
1898    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1899    OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offset_count));
1900    CMPTO(SLJIT_C_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
1901    
1902    /* Store match begin and end. */
1903    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1904    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1905    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1906    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1907    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1908    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
1909    #endif
1910    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1911    
1912    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
1913    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
1914    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
1915    #endif
1916    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
1917    
1918    JUMPTO(SLJIT_JUMP, quit);
1919    }
1920    
1921    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1922    {
1923    /* May destroy TMP1. */
1924    DEFINE_COMPILER;
1925    struct sljit_jump *jump;
1926    
1927    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1928      {
1929      /* The value of -1 must be kept for start_used_ptr! */
1930      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1931      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1932      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1933      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1934      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1935      JUMPHERE(jump);
1936      }
1937    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1938      {
1939      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1940      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1941      JUMPHERE(jump);
1942      }
1943    }
1944    
1945  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1946  {  {
1947  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
# Line 1348  if (c <= 127 && bit == 0x20) Line 2026  if (c <= 127 && bit == 0x20)
2026    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2027    
2028  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2029  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2030    return 0;    return 0;
2031    
2032  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2033    
2034  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2035  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1367  if (common->utf && c > 127) Line 2045  if (common->utf && c > 127)
2045  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2046  return (0 << 8) | bit;  return (0 << 8) | bit;
2047    
2048  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2049    
 #ifdef COMPILE_PCRE16  
2050  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2051  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2052    {    {
# Line 1380  if (common->utf && c > 65535) Line 2057  if (common->utf && c > 65535)
2057    }    }
2058  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2059  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2060    
2061  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2062    }
2063    
2064    static void check_partial(compiler_common *common, BOOL force)
2065    {
2066    /* Checks whether a partial matching is occured. Does not modify registers. */
2067    DEFINE_COMPILER;
2068    struct sljit_jump *jump = NULL;
2069    
2070    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
2071    
2072    if (common->mode == JIT_COMPILE)
2073      return;
2074    
2075    if (!force)
2076      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2077    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2078      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2079    
2080    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2081      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2082    else
2083      {
2084      if (common->partialmatchlabel != NULL)
2085        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2086      else
2087        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2088      }
2089    
2090    if (jump != NULL)
2091      JUMPHERE(jump);
2092  }  }
2093    
2094  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static struct sljit_jump *check_str_end(compiler_common *common)
2095  {  {
2096    /* Does not affect registers. Usually used in a tight spot. */
2097  DEFINE_COMPILER;  DEFINE_COMPILER;
2098  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
2099    struct sljit_jump *nohit;
2100    struct sljit_jump *return_value;
2101    
2102    if (common->mode == JIT_COMPILE)
2103      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2104    
2105    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2106    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2107      {
2108      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2109      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2110      JUMPHERE(nohit);
2111      return_value = JUMP(SLJIT_JUMP);
2112      }
2113    else
2114      {
2115      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
2116      if (common->partialmatchlabel != NULL)
2117        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2118      else
2119        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2120      }
2121    JUMPHERE(jump);
2122    return return_value;
2123    }
2124    
2125    static void detect_partial_match(compiler_common *common, jump_list **backtracks)
2126    {
2127    DEFINE_COMPILER;
2128    struct sljit_jump *jump;
2129    
2130    if (common->mode == JIT_COMPILE)
2131      {
2132      add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2133      return;
2134      }
2135    
2136    /* Partial matching mode. */
2137    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2138    add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2139    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2140      {
2141      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
2142      add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2143      }
2144    else
2145      {
2146      if (common->partialmatchlabel != NULL)
2147        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2148      else
2149        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2150      }
2151    JUMPHERE(jump);
2152  }  }
2153    
2154  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1396  static void read_char(compiler_common *c Line 2156  static void read_char(compiler_common *c
2156  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2157  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2158  DEFINE_COMPILER;  DEFINE_COMPILER;
2159  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2160  struct sljit_jump *jump;  struct sljit_jump *jump;
2161  #endif  #endif
2162    
2163  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2164  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2165  if (common->utf)  if (common->utf)
2166    {    {
2167  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2168    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2169  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2170    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2171  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2172    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2173    JUMPHERE(jump);    JUMPHERE(jump);
2174    }    }
2175  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2176  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2177  }  }
2178    
# Line 1423  static void peek_char(compiler_common *c Line 2181  static void peek_char(compiler_common *c
2181  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2182  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2183  DEFINE_COMPILER;  DEFINE_COMPILER;
2184  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2185  struct sljit_jump *jump;  struct sljit_jump *jump;
2186  #endif  #endif
2187    
2188  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2189  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2190  if (common->utf)  if (common->utf)
2191    {    {
2192  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2193    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2194  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2195    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2196  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2197    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2198    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2199    JUMPHERE(jump);    JUMPHERE(jump);
2200    }    }
2201  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2202  }  }
2203    
2204  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2205  {  {
2206  /* 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. */
2207  DEFINE_COMPILER;  DEFINE_COMPILER;
2208  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2209  struct sljit_jump *jump;  struct sljit_jump *jump;
2210  #endif  #endif
2211    
# Line 1458  if (common->utf) Line 2214  if (common->utf)
2214    {    {
2215    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2216    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2217  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2218    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2219    it is needed in most cases. */    it is needed in most cases. */
2220    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2221    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2222    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2223    JUMPHERE(jump);    JUMPHERE(jump);
2224  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2225    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2226    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2227    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 1474  if (common->utf) Line 2229  if (common->utf)
2229    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2230    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2231    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
2232    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2233    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2234    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2235  #endif  #elif defined COMPILE_PCRE32
2236  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2237      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2238      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2239      JUMPHERE(jump);
2240    #endif /* COMPILE_PCRE[8|16|32] */
2241    return;    return;
2242    }    }
2243  #endif  #endif /* SUPPORT_UTF */
2244  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2245  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2246  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2247  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2248  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2249  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2250  #endif  #endif
2251  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2252  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2253  JUMPHERE(jump);  JUMPHERE(jump);
2254  #endif  #endif
2255  }  }
# Line 1499  static void skip_char_back(compiler_comm Line 2258  static void skip_char_back(compiler_comm
2258  {  {
2259  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
2260  DEFINE_COMPILER;  DEFINE_COMPILER;
2261  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2262    #if defined COMPILE_PCRE8
2263  struct sljit_label *label;  struct sljit_label *label;
2264    
2265  if (common->utf)  if (common->utf)
# Line 1511  if (common->utf) Line 2271  if (common->utf)
2271    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2272    return;    return;
2273    }    }
2274  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2275  if (common->utf)  if (common->utf)
2276    {    {
2277    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
# Line 1520  if (common->utf) Line 2279  if (common->utf)
2279    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2280    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2281    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
2282    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2283    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2284    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2285    return;    return;
2286    }    }
2287  #endif  #endif /* COMPILE_PCRE[8|16] */
2288    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2289  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2290  }  }
2291    
2292  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)
2293  {  {
2294  /* 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. */
2295  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 1537  DEFINE_COMPILER; Line 2297  DEFINE_COMPILER;
2297  if (nltype == NLTYPE_ANY)  if (nltype == NLTYPE_ANY)
2298    {    {
2299    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL));
2300    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));
2301    }    }
2302  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2303    {    {
2304    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_CR);
2305    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2306    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);
2307    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2308    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));
2309    }    }
2310  else  else
2311    {    {
2312    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
2313    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));
2314    }    }
2315  }  }
2316    
2317  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2318    
2319  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2320  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2321  {  {
2322  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 1564  of the character (>= 0xc0). Return char Line 2324  of the character (>= 0xc0). Return char
2324  DEFINE_COMPILER;  DEFINE_COMPILER;
2325  struct sljit_jump *jump;  struct sljit_jump *jump;
2326    
2327  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2328  /* Searching for the first zero. */  /* Searching for the first zero. */
2329  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);
2330  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1623  DEFINE_COMPILER; Line 2383  DEFINE_COMPILER;
2383  struct sljit_jump *jump;  struct sljit_jump *jump;
2384  struct sljit_jump *compare;  struct sljit_jump *compare;
2385    
2386  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2387    
2388  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);
2389  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
# Line 1644  sljit_emit_fast_return(compiler, RETURN_ Line 2404  sljit_emit_fast_return(compiler, RETURN_
2404  JUMPHERE(jump);  JUMPHERE(jump);
2405    
2406  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2407  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2408  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2409  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2410  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2411  }  }
2412    
2413  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2414    
 #ifdef COMPILE_PCRE16  
2415  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2416  {  {
2417  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char  /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
# Line 1660  of the character (>= 0xd800). Return cha Line 2419  of the character (>= 0xd800). Return cha
2419  DEFINE_COMPILER;  DEFINE_COMPILER;
2420  struct sljit_jump *jump;  struct sljit_jump *jump;
2421    
2422  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2423  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
2424  /* Do nothing, only return. */  /* Do nothing, only return. */
2425  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 1677  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2436  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2436  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2437  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2438  }  }
 #endif /* COMPILE_PCRE16 */  
2439    
2440  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2441    
2442  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2443    
# Line 1697  DEFINE_COMPILER; Line 2455  DEFINE_COMPILER;
2455    
2456  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8);
2457    
2458  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2459  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2460  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1));
2461  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2462  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2463  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2464  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2465  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2466  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
2467  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2468  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2469  }  }
# Line 1719  struct sljit_label *newlinelabel = NULL; Line 2477  struct sljit_label *newlinelabel = NULL;
2477  struct sljit_jump *start;  struct sljit_jump *start;
2478  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2479  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2480  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2481  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2482  #endif  #endif
2483  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 1733  if (!(hascrorlf || firstline) && (common Line 2491  if (!(hascrorlf || firstline) && (common
2491  if (firstline)  if (firstline)
2492    {    {
2493    /* Search for the end of the first line. */    /* Search for the end of the first line. */
2494    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2495    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
2496    
2497    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
2498      {      {
# Line 1745  if (firstline) Line 2503  if (firstline)
2503      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2504      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);
2505      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);
2506      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      JUMPHERE(end);
2507        OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2508      }      }
2509    else    else
2510      {      {
2511      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2512      mainloop = LABEL();      mainloop = LABEL();
2513      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2514      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);
2515      read_char(common);      read_char(common);
2516      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2517      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2518      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      JUMPHERE(end);
2519        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2520      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2521      }      }
2522    
2523    JUMPHERE(end);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  
2524    }    }
2525    
2526  start = JUMP(SLJIT_JUMP);  start = JUMP(SLJIT_JUMP);
# Line 1773  if (newlinecheck) Line 2532  if (newlinecheck)
2532    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2533    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2534    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);
2535    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2536  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2537    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2538  #endif  #endif
2539    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2540    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 1796  if (newlinecheck) Line 2555  if (newlinecheck)
2555    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);
2556    
2557  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2558  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2559    #if defined COMPILE_PCRE8
2560  if (common->utf)  if (common->utf)
2561    {    {
2562    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2563    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2564    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2565    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2566    }    }
2567  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2568  if (common->utf)  if (common->utf)
2569    {    {
2570    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2571    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2572    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2573    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2574    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2575    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2576    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2577    }    }
2578  #endif  #endif /* COMPILE_PCRE[8|16] */
2579    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2580  JUMPHERE(start);  JUMPHERE(start);
2581    
2582  if (newlinecheck)  if (newlinecheck)
# Line 1828  if (newlinecheck) Line 2588  if (newlinecheck)
2588  return mainloop;  return mainloop;
2589  }  }
2590    
2591    #define MAX_N_CHARS 3
2592    
2593    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2594    {
2595    DEFINE_COMPILER;
2596    struct sljit_label *start;
2597    struct sljit_jump *quit;
2598    pcre_uint32 chars[MAX_N_CHARS * 2];
2599    pcre_uchar *cc = common->start + 1 + LINK_SIZE;
2600    int location = 0;
2601    pcre_int32 len, c, bit, caseless;
2602    int must_stop;
2603    
2604    /* We do not support alternatives now. */
2605    if (*(common->start + GET(common->start, 1)) == OP_ALT)
2606      return FALSE;
2607    
2608    while (TRUE)
2609      {
2610      caseless = 0;
2611      must_stop = 1;
2612      switch(*cc)
2613        {
2614        case OP_CHAR:
2615        must_stop = 0;
2616        cc++;
2617        break;
2618    
2619        case OP_CHARI:
2620        caseless = 1;
2621        must_stop = 0;
2622        cc++;
2623        break;
2624    
2625        case OP_SOD:
2626        case OP_SOM:
2627        case OP_SET_SOM:
2628        case OP_NOT_WORD_BOUNDARY:
2629        case OP_WORD_BOUNDARY:
2630        case OP_EODN:
2631        case OP_EOD:
2632        case OP_CIRC:
2633        case OP_CIRCM:
2634        case OP_DOLL:
2635        case OP_DOLLM:
2636        /* Zero width assertions. */
2637        cc++;
2638        continue;
2639    
2640        case OP_PLUS:
2641        case OP_MINPLUS:
2642        case OP_POSPLUS:
2643        cc++;
2644        break;
2645    
2646        case OP_EXACT:
2647        cc += 1 + IMM2_SIZE;
2648        break;
2649    
2650        case OP_PLUSI:
2651        case OP_MINPLUSI:
2652        case OP_POSPLUSI:
2653        caseless = 1;
2654        cc++;
2655        break;
2656    
2657        case OP_EXACTI:
2658        caseless = 1;
2659        cc += 1 + IMM2_SIZE;
2660        break;
2661    
2662        default:
2663        must_stop = 2;
2664        break;
2665        }
2666    
2667      if (must_stop == 2)
2668          break;
2669    
2670      len = 1;
2671    #ifdef SUPPORT_UTF
2672      if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
2673    #endif
2674    
2675      if (caseless && char_has_othercase(common, cc))
2676        {
2677        caseless = char_get_othercase_bit(common, cc);
2678        if (caseless == 0)
2679          return FALSE;
2680    #ifdef COMPILE_PCRE8
2681        caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 8));
2682    #else
2683        if ((caseless & 0x100) != 0)
2684          caseless = ((caseless & 0xff) << 16) | (len - (caseless >> 9));
2685        else
2686          caseless = ((caseless & 0xff) << 8) | (len - (caseless >> 9));
2687    #endif
2688        }
2689      else
2690        caseless = 0;
2691    
2692      while (len > 0 && location < MAX_N_CHARS * 2)
2693        {
2694        c = *cc;
2695        bit = 0;
2696        if (len == (caseless & 0xff))
2697          {
2698          bit = caseless >> 8;
2699          c |= bit;
2700          }
2701    
2702        chars[location] = c;
2703        chars[location + 1] = bit;
2704    
2705        len--;
2706        location += 2;
2707        cc++;
2708        }
2709    
2710      if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2711        break;
2712      }
2713    
2714    /* At least two characters are required. */
2715    if (location < 2 * 2)
2716        return FALSE;
2717    
2718    if (firstline)
2719      {
2720      SLJIT_ASSERT(common->first_line_end != 0);
2721      OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2722      OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2723      }
2724    else
2725      OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2726    
2727    start = LABEL();
2728    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2729    
2730    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2731    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2732    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2733    if (chars[1] != 0)
2734      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2735    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2736    if (location > 2 * 2)
2737      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2738    if (chars[3] != 0)
2739      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2740    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2741    if (location > 2 * 2)
2742      {
2743      if (chars[5] != 0)
2744        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2745      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
2746      }
2747    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2748    
2749    JUMPHERE(quit);
2750    
2751    if (firstline)
2752      OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2753    else
2754      OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2755    return TRUE;
2756    }
2757    
2758    #undef MAX_N_CHARS
2759    
2760  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
2761  {  {
2762  DEFINE_COMPILER;  DEFINE_COMPILER;
2763  struct sljit_label *start;  struct sljit_label *start;
2764  struct sljit_jump *leave;  struct sljit_jump *quit;
2765  struct sljit_jump *found;  struct sljit_jump *found;
2766  pcre_uchar oc, bit;  pcre_uchar oc, bit;
2767    
2768  if (firstline)  if (firstline)
2769    {    {
2770    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2771    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2772      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2773    }    }
2774    
2775  start = LABEL();  start = LABEL();
2776  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2777  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2778    
2779  oc = first_char;  oc = first_char;
# Line 1860  if (first_char == oc) Line 2790  if (first_char == oc)
2790  else  else
2791    {    {
2792    bit = first_char ^ oc;    bit = first_char ^ oc;
2793    if (ispowerof2(bit))    if (is_powerof2(bit))
2794      {      {
2795      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2796      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
# Line 1868  else Line 2798  else
2798    else    else
2799      {      {
2800      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
2801      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2802      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);
2803      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
2804      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
2805      }      }
2806    }    }
2807    
2808  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 #if defined SUPPORT_UTF && defined COMPILE_PCRE8  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);  
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
 if (common->utf)  
   {  
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);  
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);  
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);  
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);  
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  
   }  
 #endif  
2809  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2810  JUMPHERE(found);  JUMPHERE(found);
2811  JUMPHERE(leave);  JUMPHERE(quit);
2812    
2813  if (firstline)  if (firstline)
2814    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2815  }  }
2816    
2817  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)  static SLJIT_INLINE void fast_forward_newline(compiler_common *common, BOOL firstline)
# Line 1909  DEFINE_COMPILER; Line 2820  DEFINE_COMPILER;
2820  struct sljit_label *loop;  struct sljit_label *loop;
2821  struct sljit_jump *lastchar;  struct sljit_jump *lastchar;
2822  struct sljit_jump *firstchar;  struct sljit_jump *firstchar;
2823  struct sljit_jump *leave;  struct sljit_jump *quit;
2824  struct sljit_jump *foundcr = NULL;  struct sljit_jump *foundcr = NULL;
2825  struct sljit_jump *notfoundnl;  struct sljit_jump *notfoundnl;
2826  jump_list *newline = NULL;  jump_list *newline = NULL;
2827    
2828  if (firstline)  if (firstline)
2829    {    {
2830    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2831    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2832      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2833    }    }
2834    
2835  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1930  if (common->nltype == NLTYPE_FIXED && co Line 2842  if (common->nltype == NLTYPE_FIXED && co
2842    
2843    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2844    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);
2845    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
2846  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2847    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
2848  #endif  #endif
2849    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2850    
2851    loop = LABEL();    loop = LABEL();
2852    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2853    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2854    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2855    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2856    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);
2857    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);
2858    
2859    JUMPHERE(leave);    JUMPHERE(quit);
2860    JUMPHERE(firstchar);    JUMPHERE(firstchar);
2861    JUMPHERE(lastchar);    JUMPHERE(lastchar);
2862    
# Line 1968  set_jumps(newline, loop); Line 2880  set_jumps(newline, loop);
2880    
2881  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)  if (common->nltype == NLTYPE_ANY || common->nltype == NLTYPE_ANYCRLF)
2882    {    {
2883    leave = JUMP(SLJIT_JUMP);    quit = JUMP(SLJIT_JUMP);
2884    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2885    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2886    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2887    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);
2888    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2889  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2890    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2891  #endif  #endif
2892    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2893    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2894    JUMPHERE(leave);    JUMPHERE(quit);
2895    }    }
2896  JUMPHERE(lastchar);  JUMPHERE(lastchar);
2897  JUMPHERE(firstchar);  JUMPHERE(firstchar);
2898    
2899  if (firstline)  if (firstline)
2900    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
2901  }  }
2902    
2903    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
2904    
2905  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)  static SLJIT_INLINE void fast_forward_start_bits(compiler_common *common, sljit_uw start_bits, BOOL firstline)
2906  {  {
2907  DEFINE_COMPILER;  DEFINE_COMPILER;
2908  struct sljit_label *start;  struct sljit_label *start;
2909  struct sljit_jump *leave;  struct sljit_jump *quit;
2910  struct sljit_jump *found;  struct sljit_jump *found = NULL;
2911    jump_list *matches = NULL;
2912    pcre_uint8 inverted_start_bits[32];
2913    int i;
2914  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2915  struct sljit_jump *jump;  struct sljit_jump *jump;
2916  #endif  #endif
2917    
2918    for (i = 0; i < 32; ++i)
2919      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
2920    
2921  if (firstline)  if (firstline)
2922    {    {
2923    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    SLJIT_ASSERT(common->first_line_end != 0);
2924    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, RETURN_ADDR, 0, STR_END, 0);
2925      OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2926    }    }
2927    
2928  start = LABEL();  start = LABEL();
2929  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2930  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2931  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2932  if (common->utf)  if (common->utf)
2933    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2934  #endif  #endif
2935    
2936    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
2937      {
2938  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
2939  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2940  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2941  JUMPHERE(jump);    JUMPHERE(jump);
2942  #endif  #endif
2943  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2944  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2945  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
2946  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
2947  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);
2948  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
2949      }
2950    
2951  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2952  if (common->utf)  if (common->utf)
2953    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2954  #endif  #endif
2955  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2956  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
2957    #if defined COMPILE_PCRE8
2958  if (common->utf)  if (common->utf)
2959    {    {
2960    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2961    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
2962    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2963    }    }
2964  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2965  if (common->utf)  if (common->utf)
2966    {    {
2967    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2968    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2969    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2970    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2971    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2972    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2973    }    }
2974  #endif  #endif /* COMPILE_PCRE[8|16] */
2975    #endif /* SUPPORT_UTF */
2976  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2977  JUMPHERE(found);  if (found != NULL)
2978  JUMPHERE(leave);    JUMPHERE(found);
2979    if (matches != NULL)
2980      set_jumps(matches, LABEL());
2981    JUMPHERE(quit);
2982    
2983  if (firstline)  if (firstline)
2984    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, RETURN_ADDR, 0);
2985  }  }
2986    
2987  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
# Line 2064  struct sljit_jump *alreadyfound; Line 2993  struct sljit_jump *alreadyfound;
2993  struct sljit_jump *found;  struct sljit_jump *found;
2994  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2995  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2996  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
2997    
2998  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2999    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
3000  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);
3001  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
3002  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
# Line 2094  if (req_char == oc) Line 3024  if (req_char == oc)
3024  else  else
3025    {    {
3026    bit = req_char ^ oc;    bit = req_char ^ oc;
3027    if (ispowerof2(bit))    if (is_powerof2(bit))
3028      {      {
3029      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3030      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
# Line 2111  JUMPTO(SLJIT_JUMP, loop); Line 3041  JUMPTO(SLJIT_JUMP, loop);
3041  JUMPHERE(found);  JUMPHERE(found);
3042  if (foundoc)  if (foundoc)
3043    JUMPHERE(foundoc);    JUMPHERE(foundoc);
3044  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
3045  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
3046  JUMPHERE(toolong);  JUMPHERE(toolong);
3047  return notfound;  return notfound;
# Line 2123  DEFINE_COMPILER; Line 3053  DEFINE_COMPILER;
3053  struct sljit_jump *jump;  struct sljit_jump *jump;
3054  struct sljit_label *mainloop;  struct sljit_label *mainloop;
3055    
3056  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3057  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
3058    GET_LOCAL_BASE(TMP3, 0, 0);
3059    
3060  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3061  mainloop = LABEL();  mainloop = LABEL();
3062  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3063  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);
3064  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_LOCALS_REG, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3065  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_sw));
3066  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_w), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(TMP1), 2 * sizeof(sljit_sw));
3067  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_sw));
3068  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3069    
3070  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2144  sljit_emit_fast_return(compiler, RETURN_ Line 3075  sljit_emit_fast_return(compiler, RETURN_
3075  JUMPHERE(jump);  JUMPHERE(jump);
3076  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
3077  /* Set string begin. */  /* Set string begin. */
3078  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3079  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_sw));
3080  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
3081  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3082    
3083  JUMPHERE(jump);  JUMPHERE(jump);
3084    if (common->mark_ptr != 0)
3085      {
3086      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
3087      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3088      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_sw));
3089      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
3090      JUMPTO(SLJIT_JUMP, mainloop);
3091    
3092      JUMPHERE(jump);
3093      }
3094    
3095  /* Unknown command. */  /* Unknown command. */
3096  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_sw));
3097  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3098  }  }
3099    
3100  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
3101  {  {
3102  DEFINE_COMPILER;  DEFINE_COMPILER;
3103  struct sljit_jump *beginend;  struct sljit_jump *skipread;
3104  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3105  struct sljit_jump *jump;  struct sljit_jump *jump;
3106  #endif  #endif
3107    
3108  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
3109    
3110  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);
3111  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
3112  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3113  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));
3114  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
3115  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
3116  skip_char_back(common);  skip_char_back(common);
3117    check_start_used_ptr(common);
3118  read_char(common);  read_char(common);
3119    
3120  /* Testing char type. */  /* Testing char type. */
# Line 2183  if (common->use_ucp) Line 3126  if (common->use_ucp)
3126    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3127    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3128    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3129    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3130    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3131    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3132    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3133    JUMPHERE(jump);    JUMPHERE(jump);
3134    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3135    }    }
# Line 2212  else Line 3155  else
3155      JUMPHERE(jump);      JUMPHERE(jump);
3156  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3157    }    }
3158  JUMPHERE(beginend);  JUMPHERE(skipread);
3159    
3160  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3161  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
3162  peek_char(common);  peek_char(common);
3163    
3164  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
3165  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3166  if (common->use_ucp)  if (common->use_ucp)
3167      {
3168      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
3169      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
3170      add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3171      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3172      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
3173      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3174      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);
3175      OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);
3176      OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3177      JUMPHERE(jump);
3178      }
3179    else
3180    #endif
3181      {
3182    #ifndef COMPILE_PCRE8
3183      /* TMP2 may be destroyed by peek_char. */
3184      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3185      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3186    #elif defined SUPPORT_UTF
3187      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3188      jump = NULL;
3189      if (common->utf)
3190        jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3191    #endif
3192      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
3193      OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
3194      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3195    #ifndef COMPILE_PCRE8
3196      JUMPHERE(jump);
3197    #elif defined SUPPORT_UTF
3198      if (jump != NULL)
3199        JUMPHERE(jump);
3200    #endif /* COMPILE_PCRE8 */
3201      }
3202    JUMPHERE(skipread);
3203    
3204    OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3205    sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3206    }
3207    
3208    /*
3209      range format:
3210    
3211      ranges[0] = length of the range (max MAX_RANGE_SIZE, -1 means invalid range).
3212      ranges[1] = first bit (0 or 1)
3213      ranges[2-length] = position of the bit change (when the current bit is not equal to the previous)
3214    */
3215    
3216    static BOOL check_ranges(compiler_common *common, int *ranges, jump_list **backtracks, BOOL readch)
3217    {
3218    DEFINE_COMPILER;
3219    struct sljit_jump *jump;
3220    
3221    if (ranges[0] < 0)
3222      return FALSE;
3223    
3224    switch(ranges[0])
3225      {
3226      case 1:
3227      if (readch)
3228        read_char(common);
3229      add_jump(compiler, backtracks, CMP(ranges[1] == 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3230      return TRUE;
3231    
3232      case 2:
3233      if (readch)
3234        read_char(common);
3235      OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[2]);
3236      add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[3] - ranges[2]));
3237      return TRUE;
3238    
3239      case 4:
3240      if (ranges[2] + 1 == ranges[3] && ranges[4] + 1 == ranges[5])
3241        {
3242        if (readch)
3243          read_char(common);
3244        if (ranges[1] != 0)
3245          {
3246          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]));
3247          add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3248          }
3249        else
3250          {
3251          jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, ranges[2]);
3252          add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, ranges[4]));
3253          JUMPHERE(jump);
3254          }
3255        return TRUE;
3256        }
3257      if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3258        {
3259        if (readch)
3260          read_char(common);
3261        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4] - ranges[2]);
3262        OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ranges[4]);
3263        add_jump(compiler, backtracks, CMP(ranges[1] != 0 ? SLJIT_C_LESS : SLJIT_C_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, ranges[5] - ranges[4]));
3264        return TRUE;
3265        }
3266      return FALSE;
3267    
3268      default:
3269      return FALSE;
3270      }
3271    }
3272    
3273    static void get_ctype_ranges(compiler_common *common, int flag, int *ranges)
3274    {
3275    int i, bit, length;
3276    const pcre_uint8 *ctypes = (const pcre_uint8*)common->ctypes;
3277    
3278    bit = ctypes[0] & flag;
3279    ranges[0] = -1;
3280    ranges[1] = bit != 0 ? 1 : 0;
3281    length = 0;
3282    
3283    for (i = 1; i < 256; i++)
3284      if ((ctypes[i] & flag) != bit)
3285        {
3286        if (length >= MAX_RANGE_SIZE)
3287          return;
3288        ranges[2 + length] = i;
3289        length++;
3290        bit ^= flag;
3291        }
3292    
3293    if (bit != 0)
3294      {
3295      if (length >= MAX_RANGE_SIZE)
3296        return;
3297      ranges[2 + length] = 256;
3298      length++;
3299      }
3300    ranges[0] = length;
3301    }
3302    
3303    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks)
3304    {
3305    int ranges[2 + MAX_RANGE_SIZE];
3306    pcre_uint8 bit, cbit, all;
3307    int i, byte, length = 0;
3308    
3309    bit = bits[0] & 0x1;
3310    ranges[1] = bit;
3311    /* Can be 0 or 255. */
3312    all = -bit;
3313    
3314    for (i = 0; i < 256; )
3315    {    {
3316    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    byte = i >> 3;
3317    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    if ((i & 0x7) == 0 && bits[byte] == all)
3318    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));      i += 8;
3319    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    else
3320    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);      {
3321    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);      cbit = (bits[byte] >> (i & 0x7)) & 0x1;
3322    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Nd - ucp_Ll);      if (cbit != bit)
3323    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd);        {
3324    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        if (length >= MAX_RANGE_SIZE)
3325    JUMPHERE(jump);          return FALSE;
3326          ranges[2 + length] = i;
3327          length++;
3328          bit = cbit;
3329          all = -cbit;
3330          }
3331        i++;
3332        }
3333    }    }
3334  else  
3335  #endif  if (((bit == 0) && nclass) || ((bit == 1) && !nclass))
3336    {    {
3337  #ifndef COMPILE_PCRE8    if (length >= MAX_RANGE_SIZE)
3338    /* TMP2 may be destroyed by peek_char. */      return FALSE;
3339    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    ranges[2 + length] = 256;
3340    jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);    length++;
 #elif defined SUPPORT_UTF  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  
   jump = NULL;  
   if (common->utf)  
     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);  
 #ifndef COMPILE_PCRE8  
   JUMPHERE(jump);  
 #elif defined SUPPORT_UTF  
   if (jump != NULL)  
     JUMPHERE(jump);  
 #endif /* COMPILE_PCRE8 */  
3341    }    }
3342  JUMPHERE(beginend);  ranges[0] = length;
3343    
3344  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);  
3345  }  }
3346    
3347  static void check_anynewline(compiler_common *common)  static void check_anynewline(compiler_common *common)
# Line 2267  static void check_anynewline(compiler_co Line 3349  static void check_anynewline(compiler_co
3349  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3350  DEFINE_COMPILER;  DEFINE_COMPILER;
3351    
3352  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3353    
3354  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3355  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);
3356  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3357  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);
3358  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3359  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3360  if (common->utf)  if (common->utf)
3361    {    {
3362  #endif  #endif
3363    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3364    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3365    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);
3366  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3367    }    }
3368  #endif  #endif
3369  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3370  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3371  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3372  }  }
3373    
# Line 2294  static void check_hspace(compiler_common Line 3376  static void check_hspace(compiler_common
3376  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3377  DEFINE_COMPILER;  DEFINE_COMPILER;
3378    
3379  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3380    
3381  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);
3382  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3383  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);
3384  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3385  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);
3386  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3387  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3388  if (common->utf)  if (common->utf)
3389    {    {
3390  #endif  #endif
3391    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3392    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);
3393    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3394    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x180e);
3395    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3396    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3397    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x200A - 0x2000);
3398    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3399    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x202f - 0x2000);
3400    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3401    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);
3402    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3403    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);
3404  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3405    }    }
3406  #endif  #endif
3407  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3408  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3409    
3410  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3411  }  }
# Line 2333  static void check_vspace(compiler_common Line 3415  static void check_vspace(compiler_common
3415  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */  /* Check whether TMP1 contains a newline character. TMP2 destroyed. */
3416  DEFINE_COMPILER;  DEFINE_COMPILER;
3417    
3418  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3419    
3420  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3421  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);
3422  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3423  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);
3424  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3425  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3426  if (common->utf)  if (common->utf)
3427    {    {
3428  #endif  #endif
3429    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3430    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3431    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);
3432  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3433    }    }
3434  #endif  #endif
3435  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3436  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3437    
3438  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3439  }  }
# Line 2365  DEFINE_COMPILER; Line 3447  DEFINE_COMPILER;
3447  struct sljit_jump *jump;  struct sljit_jump *jump;
3448  struct sljit_label *label;  struct sljit_label *label;
3449    
3450  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3451  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3452  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
3453  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
# Line 2394  DEFINE_COMPILER; Line 3476  DEFINE_COMPILER;
3476  struct sljit_jump *jump;  struct sljit_jump *jump;
3477  struct sljit_label *label;  struct sljit_label *label;
3478    
3479  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3480  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3481    
3482  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
# Line 2437  sljit_emit_fast_return(compiler, RETURN_ Line 3519  sljit_emit_fast_return(compiler, RETURN_
3519    
3520  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3521    
3522  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)  static const pcre_uchar * SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
3523  {  {
3524  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3525  int c1, c2;  pcre_uint32 c1, c2;
3526  const pcre_uchar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3527  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3528    const ucd_record *ur;
3529    const pcre_uint32 *pp;
3530    
3531  while (src1 < end1)  while (src1 < end1)
3532    {    {
3533    if (src2 >= end2)    if (src2 >= end2)
3534      return 0;      return (pcre_uchar*)1;
3535    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3536    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3537    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    ur = GET_UCD(c2);
3538      if (c1 != c2 && c1 != c2 + ur->other_case)
3539        {
3540        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3541        for (;;)
3542          {
3543          if (c1 < *pp) return NULL;
3544          if (c1 == *pp++) break;
3545          }
3546        }
3547    }    }
3548  return src2;  return src2;
3549  }  }
# Line 2458  return src2; Line 3551  return src2;
3551  #endif /* SUPPORT_UTF && SUPPORT_UCP */  #endif /* SUPPORT_UTF && SUPPORT_UCP */
3552    
3553  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
3554      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **backtracks)
3555  {  {
3556  DEFINE_COMPILER;  DEFINE_COMPILER;
3557  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
# Line 2472  if (caseless && char_has_othercase(commo Line 3565  if (caseless && char_has_othercase(commo
3565    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3566    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3567    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3568  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3569    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3570    othercasebit &= 0xff;    othercasebit &= 0xff;
3571  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3572  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3573      ever are characters outside the BMP whose othercase differs in only one
3574      bit from itself (there currently are none), this code will need to be
3575      revised for COMPILE_PCRE32. */
3576    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3577    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3578      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3579    else    else
3580      othercasebit &= 0xff;      othercasebit &= 0xff;
3581  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3582    }    }
3583    
3584  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3585    {    {
3586  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3587  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3588    if (context->length >= 4)    if (context->length >= 4)
3589      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3590    else if (context->length >= 2)    else if (context->length >= 2)
3591      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3592    else    else
3593  #endif  #endif
3594      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3595  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3596  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3597    if (context->length >= 4)    if (context->length >= 4)
3598      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3599    else    else
3600  #endif  #endif
3601      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3602  #endif  #elif defined COMPILE_PCRE32
3603  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3604    #endif /* COMPILE_PCRE[8|16|32] */
3605    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3606    }    }
3607    
# Line 2520  do Line 3615  do
3615  #endif  #endif
3616    
3617    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3618  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3619    
3620    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3621    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 2535  do Line 3630  do
3630      }      }
3631    context->ucharptr++;    context->ucharptr++;
3632    
3633  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3634    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))    if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
3635  #else  #else
3636    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
# Line 2543  do Line 3638  do
3638      {      {
3639      if (context->length >= 4)      if (context->length >= 4)
3640        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);
 #ifdef COMPILE_PCRE8  
3641      else if (context->length >= 2)      else if (context->length >= 2)
3642        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);
3643    #if defined COMPILE_PCRE8
3644      else if (context->length >= 1)      else if (context->length >= 1)
3645        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);
3646  #else  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_SH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3647      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3648    
3649      switch(context->ucharptr)      switch(context->ucharptr)
# Line 2559  do Line 3651  do
3651        case 4 / sizeof(pcre_uchar):        case 4 / sizeof(pcre_uchar):
3652        if (context->oc.asint != 0)        if (context->oc.asint != 0)
3653          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);
3654        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));
3655        break;        break;
3656    
3657        case 2 / sizeof(pcre_uchar):        case 2 / sizeof(pcre_uchar):
3658        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
3659          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);
3660        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));
3661        break;        break;
3662    
3663  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3664        case 1:        case 1:
3665        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
3666          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);
3667        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));
3668        break;        break;
3669  #endif  #endif
3670    
# Line 2585  do Line 3677  do
3677    
3678  #else  #else
3679    
3680    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3681  #ifdef COMPILE_PCRE8    if (context->length >= 1)
3682    if (context->length > 0)      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3683      OP1(SLJIT_MOV_UB, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #else  
   if (context->length > 0)  
     OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3684    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3685    
3686    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
3687      {      {
3688      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
3689      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));
3690      }      }
3691    else    else
3692      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));
3693    
3694  #endif  #endif
3695    
# Line 2637  return cc; Line 3725  return cc;
3725      } \      } \
3726    charoffset = (value);    charoffset = (value);
3727    
3728  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)  static void compile_xclass_matchingpath(compiler_common *common, pcre_uchar *cc, jump_list **backtracks)
3729  {  {
3730  DEFINE_COMPILER;  DEFINE_COMPILER;
3731  jump_list *found = NULL;  jump_list *found = NULL;
3732  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fallbacks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3733  unsigned int c;  pcre_int32 c, charoffset;
3734  int compares;  const pcre_uint32 *other_cases;
3735  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3736  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3737    int compares, invertcmp, numberofcmps;
3738  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3739  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3740  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3741  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3742  unsigned int typeoffset;  pcre_int32 typeoffset;
3743  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3744    
3745  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */  /* Although SUPPORT_UTF must be defined, we are
3746  check_input_end(common, fallbacks);     not necessary in utf mode even in 8 bit mode. */
3747    detect_partial_match(common, backtracks);
3748  read_char(common);  read_char(common);
3749    
3750  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
# Line 2669  if ((*cc++ & XCL_MAP) != 0) Line 3757  if ((*cc++ & XCL_MAP) != 0)
3757      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3758  #endif  #endif
3759    
3760    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    if (!check_class_ranges(common, (const pcre_uint8 *)cc, TRUE, list))
3761    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      {
3762    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3763    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3764    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
3765    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3766        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
3767        add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
3768        }
3769    
3770  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3771    JUMPHERE(jump);    JUMPHERE(jump);
# Line 2747  while (*cc != XCL_END) Line 3838  while (*cc != XCL_END)
3838        needschar = TRUE;        needschar = TRUE;
3839        break;        break;
3840    
3841          case PT_CLIST:
3842          needschar = TRUE;
3843          break;
3844    
3845        default:        default:
3846        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
3847        break;        break;
# Line 2783  if (needstype || needsscript) Line 3878  if (needstype || needsscript)
3878      {      {
3879      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3880        {        {
3881        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3882        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3883        }        }
3884      else      else
3885        {        {
3886        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3887        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
3888        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3889        }        }
3890      }      }
# Line 2807  typeoffset = 0; Line 3902  typeoffset = 0;
3902  while (*cc != XCL_END)  while (*cc != XCL_END)
3903    {    {
3904    compares--;    compares--;
3905    invertcmp = (compares == 0 && list != fallbacks);    invertcmp = (compares == 0 && list != backtracks);
3906    jump = NULL;    jump = NULL;
3907    
3908    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
# Line 2825  while (*cc != XCL_END) Line 3920  while (*cc != XCL_END)
3920      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3921        {        {
3922        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3923        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_EQUAL);
3924        numberofcmps++;        numberofcmps++;
3925        }        }
3926      else if (numberofcmps > 0)      else if (numberofcmps > 0)
3927        {        {
3928        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3929        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3930        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3931        numberofcmps = 0;        numberofcmps = 0;
3932        }        }
# Line 2864  while (*cc != XCL_END) Line 3959  while (*cc != XCL_END)
3959      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
3960        {        {
3961        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3962        COND_VALUE(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(numberofcmps == 0 ? SLJIT_MOV : SLJIT_OR, TMP2, 0, numberofcmps == 0 ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
3963        numberofcmps++;        numberofcmps++;
3964        }        }
3965      else if (numberofcmps > 0)      else if (numberofcmps > 0)
3966        {        {
3967        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c - charoffset);
3968        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3969        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
3970        numberofcmps = 0;        numberofcmps = 0;
3971        }        }
# Line 2889  while (*cc != XCL_END) Line 3984  while (*cc != XCL_END)
3984      switch(*cc)      switch(*cc)
3985        {        {
3986        case PT_ANY:        case PT_ANY:
3987        if (list != fallbacks)        if (list != backtracks)
3988          {          {
3989          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))
3990            continue;            continue;
# Line 2901  while (*cc != XCL_END) Line 3996  while (*cc != XCL_END)
3996    
3997        case PT_LAMP:        case PT_LAMP:
3998        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - typeoffset);
3999        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4000        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Ll - typeoffset);
4001        COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4002        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lt - typeoffset);
4003        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4004        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4005        break;        break;
4006    
# Line 2932  while (*cc != XCL_END) Line 4027  while (*cc != XCL_END)
4027          }          }
4028        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4029        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 13 - 9);
4030        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4031        if (*cc == PT_SPACE)        if (*cc == PT_SPACE)
4032          JUMPHERE(jump);          JUMPHERE(jump);
4033    
4034        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4035        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Zs - ucp_Zl);
4036        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4037        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4038        break;        break;
4039    
4040        case PT_WORD:        case PT_WORD:
4041        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE - charoffset);
4042        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4043        /* ... fall through */        /* ... fall through */
4044    
4045        case PT_ALNUM:        case PT_ALNUM:
4046        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
4047        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_Lu - ucp_Ll);
4048        COND_VALUE((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS((*cc == PT_ALNUM) ? SLJIT_MOV : SLJIT_OR, TMP2, 0, (*cc == PT_ALNUM) ? SLJIT_UNUSED : TMP2, 0, SLJIT_C_LESS_EQUAL);
4049        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
4050        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, typereg, 0, SLJIT_IMM, ucp_No - ucp_Nd);
4051        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4052          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4053          break;
4054    
4055          case PT_CLIST:
4056          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4057    
4058          /* At least three characters are required.
4059             Otherwise this case would be handled by the normal code path. */
4060          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4061          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4062    
4063          /* Optimizing character pairs, if their difference is power of 2. */
4064          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4065            {
4066            if (charoffset == 0)
4067              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4068            else
4069              {
4070              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4071              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4072              }
4073            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4074            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4075            other_cases += 2;
4076            }
4077          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4078            {
4079            if (charoffset == 0)
4080              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4081            else
4082              {
4083              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4084              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4085              }
4086            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4087            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4088    
4089            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4090            OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4091    
4092            other_cases += 3;
4093            }
4094          else
4095            {
4096            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4097            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4098            }
4099    
4100          while (*other_cases != NOTACHAR)
4101            {
4102            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4103            OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4104            }
4105        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4106        break;        break;
4107        }        }
# Line 2962  while (*cc != XCL_END) Line 4110  while (*cc != XCL_END)
4110  #endif  #endif
4111    
4112    if (jump != NULL)    if (jump != NULL)
4113      add_jump(compiler, compares > 0 ? list : fallbacks, jump);      add_jump(compiler, compares > 0 ? list : backtracks, jump);
4114    }    }
4115    
4116  if (found != NULL)  if (found != NULL)
# Line 2974  if (found != NULL) Line 4122  if (found != NULL)
4122    
4123  #endif  #endif
4124    
4125  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_matchingpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **backtracks)
4126  {  {
4127  DEFINE_COMPILER;  DEFINE_COMPILER;
4128  int length;  int length;
# Line 2993  switch(type) Line 4141  switch(type)
4141    case OP_SOD:    case OP_SOD:
4142    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4143    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));
4144    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));
4145    return cc;    return cc;
4146    
4147    case OP_SOM:    case OP_SOM:
4148    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
4149    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));
4150    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));
4151    return cc;    return cc;
4152    
4153    case OP_NOT_WORD_BOUNDARY:    case OP_NOT_WORD_BOUNDARY:
4154    case OP_WORD_BOUNDARY:    case OP_WORD_BOUNDARY:
4155    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL));
4156    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));
4157    return cc;    return cc;
4158    
4159    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
4160    case OP_DIGIT:    case OP_DIGIT:
4161    check_input_end(common, fallbacks);    /* Digits are usually 0-9, so it is worth to optimize them. */
4162    read_char8_type(common);    if (common->digits[0] == -2)
4163    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);      get_ctype_ranges(common, ctype_digit, common->digits);
4164    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    detect_partial_match(common, backtracks);
4165      /* Flip the starting bit in the negative case. */
4166      if (type == OP_NOT_DIGIT)
4167        common->digits[1] ^= 1;
4168      if (!check_ranges(common, common->digits, backtracks, TRUE))
4169        {
4170        read_char8_type(common);
4171        OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
4172        add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4173        }
4174      if (type == OP_NOT_DIGIT)
4175        common->digits[1] ^= 1;
4176    return cc;    return cc;
4177    
4178    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
4179    case OP_WHITESPACE:    case OP_WHITESPACE:
4180    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4181    read_char8_type(common);    read_char8_type(common);
4182    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
4183    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4184    return cc;    return cc;
4185    
4186    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
4187    case OP_WORDCHAR:    case OP_WORDCHAR:
4188    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4189    read_char8_type(common);    read_char8_type(common);
4190    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
4191    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
4192    return cc;    return cc;
4193    
4194    case OP_ANY:    case OP_ANY:
4195    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4196    read_char(common);    read_char(common);
4197    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4198      {      {
4199      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);      jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4200      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4201          jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4202        else
4203          jump[1] = check_str_end(common);
4204    
4205      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4206      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
4207      JUMPHERE(jump[1]);      if (jump[1] != NULL)
4208          JUMPHERE(jump[1]);
4209      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4210      }      }
4211    else    else
4212      check_newlinechar(common, common->nltype, fallbacks, TRUE);      check_newlinechar(common, common->nltype, backtracks, TRUE);
4213    return cc;    return cc;
4214    
4215    case OP_ALLANY:    case OP_ALLANY:
4216    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4217  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4218    if (common->utf)    if (common->utf)
4219      {      {
4220      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4221      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4222  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4223    #if defined COMPILE_PCRE8
4224      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4225      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4226      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4227  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4228      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4229      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4230      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
4231      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4232      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4233      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4234  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4235      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4236    #endif /* COMPILE_PCRE[8|16] */
4237      return cc;      return cc;
4238      }      }
4239  #endif  #endif
# Line 3077  switch(type) Line 4241  switch(type)
4241    return cc;    return cc;
4242    
4243    case OP_ANYBYTE:    case OP_ANYBYTE:
4244    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4245    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4246    return cc;    return cc;
4247    
# Line 3090  switch(type) Line 4254  switch(type)
4254    propdata[2] = cc[0];    propdata[2] = cc[0];
4255    propdata[3] = cc[1];    propdata[3] = cc[1];
4256    propdata[4] = XCL_END;    propdata[4] = XCL_END;
4257    compile_xclass_hotpath(common, propdata, fallbacks);    compile_xclass_matchingpath(common, propdata, backtracks);
4258    return cc + 2;    return cc + 2;
4259  #endif  #endif
4260  #endif  #endif
4261    
4262    case OP_ANYNL:    case OP_ANYNL:
4263    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4264    read_char(common);    read_char(common);
4265    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);    jump[0] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
4266    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
4267      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4268        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4269      else
4270        jump[1] = check_str_end(common);
4271    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4272    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4273    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
4274    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
4275    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4276    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4277    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4278    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
4279    JUMPHERE(jump[3]);    JUMPHERE(jump[3]);
# Line 3113  switch(type) Line 4281  switch(type)
4281    
4282    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
4283    case OP_HSPACE:    case OP_HSPACE:
4284    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4285    read_char(common);    read_char(common);
4286    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
4287    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4288    return cc;    return cc;
4289    
4290    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
4291    case OP_VSPACE:    case OP_VSPACE:
4292    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4293    read_char(common);    read_char(common);
4294    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
4295    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
4296    return cc;    return cc;
4297    
4298  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4299    case OP_EXTUNI:    case OP_EXTUNI:
4300    check_input_end(common, fallbacks);    detect_partial_match(common, backtracks);
4301    read_char(common);    read_char(common);
4302    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4303    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4304    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4305      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4306      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4307    
4308    label = LABEL();    label = LABEL();
4309    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[0] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
4310    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4311    read_char(common);    read_char(common);
4312    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4313    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4314    CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc, label);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4315    
4316      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4317      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
4318      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4319      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4320      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4321      JUMPTO(SLJIT_C_NOT_ZERO, label);
4322    
4323    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4324    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4325      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4326    
4327      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4328        {
4329        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
4330        /* Since we successfully read a char above, partial matching must occure. */
4331        check_partial(common, TRUE);
4332        JUMPHERE(jump[0]);
4333        }