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

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

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

revision 999 by zherczeg, Mon Aug 6 07:36:49 2012 UTC revision 1278 by zherczeg, Tue Mar 12 06:15:04 2013 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2012 University of Cambridge             Copyright (c) 1997-2013 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2012                        Copyright (c) 2010-2013
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 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. */  /* Defines for debugging purposes. */
 #define LOCAL_SPACE_SIZE 32768  
69    
70    /* 1 - Use unoptimized capturing brackets.
71       2 - Enable capture_last_ptr (includes option 1). */
72    /* #define DEBUG_FORCE_UNOPTIMIZED_CBRAS 2 */
73    
74    /* 1 - Always have a control head. */
75    /* #define DEBUG_FORCE_CONTROL_HEAD 1 */
76    
77    /* Allocate memory for the regex stack on the real machine stack.
78    Fast, but limited size. */
79    #define MACHINE_STACK_SIZE 32768
80    
81    /* Growth rate for stack allocated by the OS. Should be the multiply
82    of page size. */
83  #define STACK_GROWTH_RATE 8192  #define STACK_GROWTH_RATE 8192
84    
85  /* Enable to check that the allocation could destroy temporaries. */  /* Enable to check that the allocation could destroy temporaries. */
# Line 134  The generated code will be the following Line 146  The generated code will be the following
146  /*  /*
147  Saved stack frames:  Saved stack frames:
148    
149  Atomic blocks and asserts require reloading the values of local variables  Atomic blocks and asserts require reloading the values of private data
150  when the backtrack mechanism performed. Because of OP_RECURSE, the locals  when the backtrack mechanism performed. Because of OP_RECURSE, the data
151  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
152  mechanism.  mechanism.
153    
154  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:
155  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]  ([ capturing bracket offset ][ start value ][ end value ])+ ... [ 0 ] [ previous head ]
156    
157  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.
158  */  */
159    
160  typedef struct jit_arguments {  typedef struct jit_arguments {
# Line 154  typedef struct jit_arguments { Line 166  typedef struct jit_arguments {
166    int *offsets;    int *offsets;
167    pcre_uchar *uchar_ptr;    pcre_uchar *uchar_ptr;
168    pcre_uchar *mark_ptr;    pcre_uchar *mark_ptr;
169      void *callout_data;
170    /* Everything else after. */    /* Everything else after. */
171    int offsetcount;    int real_offset_count;
172    int calllimit;    int offset_count;
173      int call_limit;
174    pcre_uint8 notbol;    pcre_uint8 notbol;
175    pcre_uint8 noteol;    pcre_uint8 noteol;
176    pcre_uint8 notempty;    pcre_uint8 notempty;
# Line 167  typedef struct executable_functions { Line 181  typedef struct executable_functions {
181    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
182    PUBL(jit_callback) callback;    PUBL(jit_callback) callback;
183    void *userdata;    void *userdata;
184      pcre_uint32 top_bracket;
185    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
186  } executable_functions;  } executable_functions;
187    
# Line 175  typedef struct jump_list { Line 190  typedef struct jump_list {
190    struct jump_list *next;    struct jump_list *next;
191  } jump_list;  } jump_list;
192    
 enum stub_types { stack_alloc };  
   
193  typedef struct stub_list {  typedef struct stub_list {
   enum stub_types type;  
   int data;  
194    struct sljit_jump *start;    struct sljit_jump *start;
195    struct sljit_label *quit;    struct sljit_label *quit;
196    struct stub_list *next;    struct stub_list *next;
197  } stub_list;  } stub_list;
198    
199    enum frame_types {
200      no_frame = -1,
201      no_stack = -2
202    };
203    
204    enum control_types {
205      type_commit = 0,
206      type_prune = 1,
207      type_skip = 2,
208      type_skip_arg = 3,
209      type_mark = 4
210    };
211    
212  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
213    
214  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
# Line 205  typedef struct backtrack_common { Line 229  typedef struct backtrack_common {
229  typedef struct assert_backtrack {  typedef struct assert_backtrack {
230    backtrack_common common;    backtrack_common common;
231    jump_list *condfailed;    jump_list *condfailed;
232    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
233    int framesize;    int framesize;
234    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
235    int localptr;    int private_data_ptr;
236    /* For iterators. */    /* For iterators. */
237    struct sljit_label *matchingpath;    struct sljit_label *matchingpath;
238  } assert_backtrack;  } assert_backtrack;
# Line 226  typedef struct bracket_backtrack { Line 250  typedef struct bracket_backtrack {
250      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
251      jump_list *condfailed;      jump_list *condfailed;
252      assert_backtrack *assert;      assert_backtrack *assert;
253      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
254      int framesize;      int framesize;
255    } u;    } u;
256    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
257    int localptr;    int private_data_ptr;
258  } bracket_backtrack;  } bracket_backtrack;
259    
260  typedef struct bracketpos_backtrack {  typedef struct bracketpos_backtrack {
261    backtrack_common common;    backtrack_common common;
262    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
263    int localptr;    int private_data_ptr;
264    /* Reverting stack is needed. */    /* Reverting stack is needed. */
265    int framesize;    int framesize;
266    /* Allocated stack size. */    /* Allocated stack size. */
# Line 266  typedef struct recurse_entry { Line 290  typedef struct recurse_entry {
290    
291  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
292    backtrack_common common;    backtrack_common common;
293      BOOL inlined_pattern;
294  } recurse_backtrack;  } recurse_backtrack;
295    
296  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
297    
298  typedef struct compiler_common {  typedef struct compiler_common {
299      /* The sljit ceneric compiler. */
300    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
301      /* First byte code. */
302    pcre_uchar *start;    pcre_uchar *start;
303      /* Maps private data offset to each opcode. */
304    /* Opcode local area direct map. */    int *private_data_ptrs;
305    int *localptrs;    /* Tells whether the capturing bracket is optimized. */
306    int cbraptr;    pcre_uint8 *optimized_cbracket;
307    /* OVector starting point. Must be divisible by 2. */    /* Starting offset of private data for capturing brackets. */
308      int cbra_ptr;
309      /* Output vector starting point. Must be divisible by 2. */
310    int ovector_start;    int ovector_start;
311    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
312    int req_char_ptr;    int req_char_ptr;
313    /* Head of the last recursion. */    /* Head of the last recursion. */
314    int recursive_head;    int recursive_head_ptr;
315    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
316    int start_used_ptr;    int start_used_ptr;
317    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 291  typedef struct compiler_common { Line 320  typedef struct compiler_common {
320    int first_line_end;    int first_line_end;
321    /* Points to the marked string. */    /* Points to the marked string. */
322    int mark_ptr;    int mark_ptr;
323      /* Recursive control verb management chain. */
324      int control_head_ptr;
325      /* Points to the last matched capture block index. */
326      int capture_last_ptr;
327      /* Points to the starting position of the current match. */
328      int start_ptr;
329    
330    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
331    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
332    sljit_w lcc;    sljit_sw lcc;
333    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
334    int mode;    int mode;
335      /* \K is in the pattern. */
336      BOOL has_set_som;
337      /* (*SKIP:arg) is in the pattern. */
338      BOOL has_skip_arg;
339      /* Needs to know the start position anytime. */
340      BOOL needs_start_ptr;
341      /* Currently in recurse or assert. */
342      BOOL local_exit;
343    /* Newline control. */    /* Newline control. */
344    int nltype;    int nltype;
345    int newline;    int newline;
346    int bsr_nltype;    int bsr_nltype;
347    /* Dollar endonly. */    /* Dollar endonly. */
348    int endonly;    int endonly;
   BOOL has_set_som;  
349    /* Tables. */    /* Tables. */
350    sljit_w ctypes;    sljit_sw ctypes;
351    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
352    /* Named capturing brackets. */    /* Named capturing brackets. */
353    sljit_uw name_table;    sljit_uw name_table;
354    sljit_w name_count;    sljit_sw name_count;
355    sljit_w name_entry_size;    sljit_sw name_entry_size;
356    
357    /* Labels and jump lists. */    /* Labels and jump lists. */
358    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
359    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
360    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
361      struct sljit_label *accept_label;
362    stub_list *stubs;    stub_list *stubs;
363    recurse_entry *entries;    recurse_entry *entries;
364    recurse_entry *currententry;    recurse_entry *currententry;
365    jump_list *partialmatch;    jump_list *partialmatch;
366    jump_list *quit;    jump_list *quit;
367      jump_list *forced_quit;
368    jump_list *accept;    jump_list *accept;
369    jump_list *calllimit;    jump_list *calllimit;
370    jump_list *stackalloc;    jump_list *stackalloc;
# Line 331  typedef struct compiler_common { Line 375  typedef struct compiler_common {
375    jump_list *vspace;    jump_list *vspace;
376    jump_list *casefulcmp;    jump_list *casefulcmp;
377    jump_list *caselesscmp;    jump_list *caselesscmp;
378      jump_list *reset_match;
379    BOOL jscript_compat;    BOOL jscript_compat;
380  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
381    BOOL utf;    BOOL utf;
382  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
383    BOOL use_ucp;    BOOL use_ucp;
384  #endif  #endif
385    #ifndef COMPILE_PCRE32
386    jump_list *utfreadchar;    jump_list *utfreadchar;
387    #endif
388  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
389    jump_list *utfreadtype8;    jump_list *utfreadtype8;
390  #endif  #endif
# Line 355  typedef struct compare_context { Line 402  typedef struct compare_context {
402  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
403    int ucharptr;    int ucharptr;
404    union {    union {
405      sljit_i asint;      sljit_si asint;
406      sljit_uh asushort;      sljit_uh asushort;
407  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
408      sljit_ub asbyte;      sljit_ub asbyte;
409      sljit_ub asuchars[4];      sljit_ub asuchars[4];
410  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
411      sljit_uh asuchars[2];      sljit_uh asuchars[2];
412  #endif  #elif defined COMPILE_PCRE32
413        sljit_ui asuchars[1];
414  #endif  #endif
415    } c;    } c;
416    union {    union {
417      sljit_i asint;      sljit_si asint;
418      sljit_uh asushort;      sljit_uh asushort;
419  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
420      sljit_ub asbyte;      sljit_ub asbyte;
421      sljit_ub asuchars[4];      sljit_ub asuchars[4];
422  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
423      sljit_uh asuchars[2];      sljit_uh asuchars[2];
424  #endif  #elif defined COMPILE_PCRE32
425        sljit_ui asuchars[1];
426  #endif  #endif
427    } oc;    } oc;
428  #endif  #endif
429  } compare_context;  } compare_context;
430    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
431  /* Undefine sljit macros. */  /* Undefine sljit macros. */
432  #undef CMP  #undef CMP
433    
434  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
435  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
436    
437  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
438  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
439  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
440  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_SAVED_REG1
441  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_SAVED_REG2
442  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
443  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
444  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
445  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
446  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
447    
448  /* Locals layout. */  /* Local space layout. */
449  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
450  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
451  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
452  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
453  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
454  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
455  /* Max limit of recursions. */  /* Max limit of recursions. */
456  #define CALL_LIMIT       (4 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
457  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
458  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
459  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
460  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. */
461  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
462  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
463  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
464  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
465    
466  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
467  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
468  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
469  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
470  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
471  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
472    #elif defined COMPILE_PCRE32
473    #define MOV_UCHAR  SLJIT_MOV_UI
474    #define MOVU_UCHAR SLJIT_MOVU_UI
475  #else  #else
476  #error Unsupported compiling mode  #error Unsupported compiling mode
477  #endif  #endif
 #endif  
478    
479  /* Shortcuts. */  /* Shortcuts. */
480  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 449  the start pointers when the end of the c Line 491  the start pointers when the end of the c
491    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
492  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
493    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
494    #define SET_LABEL(jump, label) \
495      sljit_set_label((jump), (label))
496  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
497    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
498  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
499    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))
500  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
501    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
502  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
503    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
504    
# Line 469  return cc; Line 513  return cc;
513    
514  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
515   next_opcode   next_opcode
516   get_localspace   get_private_data_length
517   set_localptrs   set_private_data_ptrs
518   get_framesize   get_framesize
519   init_frame   init_frame
520   get_localsize   get_private_data_copy_length
521   copy_locals   copy_private_data
522   compile_matchingpath   compile_matchingpath
523   compile_backtrackingpath   compile_backtrackingpath
524  */  */
# Line 497  switch(*cc) Line 541  switch(*cc)
541    case OP_WORDCHAR:    case OP_WORDCHAR:
542    case OP_ANY:    case OP_ANY:
543    case OP_ALLANY:    case OP_ALLANY:
544      case OP_NOTPROP:
545      case OP_PROP:
546    case OP_ANYNL:    case OP_ANYNL:
547    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
548    case OP_HSPACE:    case OP_HSPACE:
# Line 509  switch(*cc) Line 555  switch(*cc)
555    case OP_CIRCM:    case OP_CIRCM:
556    case OP_DOLL:    case OP_DOLL:
557    case OP_DOLLM:    case OP_DOLLM:
   case OP_TYPESTAR:  
   case OP_TYPEMINSTAR:  
   case OP_TYPEPLUS:  
   case OP_TYPEMINPLUS:  
   case OP_TYPEQUERY:  
   case OP_TYPEMINQUERY:  
   case OP_TYPEPOSSTAR:  
   case OP_TYPEPOSPLUS:  
   case OP_TYPEPOSQUERY:  
558    case OP_CRSTAR:    case OP_CRSTAR:
559    case OP_CRMINSTAR:    case OP_CRMINSTAR:
560    case OP_CRPLUS:    case OP_CRPLUS:
561    case OP_CRMINPLUS:    case OP_CRMINPLUS:
562    case OP_CRQUERY:    case OP_CRQUERY:
563    case OP_CRMINQUERY:    case OP_CRMINQUERY:
564      case OP_CRRANGE:
565      case OP_CRMINRANGE:
566      case OP_CLASS:
567      case OP_NCLASS:
568      case OP_REF:
569      case OP_REFI:
570      case OP_RECURSE:
571      case OP_CALLOUT:
572      case OP_ALT:
573      case OP_KET:
574      case OP_KETRMAX:
575      case OP_KETRMIN:
576      case OP_KETRPOS:
577      case OP_REVERSE:
578      case OP_ASSERT:
579      case OP_ASSERT_NOT:
580      case OP_ASSERTBACK:
581      case OP_ASSERTBACK_NOT:
582      case OP_ONCE:
583      case OP_ONCE_NC:
584      case OP_BRA:
585      case OP_BRAPOS:
586      case OP_CBRA:
587      case OP_CBRAPOS:
588      case OP_COND:
589      case OP_SBRA:
590      case OP_SBRAPOS:
591      case OP_SCBRA:
592      case OP_SCBRAPOS:
593      case OP_SCOND:
594      case OP_CREF:
595      case OP_NCREF:
596      case OP_RREF:
597      case OP_NRREF:
598    case OP_DEF:    case OP_DEF:
599    case OP_BRAZERO:    case OP_BRAZERO:
600    case OP_BRAMINZERO:    case OP_BRAMINZERO:
601    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
602      case OP_PRUNE:
603      case OP_SKIP:
604    case OP_COMMIT:    case OP_COMMIT:
605    case OP_FAIL:    case OP_FAIL:
606    case OP_ACCEPT:    case OP_ACCEPT:
607    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
608      case OP_CLOSE:
609    case OP_SKIPZERO:    case OP_SKIPZERO:
610    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
611    
612    case OP_CHAR:    case OP_CHAR:
613    case OP_CHARI:    case OP_CHARI:
# Line 551  switch(*cc) Line 619  switch(*cc)
619    case OP_MINPLUS:    case OP_MINPLUS:
620    case OP_QUERY:    case OP_QUERY:
621    case OP_MINQUERY:    case OP_MINQUERY:
622      case OP_UPTO:
623      case OP_MINUPTO:
624      case OP_EXACT:
625    case OP_POSSTAR:    case OP_POSSTAR:
626    case OP_POSPLUS:    case OP_POSPLUS:
627    case OP_POSQUERY:    case OP_POSQUERY:
628      case OP_POSUPTO:
629    case OP_STARI:    case OP_STARI:
630    case OP_MINSTARI:    case OP_MINSTARI:
631    case OP_PLUSI:    case OP_PLUSI:
632    case OP_MINPLUSI:    case OP_MINPLUSI:
633    case OP_QUERYI:    case OP_QUERYI:
634    case OP_MINQUERYI:    case OP_MINQUERYI:
635      case OP_UPTOI:
636      case OP_MINUPTOI:
637      case OP_EXACTI:
638    case OP_POSSTARI:    case OP_POSSTARI:
639    case OP_POSPLUSI:    case OP_POSPLUSI:
640    case OP_POSQUERYI:    case OP_POSQUERYI:
641      case OP_POSUPTOI:
642    case OP_NOTSTAR:    case OP_NOTSTAR:
643    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
644    case OP_NOTPLUS:    case OP_NOTPLUS:
645    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
646    case OP_NOTQUERY:    case OP_NOTQUERY:
647    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
648      case OP_NOTUPTO:
649      case OP_NOTMINUPTO:
650      case OP_NOTEXACT:
651    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
652    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
653    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
654      case OP_NOTPOSUPTO:
655    case OP_NOTSTARI:    case OP_NOTSTARI:
656    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
657    case OP_NOTPLUSI:    case OP_NOTPLUSI:
658    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
659    case OP_NOTQUERYI:    case OP_NOTQUERYI:
660    case OP_NOTMINQUERYI:    case OP_NOTMINQUERYI:
   case OP_NOTPOSSTARI:  
   case OP_NOTPOSPLUSI:  
   case OP_NOTPOSQUERYI:  
   cc += 2;  
 #ifdef SUPPORT_UTF  
   if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);  
 #endif  
   return cc;  
   
   case OP_UPTO:  
   case OP_MINUPTO:  
   case OP_EXACT:  
   case OP_POSUPTO:  
   case OP_UPTOI:  
   case OP_MINUPTOI:  
   case OP_EXACTI:  
   case OP_POSUPTOI:  
   case OP_NOTUPTO:  
   case OP_NOTMINUPTO:  
   case OP_NOTEXACT:  
   case OP_NOTPOSUPTO:  
661    case OP_NOTUPTOI:    case OP_NOTUPTOI:
662    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
663    case OP_NOTEXACTI:    case OP_NOTEXACTI:
664      case OP_NOTPOSSTARI:
665      case OP_NOTPOSPLUSI:
666      case OP_NOTPOSQUERYI:
667    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
668    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
669  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
670    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
671  #endif  #endif
672    return cc;    return cc;
673    
674    case OP_NOTPROP:    /* Special cases. */
675    case OP_PROP:    case OP_TYPESTAR:
676    return cc + 1 + 2;    case OP_TYPEMINSTAR:
677      case OP_TYPEPLUS:
678      case OP_TYPEMINPLUS:
679      case OP_TYPEQUERY:
680      case OP_TYPEMINQUERY:
681    case OP_TYPEUPTO:    case OP_TYPEUPTO:
682    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
683    case OP_TYPEEXACT:    case OP_TYPEEXACT:
684      case OP_TYPEPOSSTAR:
685      case OP_TYPEPOSPLUS:
686      case OP_TYPEPOSQUERY:
687    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
688    case OP_REF:    return cc + PRIV(OP_lengths)[*cc] - 1;
   case OP_REFI:  
   case OP_CREF:  
   case OP_NCREF:  
   case OP_RREF:  
   case OP_NRREF:  
   case OP_CLOSE:  
   cc += 1 + IMM2_SIZE;  
   return cc;  
   
   case OP_CRRANGE:  
   case OP_CRMINRANGE:  
   return cc + 1 + 2 * IMM2_SIZE;  
689    
690    case OP_CLASS:    case OP_ANYBYTE:
691    case OP_NCLASS:  #ifdef SUPPORT_UTF
692    return cc + 1 + 32 / sizeof(pcre_uchar);    if (common->utf) return NULL;
693    #endif
694      return cc + 1;
695    
696  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
697    case OP_XCLASS:    case OP_XCLASS:
698    return cc + GET(cc, 1);    return cc + GET(cc, 1);
699  #endif  #endif
700    
   case OP_RECURSE:  
   case OP_ASSERT:  
   case OP_ASSERT_NOT:  
   case OP_ASSERTBACK:  
   case OP_ASSERTBACK_NOT:  
   case OP_REVERSE:  
   case OP_ONCE:  
   case OP_ONCE_NC:  
   case OP_BRA:  
   case OP_BRAPOS:  
   case OP_COND:  
   case OP_SBRA:  
   case OP_SBRAPOS:  
   case OP_SCOND:  
   case OP_ALT:  
   case OP_KET:  
   case OP_KETRMAX:  
   case OP_KETRMIN:  
   case OP_KETRPOS:  
   return cc + 1 + LINK_SIZE;  
   
   case OP_CBRA:  
   case OP_CBRAPOS:  
   case OP_SCBRA:  
   case OP_SCBRAPOS:  
   return cc + 1 + LINK_SIZE + IMM2_SIZE;  
   
701    case OP_MARK:    case OP_MARK:
702      case OP_PRUNE_ARG:
703      case OP_SKIP_ARG:
704    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
705    
706    default:    default:
# Line 675  switch(*cc) Line 708  switch(*cc)
708    }    }
709  }  }
710    
711  #define CASE_ITERATOR_LOCAL1 \  #define CASE_ITERATOR_PRIVATE_DATA_1 \
712      case OP_MINSTAR: \      case OP_MINSTAR: \
713      case OP_MINPLUS: \      case OP_MINPLUS: \
714      case OP_QUERY: \      case OP_QUERY: \
# Line 693  switch(*cc) Line 726  switch(*cc)
726      case OP_NOTQUERYI: \      case OP_NOTQUERYI: \
727      case OP_NOTMINQUERYI:      case OP_NOTMINQUERYI:
728    
729  #define CASE_ITERATOR_LOCAL2A \  #define CASE_ITERATOR_PRIVATE_DATA_2A \
730      case OP_STAR: \      case OP_STAR: \
731      case OP_PLUS: \      case OP_PLUS: \
732      case OP_STARI: \      case OP_STARI: \
# Line 703  switch(*cc) Line 736  switch(*cc)
736      case OP_NOTSTARI: \      case OP_NOTSTARI: \
737      case OP_NOTPLUSI:      case OP_NOTPLUSI:
738    
739  #define CASE_ITERATOR_LOCAL2B \  #define CASE_ITERATOR_PRIVATE_DATA_2B \
740      case OP_UPTO: \      case OP_UPTO: \
741      case OP_MINUPTO: \      case OP_MINUPTO: \
742      case OP_UPTOI: \      case OP_UPTOI: \
# Line 713  switch(*cc) Line 746  switch(*cc)
746      case OP_NOTUPTOI: \      case OP_NOTUPTOI: \
747      case OP_NOTMINUPTOI:      case OP_NOTMINUPTOI:
748    
749  #define CASE_ITERATOR_TYPE_LOCAL1 \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_1 \
750      case OP_TYPEMINSTAR: \      case OP_TYPEMINSTAR: \
751      case OP_TYPEMINPLUS: \      case OP_TYPEMINPLUS: \
752      case OP_TYPEQUERY: \      case OP_TYPEQUERY: \
753      case OP_TYPEMINQUERY:      case OP_TYPEMINQUERY:
754    
755  #define CASE_ITERATOR_TYPE_LOCAL2A \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2A \
756      case OP_TYPESTAR: \      case OP_TYPESTAR: \
757      case OP_TYPEPLUS:      case OP_TYPEPLUS:
758    
759  #define CASE_ITERATOR_TYPE_LOCAL2B \  #define CASE_ITERATOR_TYPE_PRIVATE_DATA_2B \
760      case OP_TYPEUPTO: \      case OP_TYPEUPTO: \
761      case OP_TYPEMINUPTO:      case OP_TYPEMINUPTO:
762    
# Line 752  switch(*cc) Line 785  switch(*cc)
785    }    }
786  }  }
787    
788  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static int get_private_data_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
789  {  {
790  int localspace = 0;  int private_data_length = 0;
791  pcre_uchar *alternative;  pcre_uchar *alternative;
792    pcre_uchar *name;
793  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
794  int space, size, bracketlen;  int space, size, i;
795    pcre_uint32 bracketlen;
796    
797  /* 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. */
798  while (cc < ccend)  while (cc < ccend)
# Line 772  while (cc < ccend) Line 807  while (cc < ccend)
807      cc += 1;      cc += 1;
808      break;      break;
809    
810        case OP_REF:
811        case OP_REFI:
812        common->optimized_cbracket[GET2(cc, 1)] = 0;
813        cc += 1 + IMM2_SIZE;
814        break;
815    
816      case OP_ASSERT:      case OP_ASSERT:
817      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
818      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 781  while (cc < ccend) Line 822  while (cc < ccend)
822      case OP_BRAPOS:      case OP_BRAPOS:
823      case OP_SBRA:      case OP_SBRA:
824      case OP_SBRAPOS:      case OP_SBRAPOS:
825      case OP_SCOND:      private_data_length += sizeof(sljit_sw);
     localspace += sizeof(sljit_w);  
826      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
827      break;      break;
828    
829      case OP_CBRAPOS:      case OP_CBRAPOS:
830      case OP_SCBRAPOS:      case OP_SCBRAPOS:
831      localspace += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
832        common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
833      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
834      break;      break;
835    
836      case OP_COND:      case OP_COND:
837      /* Might be a hidden SCOND. */      case OP_SCOND:
838      alternative = cc + GET(cc, 1);      /* Only AUTO_CALLOUT can insert this opcode. We do
839      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)         not intend to support this case. */
840        localspace += sizeof(sljit_w);      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
841          return -1;
842    
843        if (*cc == OP_COND)
844          {
845          /* Might be a hidden SCOND. */
846          alternative = cc + GET(cc, 1);
847          if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
848            private_data_length += sizeof(sljit_sw);
849          }
850        else
851          private_data_length += sizeof(sljit_sw);
852      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
853      break;      break;
854    
855        case OP_CREF:
856        i = GET2(cc, 1);
857        common->optimized_cbracket[i] = 0;
858        cc += 1 + IMM2_SIZE;
859        break;
860    
861        case OP_NCREF:
862        bracketlen = GET2(cc, 1);
863        name = (pcre_uchar *)common->name_table;
864        alternative = name;
865        for (i = 0; i < common->name_count; i++)
866          {
867          if (GET2(name, 0) == bracketlen) break;
868          name += common->name_entry_size;
869          }
870        SLJIT_ASSERT(i != common->name_count);
871    
872        for (i = 0; i < common->name_count; i++)
873          {
874          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
875            common->optimized_cbracket[GET2(alternative, 0)] = 0;
876          alternative += common->name_entry_size;
877          }
878        bracketlen = 0;
879        cc += 1 + IMM2_SIZE;
880        break;
881    
882      case OP_BRA:      case OP_BRA:
883      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
884      break;      break;
# Line 809  while (cc < ccend) Line 888  while (cc < ccend)
888      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
889      break;      break;
890    
891      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
892      space = 1;      space = 1;
893      size = -2;      size = -2;
894      break;      break;
895    
896      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
897      space = 2;      space = 2;
898      size = -2;      size = -2;
899      break;      break;
900    
901      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
902      space = 2;      space = 2;
903      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
904      break;      break;
905    
906      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
907      space = 1;      space = 1;
908      size = 1;      size = 1;
909      break;      break;
910    
911      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
912      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
913        space = 2;        space = 2;
914      size = 1;      size = 1;
915      break;      break;
916    
917      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
918      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
919        space = 2;        space = 2;
920      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 856  while (cc < ccend) Line 935  while (cc < ccend)
935    
936      case OP_RECURSE:      case OP_RECURSE:
937      /* Set its value only once. */      /* Set its value only once. */
938      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
939        {        {
940        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
941        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
942        }        }
943      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
944      break;      break;
945    
946        case OP_CALLOUT:
947        if (common->capture_last_ptr == 0)
948          {
949          common->capture_last_ptr = common->ovector_start;
950          common->ovector_start += sizeof(sljit_sw);
951          }
952        cc += 2 + 2 * LINK_SIZE;
953        break;
954    
955        case OP_PRUNE_ARG:
956        common->needs_start_ptr = TRUE;
957        common->control_head_ptr = 1;
958        /* Fall through. */
959    
960      case OP_MARK:      case OP_MARK:
961      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
962        {        {
963        common->mark_ptr = common->ovector_start;        common->mark_ptr = common->ovector_start;
964        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
965        }        }
966      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
967      break;      break;
968    
969        case OP_PRUNE:
970        case OP_SKIP:
971        common->needs_start_ptr = TRUE;
972        common->control_head_ptr = 1;
973        cc += 1;
974        break;
975    
976        case OP_SKIP_ARG:
977        common->control_head_ptr = 1;
978        common->has_skip_arg = TRUE;
979        cc += 1 + 2 + cc[1];
980        break;
981    
982      default:      default:
983      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
984      if (cc == NULL)      if (cc == NULL)
# Line 881  while (cc < ccend) Line 987  while (cc < ccend)
987      }      }
988    
989    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
990      localspace += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_sw) * space;
991    
992    if (size != 0)    if (size != 0)
993      {      {
# Line 896  while (cc < ccend) Line 1002  while (cc < ccend)
1002        cc += size;        cc += size;
1003      }      }
1004    
1005    if (bracketlen > 0)    if (bracketlen != 0)
1006      {      {
1007      if (cc >= end)      if (cc >= end)
1008        {        {
# Line 907  while (cc < ccend) Line 1013  while (cc < ccend)
1013      cc += bracketlen;      cc += bracketlen;
1014      }      }
1015    }    }
1016  return localspace;  return private_data_length;
1017  }  }
1018    
1019  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)
1020  {  {
1021  pcre_uchar *cc = common->start;  pcre_uchar *cc = common->start;
1022  pcre_uchar *alternative;  pcre_uchar *alternative;
# Line 934  while (cc < ccend) Line 1040  while (cc < ccend)
1040      case OP_SBRA:      case OP_SBRA:
1041      case OP_SBRAPOS:      case OP_SBRAPOS:
1042      case OP_SCOND:      case OP_SCOND:
1043      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1044      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1045      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1046      break;      break;
1047    
1048      case OP_CBRAPOS:      case OP_CBRAPOS:
1049      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1050      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1051      localptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1052      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1053      break;      break;
1054    
# Line 951  while (cc < ccend) Line 1057  while (cc < ccend)
1057      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1058      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1059        {        {
1060        common->localptrs[cc - common->start] = localptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1061        localptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1062        }        }
1063      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1064      break;      break;
# Line 966  while (cc < ccend) Line 1072  while (cc < ccend)
1072      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1073      break;      break;
1074    
1075      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1076      space = 1;      space = 1;
1077      size = -2;      size = -2;
1078      break;      break;
1079    
1080      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1081      space = 2;      space = 2;
1082      size = -2;      size = -2;
1083      break;      break;
1084    
1085      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1086      space = 2;      space = 2;
1087      size = -(2 + IMM2_SIZE);      size = -(2 + IMM2_SIZE);
1088      break;      break;
1089    
1090      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1091      space = 1;      space = 1;
1092      size = 1;      size = 1;
1093      break;      break;
1094    
1095      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1096      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)      if (cc[1] != OP_ANYNL && cc[1] != OP_EXTUNI)
1097        space = 2;        space = 2;
1098      size = 1;      size = 1;
1099      break;      break;
1100    
1101      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1102      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)      if (cc[1 + IMM2_SIZE] != OP_ANYNL && cc[1 + IMM2_SIZE] != OP_EXTUNI)
1103        space = 2;        space = 2;
1104      size = 1 + IMM2_SIZE;      size = 1 + IMM2_SIZE;
# Line 1019  while (cc < ccend) Line 1125  while (cc < ccend)
1125    
1126    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1127      {      {
1128      common->localptrs[cc - common->start] = localptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1129      localptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_sw) * space;
1130      }      }
1131    
1132    if (size != 0)    if (size != 0)
# Line 1049  while (cc < ccend) Line 1155  while (cc < ccend)
1155    }    }
1156  }  }
1157    
1158  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1159  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive, BOOL* needs_control_head)
1160  {  {
1161  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1162  int length = 0;  int length = 0;
1163  BOOL possessive = FALSE;  int possessive = 0;
1164    BOOL stack_restore = FALSE;
1165  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1166  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1167    /* The last capture is a local variable even for recursions. */
1168    BOOL capture_last_found = FALSE;
1169    
1170    #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1171    SLJIT_ASSERT(common->control_head_ptr != 0);
1172    *needs_control_head = TRUE;
1173    #else
1174    *needs_control_head = FALSE;
1175    #endif
1176    
1177  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1178    {    {
1179    length = 3;    possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1180    possessive = TRUE;    /* This is correct regardless of common->capture_last_ptr. */
1181      capture_last_found = TRUE;
1182    }    }
1183    
1184  cc = next_opcode(common, cc);  cc = next_opcode(common, cc);
# Line 1071  while (cc < ccend) Line 1188  while (cc < ccend)
1188      {      {
1189      case OP_SET_SOM:      case OP_SET_SOM:
1190      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1191        stack_restore = TRUE;
1192      if (!setsom_found)      if (!setsom_found)
1193        {        {
1194        length += 2;        length += 2;
# Line 1080  while (cc < ccend) Line 1198  while (cc < ccend)
1198      break;      break;
1199    
1200      case OP_MARK:      case OP_MARK:
1201        case OP_PRUNE_ARG:
1202      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1203        stack_restore = TRUE;
1204      if (!setmark_found)      if (!setmark_found)
1205        {        {
1206        length += 2;        length += 2;
1207        setmark_found = TRUE;        setmark_found = TRUE;
1208        }        }
1209        if (common->control_head_ptr != 0)
1210          *needs_control_head = TRUE;
1211      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1212      break;      break;
1213    
1214      case OP_RECURSE:      case OP_RECURSE:
1215        stack_restore = TRUE;
1216      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1217        {        {
1218        length += 2;        length += 2;
# Line 1100  while (cc < ccend) Line 1223  while (cc < ccend)
1223        length += 2;        length += 2;
1224        setmark_found = TRUE;        setmark_found = TRUE;
1225        }        }
1226        if (common->capture_last_ptr != 0 && !capture_last_found)
1227          {
1228          length += 2;
1229          capture_last_found = TRUE;
1230          }
1231      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1232      break;      break;
1233    
# Line 1107  while (cc < ccend) Line 1235  while (cc < ccend)
1235      case OP_CBRAPOS:      case OP_CBRAPOS:
1236      case OP_SCBRA:      case OP_SCBRA:
1237      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1238        stack_restore = TRUE;
1239        if (common->capture_last_ptr != 0 && !capture_last_found)
1240          {
1241          length += 2;
1242          capture_last_found = TRUE;
1243          }
1244      length += 3;      length += 3;
1245      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1246      break;      break;
1247    
1248        case OP_PRUNE:
1249        case OP_SKIP:
1250        case OP_SKIP_ARG:
1251        case OP_COMMIT:
1252        if (common->control_head_ptr != 0)
1253          *needs_control_head = TRUE;
1254        /* Fall through. */
1255    
1256      default:      default:
1257        stack_restore = TRUE;
1258        /* Fall through. */
1259    
1260        case OP_NOT_WORD_BOUNDARY:
1261        case OP_WORD_BOUNDARY:
1262        case OP_NOT_DIGIT:
1263        case OP_DIGIT:
1264        case OP_NOT_WHITESPACE:
1265        case OP_WHITESPACE:
1266        case OP_NOT_WORDCHAR:
1267        case OP_WORDCHAR:
1268        case OP_ANY:
1269        case OP_ALLANY:
1270        case OP_ANYBYTE:
1271        case OP_NOTPROP:
1272        case OP_PROP:
1273        case OP_ANYNL:
1274        case OP_NOT_HSPACE:
1275        case OP_HSPACE:
1276        case OP_NOT_VSPACE:
1277        case OP_VSPACE:
1278        case OP_EXTUNI:
1279        case OP_EODN:
1280        case OP_EOD:
1281        case OP_CIRC:
1282        case OP_CIRCM:
1283        case OP_DOLL:
1284        case OP_DOLLM:
1285        case OP_CHAR:
1286        case OP_CHARI:
1287        case OP_NOT:
1288        case OP_NOTI:
1289    
1290        case OP_EXACT:
1291        case OP_POSSTAR:
1292        case OP_POSPLUS:
1293        case OP_POSQUERY:
1294        case OP_POSUPTO:
1295    
1296        case OP_EXACTI:
1297        case OP_POSSTARI:
1298        case OP_POSPLUSI:
1299        case OP_POSQUERYI:
1300        case OP_POSUPTOI:
1301    
1302        case OP_NOTEXACT:
1303        case OP_NOTPOSSTAR:
1304        case OP_NOTPOSPLUS:
1305        case OP_NOTPOSQUERY:
1306        case OP_NOTPOSUPTO:
1307    
1308        case OP_NOTEXACTI:
1309        case OP_NOTPOSSTARI:
1310        case OP_NOTPOSPLUSI:
1311        case OP_NOTPOSQUERYI:
1312        case OP_NOTPOSUPTOI:
1313    
1314        case OP_TYPEEXACT:
1315        case OP_TYPEPOSSTAR:
1316        case OP_TYPEPOSPLUS:
1317        case OP_TYPEPOSQUERY:
1318        case OP_TYPEPOSUPTO:
1319    
1320        case OP_CLASS:
1321        case OP_NCLASS:
1322        case OP_XCLASS:
1323    
1324      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1325      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1326      break;      break;
1327      }      }
1328    
1329  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1330  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1331    return -1;    return stack_restore ? no_frame : no_stack;
1332    
1333  if (length > 0)  if (length > 0)
1334    return length + 1;    return length + 1;
1335  return -1;  return stack_restore ? no_frame : no_stack;
1336  }  }
1337    
1338  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
1339  {  {
1340  DEFINE_COMPILER;  DEFINE_COMPILER;
1341  pcre_uchar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc) - (1 + LINK_SIZE);
1342  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1343  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1344    /* The last capture is a local variable even for recursions. */
1345    BOOL capture_last_found = FALSE;
1346  int offset;  int offset;
1347    
1348  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1150  while (cc < ccend) Line 1361  while (cc < ccend)
1361      if (!setsom_found)      if (!setsom_found)
1362        {        {
1363        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1364        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1365        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1366        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1367        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1368        setsom_found = TRUE;        setsom_found = TRUE;
1369        }        }
1370      cc += 1;      cc += 1;
1371      break;      break;
1372    
1373      case OP_MARK:      case OP_MARK:
1374        case OP_PRUNE_ARG:
1375      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1376      if (!setmark_found)      if (!setmark_found)
1377        {        {
1378        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1379        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1380        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1381        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1382        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1383        setmark_found = TRUE;        setmark_found = TRUE;
1384        }        }
1385      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
# Line 1177  while (cc < ccend) Line 1389  while (cc < ccend)
1389      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1390        {        {
1391        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1392        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1393        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1394        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1395        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1396        setsom_found = TRUE;        setsom_found = TRUE;
1397        }        }
1398      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1399        {        {
1400        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1401        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->mark_ptr);
1402        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1403        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1404        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1405        setmark_found = TRUE;        setmark_found = TRUE;
1406        }        }
1407        if (common->capture_last_ptr != 0 && !capture_last_found)
1408          {
1409          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1410          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1411          stackpos += (int)sizeof(sljit_sw);
1412          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1413          stackpos += (int)sizeof(sljit_sw);
1414          capture_last_found = TRUE;
1415          }
1416      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1417      break;      break;
1418    
# Line 1199  while (cc < ccend) Line 1420  while (cc < ccend)
1420      case OP_CBRAPOS:      case OP_CBRAPOS:
1421      case OP_SCBRA:      case OP_SCBRA:
1422      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1423        if (common->capture_last_ptr != 0 && !capture_last_found)
1424          {
1425          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1426          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1427          stackpos += (int)sizeof(sljit_sw);
1428          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1429          stackpos += (int)sizeof(sljit_sw);
1430          capture_last_found = TRUE;
1431          }
1432      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1433      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1434      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1435      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1436      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));
1437      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1438      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1439      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1440      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1441    
1442      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1443      break;      break;
# Line 1218  while (cc < ccend) Line 1448  while (cc < ccend)
1448      break;      break;
1449      }      }
1450    
1451  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1452  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1453  }  }
1454    
1455  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)  static SLJIT_INLINE int get_private_data_copy_length(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL needs_control_head)
1456  {  {
1457  int localsize = 2;  int private_data_length = needs_control_head ? 3 : 2;
1458  int size;  int size;
1459  pcre_uchar *alternative;  pcre_uchar *alternative;
1460  /* Calculate the sum of the local variables. */  /* Calculate the sum of the private machine words. */
1461  while (cc < ccend)  while (cc < ccend)
1462    {    {
1463    size = 0;    size = 0;
# Line 1243  while (cc < ccend) Line 1473  while (cc < ccend)
1473      case OP_SBRA:      case OP_SBRA:
1474      case OP_SBRAPOS:      case OP_SBRAPOS:
1475      case OP_SCOND:      case OP_SCOND:
1476      localsize++;      private_data_length++;
1477      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1478      break;      break;
1479    
1480      case OP_CBRA:      case OP_CBRA:
1481      case OP_SCBRA:      case OP_SCBRA:
1482      localsize++;      if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1483          private_data_length++;
1484      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1485      break;      break;
1486    
1487      case OP_CBRAPOS:      case OP_CBRAPOS:
1488      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1489      localsize += 2;      private_data_length += 2;
1490      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1491      break;      break;
1492    
# Line 1263  while (cc < ccend) Line 1494  while (cc < ccend)
1494      /* Might be a hidden SCOND. */      /* Might be a hidden SCOND. */
1495      alternative = cc + GET(cc, 1);      alternative = cc + GET(cc, 1);
1496      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1497        localsize++;        private_data_length++;
1498      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1499      break;      break;
1500    
1501      CASE_ITERATOR_LOCAL1      CASE_ITERATOR_PRIVATE_DATA_1
1502      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1503        localsize++;        private_data_length++;
1504      cc += 2;      cc += 2;
1505  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1506      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1507  #endif  #endif
1508      break;      break;
1509    
1510      CASE_ITERATOR_LOCAL2A      CASE_ITERATOR_PRIVATE_DATA_2A
1511      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1512        localsize += 2;        private_data_length += 2;
1513      cc += 2;      cc += 2;
1514  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1515      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1516  #endif  #endif
1517      break;      break;
1518    
1519      CASE_ITERATOR_LOCAL2B      CASE_ITERATOR_PRIVATE_DATA_2B
1520      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1521        localsize += 2;        private_data_length += 2;
1522      cc += 2 + IMM2_SIZE;      cc += 2 + IMM2_SIZE;
1523  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
1524      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
1525  #endif  #endif
1526      break;      break;
1527    
1528      CASE_ITERATOR_TYPE_LOCAL1      CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1529      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1530        localsize++;        private_data_length++;
1531      cc += 1;      cc += 1;
1532      break;      break;
1533    
1534      CASE_ITERATOR_TYPE_LOCAL2A      CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1535      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1536        localsize += 2;        private_data_length += 2;
1537      cc += 1;      cc += 1;
1538      break;      break;
1539    
1540      CASE_ITERATOR_TYPE_LOCAL2B      CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1541      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1542        localsize += 2;        private_data_length += 2;
1543      cc += 1 + IMM2_SIZE;      cc += 1 + IMM2_SIZE;
1544      break;      break;
1545    
# Line 1320  while (cc < ccend) Line 1551  while (cc < ccend)
1551  #else  #else
1552      size = 1 + 32 / (int)sizeof(pcre_uchar);      size = 1 + 32 / (int)sizeof(pcre_uchar);
1553  #endif  #endif
1554      if (PRIV_DATA(cc))      if (PRIVATE_DATA(cc))
1555        localsize += get_class_iterator_size(cc + size);        private_data_length += get_class_iterator_size(cc + size);
1556      cc += size;      cc += size;
1557      break;      break;
1558    
# Line 1332  while (cc < ccend) Line 1563  while (cc < ccend)
1563      }      }
1564    }    }
1565  SLJIT_ASSERT(cc == ccend);  SLJIT_ASSERT(cc == ccend);
1566  return localsize;  return private_data_length;
1567  }  }
1568    
1569  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,
1570    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1571  {  {
1572  DEFINE_COMPILER;  DEFINE_COMPILER;
1573  int srcw[2];  int srcw[2];
# Line 1357  stacktop = STACK(stacktop - 1); Line 1588  stacktop = STACK(stacktop - 1);
1588    
1589  if (!save)  if (!save)
1590    {    {
1591    stackptr += sizeof(sljit_w);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1592    if (stackptr < stacktop)    if (stackptr < stacktop)
1593      {      {
1594      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1595      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1596      tmp1empty = FALSE;      tmp1empty = FALSE;
1597      }      }
1598    if (stackptr < stacktop)    if (stackptr < stacktop)
1599      {      {
1600      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1601      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1602      tmp2empty = FALSE;      tmp2empty = FALSE;
1603      }      }
1604    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1605    }    }
1606    
1607  while (status != end)  do
1608    {    {
1609    count = 0;    count = 0;
1610    switch(status)    switch(status)
1611      {      {
1612      case start:      case start:
1613      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1614      count = 1;      count = 1;
1615      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1616        if (needs_control_head)
1617          {
1618          SLJIT_ASSERT(common->control_head_ptr != 0);
1619          count = 2;
1620          srcw[1] = common->control_head_ptr;
1621          }
1622      status = loop;      status = loop;
1623      break;      break;
1624    
# Line 1405  while (status != end) Line 1642  while (status != end)
1642        case OP_SBRAPOS:        case OP_SBRAPOS:
1643        case OP_SCOND:        case OP_SCOND:
1644        count = 1;        count = 1;
1645        srcw[0] = PRIV_DATA(cc);        srcw[0] = PRIVATE_DATA(cc);
1646        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1647        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1648        break;        break;
1649    
1650        case OP_CBRA:        case OP_CBRA:
1651        case OP_SCBRA:        case OP_SCBRA:
1652        count = 1;        if (common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] == 0)
1653        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));          {
1654            count = 1;
1655            srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1656            }
1657        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1658        break;        break;
1659    
1660        case OP_CBRAPOS:        case OP_CBRAPOS:
1661        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1662        count = 2;        count = 2;
1663        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = PRIVATE_DATA(cc);
1664        srcw[1] = PRIV_DATA(cc);        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1665        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0 && srcw[1] != 0);
1666        cc += 1 + LINK_SIZE + IMM2_SIZE;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1667        break;        break;
1668    
# Line 1432  while (status != end) Line 1672  while (status != end)
1672        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1673          {          {
1674          count = 1;          count = 1;
1675          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1676          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1677          }          }
1678        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1679        break;        break;
1680    
1681        CASE_ITERATOR_LOCAL1        CASE_ITERATOR_PRIVATE_DATA_1
1682        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1683          {          {
1684          count = 1;          count = 1;
1685          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1686          }          }
1687        cc += 2;        cc += 2;
1688  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1450  while (status != end) Line 1690  while (status != end)
1690  #endif  #endif
1691        break;        break;
1692    
1693        CASE_ITERATOR_LOCAL2A        CASE_ITERATOR_PRIVATE_DATA_2A
1694        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1695          {          {
1696          count = 2;          count = 2;
1697          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1698          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1699          }          }
1700        cc += 2;        cc += 2;
1701  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1463  while (status != end) Line 1703  while (status != end)
1703  #endif  #endif
1704        break;        break;
1705    
1706        CASE_ITERATOR_LOCAL2B        CASE_ITERATOR_PRIVATE_DATA_2B
1707        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1708          {          {
1709          count = 2;          count = 2;
1710          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1711          srcw[1] = PRIV_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1712          }          }
1713        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1714  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1476  while (status != end) Line 1716  while (status != end)
1716  #endif  #endif
1717        break;        break;
1718    
1719        CASE_ITERATOR_TYPE_LOCAL1        CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1720        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1721          {          {
1722          count = 1;          count = 1;
1723          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1724          }          }
1725        cc += 1;        cc += 1;
1726        break;        break;
1727    
1728        CASE_ITERATOR_TYPE_LOCAL2A        CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1729        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1730          {          {
1731          count = 2;          count = 2;
1732          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1733          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_sw);
1734          }          }
1735        cc += 1;        cc += 1;
1736        break;        break;
1737    
1738        CASE_ITERATOR_TYPE_LOCAL2B        CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1739        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1740          {          {
1741          count = 2;          count = 2;
1742          srcw[0] = PRIV_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1743          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_sw);
1744          }          }
1745        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
1746        break;        break;
# Line 1513  while (status != end) Line 1753  while (status != end)
1753  #else  #else
1754        size = 1 + 32 / (int)sizeof(pcre_uchar);        size = 1 + 32 / (int)sizeof(pcre_uchar);
1755  #endif  #endif
1756        if (PRIV_DATA(cc))        if (PRIVATE_DATA(cc))
1757          switch(get_class_iterator_size(cc + size))          switch(get_class_iterator_size(cc + size))
1758            {            {
1759            case 1:            case 1:
1760            count = 1;            count = 1;
1761            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1762            break;            break;
1763    
1764            case 2:            case 2:
1765            count = 2;            count = 2;
1766            srcw[0] = PRIV_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1767            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_sw);
1768            break;            break;
1769    
1770            default:            default:
# Line 1556  while (status != end) Line 1796  while (status != end)
1796          if (!tmp1empty)          if (!tmp1empty)
1797            {            {
1798            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1799            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1800            }            }
1801          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1802          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1567  while (status != end) Line 1807  while (status != end)
1807          if (!tmp2empty)          if (!tmp2empty)
1808            {            {
1809            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1810            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1811            }            }
1812          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1813          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1584  while (status != end) Line 1824  while (status != end)
1824          if (!tmp1empty)          if (!tmp1empty)
1825            {            {
1826            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1827            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1828            }            }
1829          tmp1next = FALSE;          tmp1next = FALSE;
1830          }          }
# Line 1596  while (status != end) Line 1836  while (status != end)
1836          if (!tmp2empty)          if (!tmp2empty)
1837            {            {
1838            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1839            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1840            }            }
1841          tmp1next = TRUE;          tmp1next = TRUE;
1842          }          }
1843        }        }
1844      }      }
1845    }    }
1846    while (status != end);
1847    
1848  if (save)  if (save)
1849    {    {
# Line 1611  if (save) Line 1852  if (save)
1852      if (!tmp1empty)      if (!tmp1empty)
1853        {        {
1854        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1855        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1856        }        }
1857      if (!tmp2empty)      if (!tmp2empty)
1858        {        {
1859        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1860        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1861        }        }
1862      }      }
1863    else    else
# Line 1624  if (save) Line 1865  if (save)
1865      if (!tmp2empty)      if (!tmp2empty)
1866        {        {
1867        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1868        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1869        }        }
1870      if (!tmp1empty)      if (!tmp1empty)
1871        {        {
1872        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1873        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1874        }        }
1875      }      }
1876    }    }
1877  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1878  }  }
1879    
1880  #undef CASE_ITERATOR_LOCAL1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1881  #undef CASE_ITERATOR_LOCAL2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1882  #undef CASE_ITERATOR_LOCAL2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
1883  #undef CASE_ITERATOR_TYPE_LOCAL1  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_1
1884  #undef CASE_ITERATOR_TYPE_LOCAL2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1885  #undef CASE_ITERATOR_TYPE_LOCAL2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1886    
1887  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1888  {  {
1889  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1890  }  }
# Line 1654  while (list) Line 1895  while (list)
1895    {    {
1896    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1897    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1898    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1899    list = list->next;    list = list->next;
1900    }    }
1901  }  }
# Line 1670  if (list_item) Line 1911  if (list_item)
1911    }    }
1912  }  }
1913    
1914  static void add_stub(compiler_common *common, enum stub_types type, int data, struct sljit_jump *start)  static void add_stub(compiler_common *common, struct sljit_jump *start)
1915  {  {
1916  DEFINE_COMPILER;  DEFINE_COMPILER;
1917  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1918    
1919  if (list_item)  if (list_item)
1920    {    {
   list_item->type = type;  
   list_item->data = data;  
1921    list_item->start = start;    list_item->start = start;
1922    list_item->quit = LABEL();    list_item->quit = LABEL();
1923    list_item->next = common->stubs;    list_item->next = common->stubs;
# Line 1694  stub_list* list_item = common->stubs; Line 1933  stub_list* list_item = common->stubs;
1933  while (list_item)  while (list_item)
1934    {    {
1935    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
1936    switch(list_item->type)    add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
     {  
     case stack_alloc:  
     add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));  
     break;  
     }  
1937    JUMPTO(SLJIT_JUMP, list_item->quit);    JUMPTO(SLJIT_JUMP, list_item->quit);
1938    list_item = list_item->next;    list_item = list_item->next;
1939    }    }
# Line 1719  static SLJIT_INLINE void allocate_stack( Line 1953  static SLJIT_INLINE void allocate_stack(
1953  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
1954  DEFINE_COMPILER;  DEFINE_COMPILER;
1955    
1956  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));
1957  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
1958  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
1959  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1727  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 1961  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
1961  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
1962  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
1963  #endif  #endif
1964  add_stub(common, stack_alloc, 0, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));  add_stub(common, CMP(SLJIT_C_GREATER, STACK_TOP, 0, STACK_LIMIT, 0));
1965  }  }
1966    
1967  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
1968  {  {
1969  DEFINE_COMPILER;  DEFINE_COMPILER;
1970  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));
1971  }  }
1972    
1973  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1741  static SLJIT_INLINE void reset_ovector(c Line 1975  static SLJIT_INLINE void reset_ovector(c
1975  DEFINE_COMPILER;  DEFINE_COMPILER;
1976  struct sljit_label *loop;  struct sljit_label *loop;
1977  int i;  int i;
1978    
1979  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1980    SLJIT_ASSERT(length > 1);
1981  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1982  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1983    if (length < 8)
1984      {
1985      for (i = 1; i < length; i++)
1986        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
1987      }
1988    else
1989      {
1990      GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
1991      OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
1992      loop = LABEL();
1993      OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
1994      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
1995      JUMPTO(SLJIT_C_NOT_ZERO, loop);
1996      }
1997    }
1998    
1999    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2000    {
2001    DEFINE_COMPILER;
2002    struct sljit_label *loop;
2003    int i;
2004    
2005    SLJIT_ASSERT(length > 1);
2006    /* OVECTOR(1) contains the "string begin - 1" constant. */
2007    if (length > 2)
2008      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2009  if (length < 8)  if (length < 8)
2010    {    {
2011    for (i = 0; i < length; i++)    for (i = 2; i < length; i++)
2012      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2013    }    }
2014  else  else
2015    {    {
2016    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2017    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2018    loop = LABEL();    loop = LABEL();
2019    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2020    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2021    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
2022    }    }
2023    
2024    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2025    if (common->mark_ptr != 0)
2026      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2027    SLJIT_ASSERT(common->control_head_ptr != 0);
2028    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2029    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2030    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2031    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2032    }
2033    
2034    static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2035    {
2036    sljit_sw return_value = 0;
2037    const pcre_uchar *skip_arg = NULL;
2038    
2039    SLJIT_ASSERT(current != NULL);
2040    do
2041      {
2042      switch (current[-2])
2043        {
2044        case type_commit:
2045        /* Commit overwrites all. */
2046        return -1;
2047    
2048        case type_prune:
2049        break;
2050    
2051        case type_skip:
2052        /* Overwrites prune, but not other skips. */
2053        if (return_value == 0 && skip_arg == NULL)
2054          return_value = current[-3];
2055        break;
2056    
2057        case type_skip_arg:
2058        if (return_value == 0 && skip_arg == NULL)
2059          skip_arg = (pcre_uchar *)current[-3];
2060        break;
2061    
2062        case type_mark:
2063        if (return_value == 0 && skip_arg != NULL)
2064          if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2065            return_value = current[-4];
2066        break;
2067    
2068        default:
2069        SLJIT_ASSERT_STOP();
2070        break;
2071        }
2072      current = (sljit_sw*)current[-1];
2073      }
2074    while (current != NULL);
2075    return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2076  }  }
2077    
2078  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2079  {  {
2080  DEFINE_COMPILER;  DEFINE_COMPILER;
2081  struct sljit_label *loop;  struct sljit_label *loop;
2082  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
2083    
2084  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2085  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2086  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);
2087    
2088  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
2089  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2090    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
2091  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offset_count));
2092  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2093    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_SCRATCH_REG3, 0);
2094  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
2095  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
2096  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
2097  /* Unlikely, but possible */  /* Unlikely, but possible */
2098  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);
2099  loop = LABEL();  loop = LABEL();
2100  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_SCRATCH_REG1, 0);
2101  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_sw));
2102  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
2103  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2104  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2105  #endif  #endif
2106  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
2107  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);
2108  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2109  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2110    
2111  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2112  if (topbracket > 1)  if (topbracket > 1)
2113    {    {
2114    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG1, 0, OVECTOR_START + topbracket * 2 * sizeof(sljit_sw));
2115    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
2116    
2117    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
2118    loop = LABEL();    loop = LABEL();
2119    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)));
2120    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);
2121    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
2122    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
2123    }    }
2124  else  else
2125    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
# Line 1813  else Line 2128  else
2128  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *quit)
2129  {  {
2130  DEFINE_COMPILER;  DEFINE_COMPILER;
2131    struct sljit_jump *jump;
2132    
2133  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);  SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
2134  SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));  SLJIT_ASSERT(common->start_used_ptr != 0 && common->start_ptr != 0
2135      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2136    
2137  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2138  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2139  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, real_offset_count));
2140  CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, quit);  CMPTO(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 2, quit);
2141    
2142  /* Store match begin and end. */  /* Store match begin and end. */
2143  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
2144  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
2145  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);  
2146    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2147    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_ptr : (common->hit_start + (int)sizeof(sljit_sw)), SLJIT_SAVED_REG1, 0);
2148    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2149    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2150    #endif
2151    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2152    JUMPHERE(jump);
2153    
2154    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);
2155  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
2156  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2157  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, UCHAR_SHIFT);
2158  #endif  #endif
2159  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
2160    
2161  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_SAVED_REG1, 0);
2162  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2163  OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);  OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2164  #endif  #endif
2165  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);  OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 0, SLJIT_SCRATCH_REG3, 0);
2166    
2167  JUMPTO(SLJIT_JUMP, quit);  JUMPTO(SLJIT_JUMP, quit);
2168  }  }
# Line 1949  if (c <= 127 && bit == 0x20) Line 2275  if (c <= 127 && bit == 0x20)
2275    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2276    
2277  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2278  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2279    return 0;    return 0;
2280    
2281  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2282    
2283  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2284  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 1968  if (common->utf && c > 127) Line 2294  if (common->utf && c > 127)
2294  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2295  return (0 << 8) | bit;  return (0 << 8) | bit;
2296    
2297  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2298    
 #ifdef COMPILE_PCRE16  
2299  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2300  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2301    {    {
# Line 1981  if (common->utf && c > 65535) Line 2306  if (common->utf && c > 65535)
2306    }    }
2307  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2308  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2309    
2310  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2311  }  }
2312    
2313  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 2003  else if (common->mode == JIT_PARTIAL_SOF Line 2327  else if (common->mode == JIT_PARTIAL_SOF
2327    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);    jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
2328    
2329  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2330    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2331  else  else
2332    {    {
2333    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2016  if (jump != NULL) Line 2340  if (jump != NULL)
2340    JUMPHERE(jump);    JUMPHERE(jump);
2341  }  }
2342    
2343  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2344  {  {
2345  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2346  DEFINE_COMPILER;  DEFINE_COMPILER;
2347  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2348    
2349  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2350    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2351      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2352      return;
2353      }
2354    
2355  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2356  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2357    {    {
2358    nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2359    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2360    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2361    }    }
2362  else  else
2363    {    {
2364    return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);    add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2365    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2366      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2367    else    else
2368      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2369    }    }
2370  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2371  }  }
2372    
2373  static void detect_partial_match(compiler_common *common, jump_list **backtracks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
# Line 2063  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR Line 2386  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2386  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));  add_jump(compiler, backtracks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
2387  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2388    {    {
2389    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
2390    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2391    }    }
2392  else  else
# Line 2081  static void read_char(compiler_common *c Line 2404  static void read_char(compiler_common *c
2404  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2405  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2406  DEFINE_COMPILER;  DEFINE_COMPILER;
2407  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2408  struct sljit_jump *jump;  struct sljit_jump *jump;
2409  #endif  #endif
2410    
2411  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2412  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2413  if (common->utf)  if (common->utf)
2414    {    {
2415  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2416    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2417  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2418    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2419  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2420    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2421    JUMPHERE(jump);    JUMPHERE(jump);
2422    }    }
2423  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2424  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));
2425  }  }
2426    
# Line 2108  static void peek_char(compiler_common *c Line 2429  static void peek_char(compiler_common *c
2429  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2430  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2431  DEFINE_COMPILER;  DEFINE_COMPILER;
2432  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2433  struct sljit_jump *jump;  struct sljit_jump *jump;
2434  #endif  #endif
2435    
2436  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2437  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2438  if (common->utf)  if (common->utf)
2439    {    {
2440  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2441    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2442  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2443    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2444  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2445    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2446    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2447    JUMPHERE(jump);    JUMPHERE(jump);
2448    }    }
2449  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2450  }  }
2451    
2452  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2453  {  {
2454  /* 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. */
2455  DEFINE_COMPILER;  DEFINE_COMPILER;
2456  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2457  struct sljit_jump *jump;  struct sljit_jump *jump;
2458  #endif  #endif
2459    
# Line 2143  if (common->utf) Line 2462  if (common->utf)
2462    {    {
2463    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2464    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));
2465  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2466    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2467    it is needed in most cases. */    it is needed in most cases. */
2468    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2469    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2470    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2471    JUMPHERE(jump);    JUMPHERE(jump);
2472  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2473    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2474    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2475    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 2159  if (common->utf) Line 2477  if (common->utf)
2477    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2478    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2479    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);
2480    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2481    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2482    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2483  #endif  #elif defined COMPILE_PCRE32
2484  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2485      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2486      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2487      JUMPHERE(jump);
2488    #endif /* COMPILE_PCRE[8|16|32] */
2489    return;    return;
2490    }    }
2491  #endif  #endif /* SUPPORT_UTF */
2492  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2493  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));
2494  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2495  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2496  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2497  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2498  #endif  #endif
2499  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2500  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2501  JUMPHERE(jump);  JUMPHERE(jump);
2502  #endif  #endif
2503  }  }
# Line 2184  static void skip_char_back(compiler_comm Line 2506  static void skip_char_back(compiler_comm
2506  {  {
2507  /* 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. */
2508  DEFINE_COMPILER;  DEFINE_COMPILER;
2509  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2510    #if defined COMPILE_PCRE8
2511  struct sljit_label *label;  struct sljit_label *label;
2512    
2513  if (common->utf)  if (common->utf)
# Line 2196  if (common->utf) Line 2519  if (common->utf)
2519    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2520    return;    return;
2521    }    }
2522  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2523  if (common->utf)  if (common->utf)
2524    {    {
2525    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 2205  if (common->utf) Line 2527  if (common->utf)
2527    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2528    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2529    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);
2530    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2531    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2532    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2533    return;    return;
2534    }    }
2535  #endif  #endif /* COMPILE_PCRE[8|16] */
2536    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2537  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));
2538  }  }
2539    
# Line 2227  if (nltype == NLTYPE_ANY) Line 2550  if (nltype == NLTYPE_ANY)
2550  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2551    {    {
2552    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);
2553    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2554    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);
2555    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);
2556    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(jumpiftrue ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
2557    }    }
2558  else  else
# Line 2241  else Line 2564  else
2564    
2565  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2566    
2567  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2568  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2569  {  {
2570  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 2329  sljit_emit_fast_return(compiler, RETURN_ Line 2652  sljit_emit_fast_return(compiler, RETURN_
2652  JUMPHERE(jump);  JUMPHERE(jump);
2653    
2654  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2655  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);
2656  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2657  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2658  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2659  }  }
2660    
2661  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2662    
 #ifdef COMPILE_PCRE16  
2663  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2664  {  {
2665  /* 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 2362  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2684  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2684  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2685  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2686  }  }
 #endif /* COMPILE_PCRE16 */  
2687    
2688  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2689    
2690  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2691    
# Line 2384  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 2705  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
2705    
2706  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2707  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2708  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));
2709  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2710  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2711  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2712  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2713  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2714  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));
2715  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2716  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2717  }  }
# Line 2404  struct sljit_label *newlinelabel = NULL; Line 2725  struct sljit_label *newlinelabel = NULL;
2725  struct sljit_jump *start;  struct sljit_jump *start;
2726  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2727  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2728  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2729  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2730  #endif  #endif
2731  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 2459  if (newlinecheck) Line 2780  if (newlinecheck)
2780    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2781    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2782    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);
2783    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2784  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2785    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2786  #endif  #endif
2787    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2788    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2482  if (newlinecheck) Line 2803  if (newlinecheck)
2803    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);
2804    
2805  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));
2806  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2807    #if defined COMPILE_PCRE8
2808  if (common->utf)  if (common->utf)
2809    {    {
2810    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2811    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);
2812    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2813    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2814    }    }
2815  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2816  if (common->utf)  if (common->utf)
2817    {    {
2818    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2819    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2820    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);
2821    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2822    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2823    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2824    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2825    }    }
2826  #endif  #endif /* COMPILE_PCRE[8|16] */
2827    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2828  JUMPHERE(start);  JUMPHERE(start);
2829    
2830  if (newlinecheck)  if (newlinecheck)
# Line 2514  if (newlinecheck) Line 2836  if (newlinecheck)
2836  return mainloop;  return mainloop;
2837  }  }
2838    
2839  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2840    
2841    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2842  {  {
2843  DEFINE_COMPILER;  DEFINE_COMPILER;
2844  struct sljit_label *start;  struct sljit_label *start;
2845  struct sljit_jump *quit;  struct sljit_jump *quit;
2846  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
2847  pcre_int32 chars[4];  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
 pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  
2848  int location = 0;  int location = 0;
2849  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2850  BOOL must_end;  int must_stop;
   
 #ifdef COMPILE_PCRE8  
 union {  
     sljit_uh ascombined;  
     sljit_ub asuchars[2];  
 } pair;  
 #else  
 union {  
     sljit_ui ascombined;  
     sljit_uh asuchars[2];  
 } pair;  
 #endif  
2851    
2852    /* We do not support alternatives now. */
2853  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2854    return FALSE;    return FALSE;
2855    
2856  while (TRUE)  while (TRUE)
2857    {    {
2858    caseless = 0;    caseless = 0;
2859    must_end = TRUE;    must_stop = 1;
2860    switch(*cc)    switch(*cc)
2861      {      {
2862      case OP_CHAR:      case OP_CHAR:
2863      must_end = FALSE;      must_stop = 0;
2864      cc++;      cc++;
2865      break;      break;
2866    
2867      case OP_CHARI:      case OP_CHARI:
2868      caseless = 1;      caseless = 1;
2869      must_end = FALSE;      must_stop = 0;
2870      cc++;      cc++;
2871      break;      break;
2872    
# Line 2596  while (TRUE) Line 2908  while (TRUE)
2908      break;      break;
2909    
2910      default:      default:
2911      return FALSE;      must_stop = 2;
2912        break;
2913      }      }
2914    
2915      if (must_stop == 2)
2916          break;
2917    
2918    len = 1;    len = 1;
2919  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2920    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);    if (common->utf && HAS_EXTRALEN(cc[0])) len += GET_EXTRALEN(cc[0]);
# Line 2621  while (TRUE) Line 2937  while (TRUE)
2937    else    else
2938      caseless = 0;      caseless = 0;
2939    
2940    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
2941      {      {
2942      c = *cc;      c = *cc;
2943      bit = 0;      bit = 0;
# Line 2639  while (TRUE) Line 2955  while (TRUE)
2955      cc++;      cc++;
2956      }      }
2957    
2958    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
2959      break;      break;
   else if (must_end)  
     return FALSE;  
2960    }    }
2961    
2962    /* At least two characters are required. */
2963    if (location < 2 * 2)
2964        return FALSE;
2965    
2966  if (firstline)  if (firstline)
2967    {    {
2968    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
2969    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
2970    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2971    }    }
2972  else  else
2973    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
2974    
2975  start = LABEL();  start = LABEL();
2976  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  quit = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  
 #ifdef COMPILE_PCRE8  
 OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #else /* COMPILE_PCRE8 */  
 OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  
 #endif  
2977    
2978  #else /* SLJIT_UNALIGNED */  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
   
 #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  
 OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  
 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  
 #else /* SLJIT_BIG_ENDIAN */  
2979  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2980  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2981  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
2982      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
2983  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
2984  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
2985  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2986  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
2987  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
2988  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
2989    if (location > 2 * 2)
2990  #endif    {
2991      if (chars[5] != 0)
2992  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
2993    {    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[4], start);
   pair.asuchars[0] = chars[1];  
   pair.asuchars[1] = chars[3];  
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, pair.ascombined);  
2994    }    }
2995    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2996    
 pair.asuchars[0] = chars[0];  
 pair.asuchars[1] = chars[2];  
 found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, pair.ascombined);  
   
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));  
 JUMPTO(SLJIT_JUMP, start);  
 JUMPHERE(found);  
2997  JUMPHERE(quit);  JUMPHERE(quit);
2998    
2999  if (firstline)  if (firstline)
3000    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3001  else  else
3002    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_END, 0, STR_END, 0, SLJIT_IMM, IN_UCHARS((location >> 1) - 1));
3003  return TRUE;  return TRUE;
3004  }  }
3005    
3006    #undef MAX_N_CHARS
3007    
3008  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)
3009  {  {
3010  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2738  if (first_char == oc) Line 3038  if (first_char == oc)
3038  else  else
3039    {    {
3040    bit = first_char ^ oc;    bit = first_char ^ oc;
3041    if (ispowerof2(bit))    if (is_powerof2(bit))
3042      {      {
3043      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
3044      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 2746  else Line 3046  else
3046    else    else
3047      {      {
3048      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);
3049      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3050      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);
3051      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);
3052      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
3053      }      }
3054    }    }
# Line 2790  if (common->nltype == NLTYPE_FIXED && co Line 3090  if (common->nltype == NLTYPE_FIXED && co
3090    
3091    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
3092    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);
3093    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
3094  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3095    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
3096  #endif  #endif
3097    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3098    
# Line 2833  if (common->nltype == NLTYPE_ANY || comm Line 3133  if (common->nltype == NLTYPE_ANY || comm
3133    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3134    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3135    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);
3136    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3137  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3138    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3139  #endif  #endif
3140    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3141    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
# Line 2848  if (firstline) Line 3148  if (firstline)
3148    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3149  }  }
3150    
3151    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3152    
3153  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)
3154  {  {
3155  DEFINE_COMPILER;  DEFINE_COMPILER;
3156  struct sljit_label *start;  struct sljit_label *start;
3157  struct sljit_jump *quit;  struct sljit_jump *quit;
3158  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3159    jump_list *matches = NULL;
3160    pcre_uint8 inverted_start_bits[32];
3161    int i;
3162  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3163  struct sljit_jump *jump;  struct sljit_jump *jump;
3164  #endif  #endif
3165    
3166    for (i = 0; i < 32; ++i)
3167      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3168    
3169  if (firstline)  if (firstline)
3170    {    {
3171    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 2872  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P Line 3180  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
3180  if (common->utf)  if (common->utf)
3181    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3182  #endif  #endif
3183    
3184    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3185      {
3186  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3187  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3188  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3189  JUMPHERE(jump);    JUMPHERE(jump);
3190  #endif  #endif
3191  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3192  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3193  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3194  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3195  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);
3196  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
3197      }
3198    
3199  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3200  if (common->utf)  if (common->utf)
3201    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3202  #endif  #endif
3203  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));
3204  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
3205    #if defined COMPILE_PCRE8
3206  if (common->utf)  if (common->utf)
3207    {    {
3208    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
3209    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);
3210    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3211    }    }
3212  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
3213  if (common->utf)  if (common->utf)
3214    {    {
3215    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
3216    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3217    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);
3218    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3219    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3220    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3221    }    }
3222  #endif  #endif /* COMPILE_PCRE[8|16] */
3223    #endif /* SUPPORT_UTF */
3224  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3225  JUMPHERE(found);  if (found != NULL)
3226      JUMPHERE(found);
3227    if (matches != NULL)
3228      set_jumps(matches, LABEL());
3229  JUMPHERE(quit);  JUMPHERE(quit);
3230    
3231  if (firstline)  if (firstline)
# Line 2925  struct sljit_jump *alreadyfound; Line 3241  struct sljit_jump *alreadyfound;
3241  struct sljit_jump *found;  struct sljit_jump *found;
3242  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
3243  struct sljit_jump *notfound;  struct sljit_jump *notfound;
3244  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
3245    
3246  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
3247  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
# Line 2956  if (req_char == oc) Line 3272  if (req_char == oc)
3272  else  else
3273    {    {
3274    bit = req_char ^ oc;    bit = req_char ^ oc;
3275    if (ispowerof2(bit))    if (is_powerof2(bit))
3276      {      {
3277      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3278      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 2992  GET_LOCAL_BASE(TMP3, 0, 0); Line 3308  GET_LOCAL_BASE(TMP3, 0, 0);
3308  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3309  mainloop = LABEL();  mainloop = LABEL();
3310  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3311  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0);
3312    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3313    
3314  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3315  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));
3316  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));
3317  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));
3318  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3319    
3320  JUMPHERE(jump);  JUMPHERE(jump);
3321  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3322  /* End of dropping frames. */  /* End of dropping frames. */
3323  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3324    
3325  JUMPHERE(jump);  JUMPHERE(jump);
3326  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3327  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3328  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3329  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));
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
 if (common->mark_ptr != 0)  
   {  
   jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);  
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);  
   JUMPTO(SLJIT_JUMP, mainloop);  
   
   JUMPHERE(jump);  
   }  
   
 /* Unknown command. */  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
3330  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3331  }  }
3332    
# Line 3033  static void check_wordboundary(compiler_ Line 3334  static void check_wordboundary(compiler_
3334  {  {
3335  DEFINE_COMPILER;  DEFINE_COMPILER;
3336  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3337    jump_list *skipread_list = NULL;
3338  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3339  struct sljit_jump *jump;  struct sljit_jump *jump;
3340  #endif  #endif
# Line 3058  if (common->use_ucp) Line 3360  if (common->use_ucp)
3360    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3361    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3362    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);
3363    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3364    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);
3365    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);
3366    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3367    JUMPHERE(jump);    JUMPHERE(jump);
3368    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3369    }    }
# Line 3090  else Line 3392  else
3392  JUMPHERE(skipread);  JUMPHERE(skipread);
3393    
3394  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3395  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3396  peek_char(common);  peek_char(common);
3397    
3398  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3102  if (common->use_ucp) Line 3404  if (common->use_ucp)
3404    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3405    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3406    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);
3407    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3408    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);
3409    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);
3410    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3411    JUMPHERE(jump);    JUMPHERE(jump);
3412    }    }
3413  else  else
# Line 3131  else Line 3433  else
3433      JUMPHERE(jump);      JUMPHERE(jump);
3434  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3435    }    }
3436  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3437    
3438  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
3439  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 3186  switch(ranges[0]) Line 3488  switch(ranges[0])
3488        }        }
3489      return TRUE;      return TRUE;
3490      }      }
3491    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && ispowerof2(ranges[4] - ranges[2]))    if ((ranges[3] - ranges[2]) == (ranges[5] - ranges[4]) && is_powerof2(ranges[4] - ranges[2]))
3492      {      {
3493      if (readch)      if (readch)
3494        read_char(common);        read_char(common);
# Line 3285  sljit_emit_fast_enter(compiler, RETURN_A Line 3587  sljit_emit_fast_enter(compiler, RETURN_A
3587    
3588  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3589  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);
3590  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3591  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);
3592  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3593  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3594  if (common->utf)  if (common->utf)
3595    {    {
3596  #endif  #endif
3597    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3598    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3599    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);
3600  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3601    }    }
3602  #endif  #endif
3603  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3604  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);
3605  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3606  }  }
3607    
# Line 3311  DEFINE_COMPILER; Line 3613  DEFINE_COMPILER;
3613  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3614    
3615  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);
3616  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3617  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);
3618  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3619  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);
3620  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3621  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3622  if (common->utf)  if (common->utf)
3623    {    {
3624  #endif  #endif
3625    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3626    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);
3627    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3628    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);
3629    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3630    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3631    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);
3632    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3633    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);
3634    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3635    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);
3636    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3637    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);
3638  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3639    }    }
3640  #endif  #endif
3641  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3642  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);
3643    
3644  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3645  }  }
# Line 3351  sljit_emit_fast_enter(compiler, RETURN_A Line 3653  sljit_emit_fast_enter(compiler, RETURN_A
3653    
3654  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3655  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);
3656  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3657  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);
3658  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3659  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3660  if (common->utf)  if (common->utf)
3661    {    {
3662  #endif  #endif
3663    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);
3664    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3665    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);
3666  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3667    }    }
3668  #endif  #endif
3669  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3670  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);
3671    
3672  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3673  }  }
# Line 3451  sljit_emit_fast_return(compiler, RETURN_ Line 3753  sljit_emit_fast_return(compiler, RETURN_
3753    
3754  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3755    
3756  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)
3757  {  {
3758  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3759  int c1, c2;  pcre_uint32 c1, c2;
3760  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3761  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3762    const ucd_record *ur;
3763    const pcre_uint32 *pp;
3764    
3765  while (src1 < end1)  while (src1 < end1)
3766    {    {
# Line 3464  while (src1 < end1) Line 3768  while (src1 < end1)
3768      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3769    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3770    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3771    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3772      if (c1 != c2 && c1 != c2 + ur->other_case)
3773        {
3774        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3775        for (;;)
3776          {
3777          if (c1 < *pp) return NULL;
3778          if (c1 == *pp++) break;
3779          }
3780        }
3781    }    }
3782  return src2;  return src2;
3783  }  }
# Line 3486  if (caseless && char_has_othercase(commo Line 3799  if (caseless && char_has_othercase(commo
3799    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3800    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3801    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3802  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3803    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3804    othercasebit &= 0xff;    othercasebit &= 0xff;
3805  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3806  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3807      ever are characters outside the BMP whose othercase differs in only one
3808      bit from itself (there currently are none), this code will need to be
3809      revised for COMPILE_PCRE32. */
3810    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3811    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3812      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3813    else    else
3814      othercasebit &= 0xff;      othercasebit &= 0xff;
3815  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3816    }    }
3817    
3818  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3819    {    {
3820  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3821  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3822    if (context->length >= 4)    if (context->length >= 4)
3823      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
# Line 3511  if (context->sourcereg == -1) Line 3826  if (context->sourcereg == -1)
3826    else    else
3827  #endif  #endif
3828      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3829  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3830  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3831    if (context->length >= 4)    if (context->length >= 4)
3832      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3833    else    else
3834  #endif  #endif
3835      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3836  #endif  #elif defined COMPILE_PCRE32
3837  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3838    #endif /* COMPILE_PCRE[8|16|32] */
3839    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3840    }    }
3841    
# Line 3534  do Line 3849  do
3849  #endif  #endif
3850    
3851    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3852  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3853    
3854    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3855    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3549  do Line 3864  do
3864      }      }
3865    context->ucharptr++;    context->ucharptr++;
3866    
3867  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3868    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))
3869  #else  #else
3870    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
# Line 3557  do Line 3872  do
3872      {      {
3873      if (context->length >= 4)      if (context->length >= 4)
3874        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  
3875      else if (context->length >= 2)      else if (context->length >= 2)
3876        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3877    #if defined COMPILE_PCRE8
3878      else if (context->length >= 1)      else if (context->length >= 1)
3879        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);
3880  #else  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3881      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3882    
3883      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3599  do Line 3911  do
3911    
3912  #else  #else
3913    
3914    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
3915  #ifdef COMPILE_PCRE8    if (context->length >= 1)
3916    if (context->length > 0)      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
3917      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  
3918    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3919    
3920    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3656  static void compile_xclass_matchingpath( Line 3964  static void compile_xclass_matchingpath(
3964  DEFINE_COMPILER;  DEFINE_COMPILER;
3965  jump_list *found = NULL;  jump_list *found = NULL;
3966  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
3967  unsigned int c;  pcre_int32 c, charoffset;
3968  int compares;  const pcre_uint32 *other_cases;
3969  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3970  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
3971    int compares, invertcmp, numberofcmps;
3972  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3973  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
3974  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
3975  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
3976  unsigned int typeoffset;  pcre_int32 typeoffset;
3977  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
3978    
3979  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
3980     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3688  if ((*cc++ & XCL_MAP) != 0) Line 3995  if ((*cc++ & XCL_MAP) != 0)
3995      {      {
3996      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3997      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3998      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
3999      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4000      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);
4001      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
# Line 3765  while (*cc != XCL_END) Line 4072  while (*cc != XCL_END)
4072        needschar = TRUE;        needschar = TRUE;
4073        break;        break;
4074    
4075          case PT_CLIST:
4076          case PT_UCNC:
4077          needschar = TRUE;
4078          break;
4079    
4080        default:        default:
4081        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
4082        break;        break;
# Line 3801  if (needstype || needsscript) Line 4113  if (needstype || needsscript)
4113      {      {
4114      if (scriptreg == TMP1)      if (scriptreg == TMP1)
4115        {        {
4116        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));
4117        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
4118        }        }
4119      else      else
4120        {        {
4121        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
4122        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));
4123        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
4124        }        }
4125      }      }
# Line 3843  while (*cc != XCL_END) Line 4155  while (*cc != XCL_END)
4155      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4156        {        {
4157        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);
4158        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);
4159        numberofcmps++;        numberofcmps++;
4160        }        }
4161      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4162        {        {
4163        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);
4164        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);
4165        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4166        numberofcmps = 0;        numberofcmps = 0;
4167        }        }
# Line 3882  while (*cc != XCL_END) Line 4194  while (*cc != XCL_END)
4194      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4195        {        {
4196        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);
4197        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);
4198        numberofcmps++;        numberofcmps++;
4199        }        }
4200      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4201        {        {
4202        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);
4203        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);
4204        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4205        numberofcmps = 0;        numberofcmps = 0;
4206        }        }
# Line 3919  while (*cc != XCL_END) Line 4231  while (*cc != XCL_END)
4231    
4232        case PT_LAMP:        case PT_LAMP:
4233        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);
4234        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4235        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);
4236        COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4237        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);
4238        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);
4239        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4240        break;        break;
4241    
# Line 3950  while (*cc != XCL_END) Line 4262  while (*cc != XCL_END)
4262          }          }
4263        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4264        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);
4265        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4266        if (*cc == PT_SPACE)        if (*cc == PT_SPACE)
4267          JUMPHERE(jump);          JUMPHERE(jump);
4268    
4269        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4270        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);
4271        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);
4272        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4273        break;        break;
4274    
4275        case PT_WORD:        case PT_WORD:
4276        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);
4277        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4278        /* ... fall through */        /* Fall through. */
4279    
4280        case PT_ALNUM:        case PT_ALNUM:
4281        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
4282        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);
4283        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);
4284        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
4285        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);
4286        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);
4287          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4288          break;
4289    
4290          case PT_CLIST:
4291          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4292    
4293          /* At least three characters are required.
4294             Otherwise this case would be handled by the normal code path. */
4295          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4296          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4297    
4298          /* Optimizing character pairs, if their difference is power of 2. */
4299          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4300            {
4301            if (charoffset == 0)
4302              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4303            else
4304              {
4305              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4306              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4307              }
4308            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4309            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4310            other_cases += 2;
4311            }
4312          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4313            {
4314            if (charoffset == 0)
4315              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4316            else
4317              {
4318              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4319              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4320              }
4321            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4322            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4323    
4324            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4325            OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4326    
4327            other_cases += 3;
4328            }
4329          else
4330            {
4331            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4332            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4333            }
4334    
4335          while (*other_cases != NOTACHAR)
4336            {
4337            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4338            OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4339            }
4340          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4341          break;
4342    
4343          case PT_UCNC:
4344          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
4345          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4346          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
4347          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4348          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
4349          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4350    
4351          SET_CHAR_OFFSET(0xa0);
4352          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4353          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4354          SET_CHAR_OFFSET(0);
4355          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4356          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4357        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4358        break;        break;
4359        }        }
# Line 3999  int length; Line 4381  int length;
4381  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4382  compare_context context;  compare_context context;
4383  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4384    jump_list *end_list;
4385  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4386  struct sljit_label *label;  struct sljit_label *label;
4387  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4067  switch(type) Line 4450  switch(type)
4450    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4451      {      {
4452      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);
4453        end_list = NULL;
4454      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4455        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);        add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4456      else      else
4457        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4458    
4459      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4460      add_jump(compiler, backtracks, 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));
4461      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4462      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4463      }      }
4464    else    else
# Line 4089  switch(type) Line 4472  switch(type)
4472      {      {
4473      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4474      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));
4475  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4476    #if defined COMPILE_PCRE8
4477      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4478      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);
4479      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4480  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4481      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4482      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4483      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);
4484      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4485      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4486      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4487  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4488      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4489    #endif /* COMPILE_PCRE[8|16] */
4490      return cc;      return cc;
4491      }      }
4492  #endif  #endif
# Line 4134  switch(type) Line 4517  switch(type)
4517    read_char(common);    read_char(common);
4518    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);
4519    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4520      end_list = NULL;
4521    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4522      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      add_jump(compiler, &end_list, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
4523    else    else
4524      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4525    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4526    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
4527    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));
4528    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4529    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4530    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4531      set_jumps(end_list, LABEL());
4532    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4533    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4534    return cc;    return cc;
4535    
4536    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 4170  switch(type) Line 4554  switch(type)
4554    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4555    read_char(common);    read_char(common);
4556    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4557    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));
4558    add_jump(compiler, backtracks, CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, SLJIT_IMM, ucp_Mn - ucp_Mc));    /* Optimize register allocation: use a real register. */
4559      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4560      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4561    
4562    label = LABEL();    label = LABEL();
4563    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);
4564    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4565    read_char(common);    read_char(common);
4566    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4567    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));
4568    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);
4569    
4570      OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4571      OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
4572      OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4573      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4574      OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4575      JUMPTO(SLJIT_C_NOT_ZERO, label);
4576    
4577    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4578    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4579      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4580    
4581    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4582      {      {
4583      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);      jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
# Line 4206  switch(type) Line 4601  switch(type)
4601        {        {
4602        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4603        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
4604        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS);
4605        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
4606        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);        OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_NOT_EQUAL);
4607        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4608        check_partial(common, TRUE);        check_partial(common, TRUE);
4609        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
# Line 4388  switch(type) Line 4783  switch(type)
4783      }      }
4784    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4785    bit = c ^ oc;    bit = c ^ oc;
4786    if (ispowerof2(bit))    if (is_powerof2(bit))
4787      {      {
4788      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4789      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));      add_jump(compiler, backtracks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
4790      return cc + length;      return cc + length;
4791      }      }
4792    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
4793    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4794    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);
4795    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);
4796    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4797    return cc + length;    return cc + length;
4798    
# Line 4424  switch(type) Line 4819  switch(type)
4819        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4820        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));
4821        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4822        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0);
4823        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4824        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
4825        return cc + 1;        return cc + 1;
# Line 4449  switch(type) Line 4844  switch(type)
4844      {      {
4845      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4846      bit = c ^ oc;      bit = c ^ oc;
4847      if (ispowerof2(bit))      if (is_powerof2(bit))
4848        {        {
4849        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4850        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));        add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
# Line 4487  switch(type) Line 4882  switch(type)
4882  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4883    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4884    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4885    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4886    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4887    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);
4888    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
# Line 4497  switch(type) Line 4892  switch(type)
4892  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4893    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
4894    
4895  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
4896    case OP_XCLASS:    case OP_XCLASS:
4897    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
4898    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 4611  if (!common->jscript_compat) Line 5006  if (!common->jscript_compat)
5006      {      {
5007      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
5008      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
5009      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
5010      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
5011      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);
5012      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
5013      }      }
5014    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, backtracks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
# Line 4669  if (withchecks && !common->jscript_compa Line 5064  if (withchecks && !common->jscript_compa
5064  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5065  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5066    {    {
5067    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_SCRATCH_REG1 && STACK_TOP == SLJIT_SCRATCH_REG2 && TMP2 == SLJIT_SCRATCH_REG3);
5068    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));
5069    if (withchecks)    if (withchecks)
5070      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5071    
5072    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
5073    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5074    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
5075    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SCRATCH_REG2), SLJIT_OFFSETOF(jit_arguments, uchar_ptr), STR_PTR, 0);
5076    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
5077    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5078    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
# Line 4790  if (!minimize) Line 5185  if (!minimize)
5185      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5186      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5187      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
5188      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));      OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5189      zerolength = compile_ref_checks(common, ccbegin, NULL);      zerolength = compile_ref_checks(common, ccbegin, NULL);
5190      /* Restore if not zero length. */      /* Restore if not zero length. */
5191      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));      OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5192      }      }
5193    else    else
5194      {      {
# Line 4886  backtrack_common *backtrack; Line 5281  backtrack_common *backtrack;
5281  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5282  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5283  int start = GET(cc, 1);  int start = GET(cc, 1);
5284    pcre_uchar *start_cc;
5285    BOOL needs_control_head;
5286    
5287  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5288    
5289    /* Inlining simple patterns. */
5290    if (get_framesize(common, common->start + start, TRUE, &needs_control_head) == no_stack)
5291      {
5292      start_cc = common->start + start;
5293      compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
5294      BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
5295      return cc + 1 + LINK_SIZE;
5296      }
5297    
5298  while (entry != NULL)  while (entry != NULL)
5299    {    {
5300    if (entry->start == start)    if (entry->start == start)
# Line 4936  add_jump(compiler, &backtrack->topbacktr Line 5343  add_jump(compiler, &backtrack->topbacktr
5343  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5344  }  }
5345    
5346    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5347    {
5348    const pcre_uchar *begin = arguments->begin;
5349    int *offset_vector = arguments->offsets;
5350    int offset_count = arguments->offset_count;
5351    int i;
5352    
5353    if (PUBL(callout) == NULL)
5354      return 0;
5355    
5356    callout_block->version = 2;
5357    callout_block->callout_data = arguments->callout_data;
5358    
5359    /* Offsets in subject. */
5360    callout_block->subject_length = arguments->end - arguments->begin;
5361    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5362    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5363    #if defined COMPILE_PCRE8
5364    callout_block->subject = (PCRE_SPTR)begin;
5365    #elif defined COMPILE_PCRE16
5366    callout_block->subject = (PCRE_SPTR16)begin;
5367    #elif defined COMPILE_PCRE32
5368    callout_block->subject = (PCRE_SPTR32)begin;
5369    #endif
5370    
5371    /* Convert and copy the JIT offset vector to the offset_vector array. */
5372    callout_block->capture_top = 0;
5373    callout_block->offset_vector = offset_vector;
5374    for (i = 2; i < offset_count; i += 2)
5375      {
5376      offset_vector[i] = jit_ovector[i] - begin;
5377      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5378      if (jit_ovector[i] >= begin)
5379        callout_block->capture_top = i;
5380      }
5381    
5382    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5383    if (offset_count > 0)
5384      offset_vector[0] = -1;
5385    if (offset_count > 1)
5386      offset_vector[1] = -1;
5387    return (*PUBL(callout))(callout_block);
5388    }
5389    
5390    /* Aligning to 8 byte. */
5391    #define CALLOUT_ARG_SIZE \
5392        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5393    
5394    #define CALLOUT_ARG_OFFSET(arg) \
5395        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5396    
5397    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5398    {
5399    DEFINE_COMPILER;
5400    backtrack_common *backtrack;
5401    
5402    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5403    
5404    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5405    
5406    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5407    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5408    SLJIT_ASSERT(common->capture_last_ptr != 0);
5409    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5410    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5411    
5412    /* These pointer sized fields temporarly stores internal variables. */
5413    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5414    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5415    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5416    
5417    if (common->mark_ptr != 0)
5418      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5419    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5420    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5421    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5422    
5423    /* Needed to save important temporary registers. */
5424    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5425    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5426    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5427    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5428    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5429    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5430    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5431    
5432    /* Check return value. */
5433    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5434    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5435    if (common->forced_quit_label == NULL)
5436      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5437    else
5438      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5439    return cc + 2 + 2 * LINK_SIZE;
5440    }
5441    
5442    #undef CALLOUT_ARG_SIZE
5443    #undef CALLOUT_ARG_OFFSET
5444    
5445  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)  static pcre_uchar *compile_assert_matchingpath(compiler_common *common, pcre_uchar *cc, assert_backtrack *backtrack, BOOL conditional)
5446  {  {
5447  DEFINE_COMPILER;  DEFINE_COMPILER;
5448  int framesize;  int framesize;
5449  int localptr;  int extrasize;
5450    BOOL needs_control_head;
5451    int private_data_ptr;
5452  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5453  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
5454  pcre_uchar opcode;  pcre_uchar opcode;
# Line 4949  jump_list *tmp = NULL; Line 5457  jump_list *tmp = NULL;
5457  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5458  jump_list **found;  jump_list **found;
5459  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5460  struct sljit_label *save_quitlabel = common->quitlabel;  struct sljit_label *save_quit_label = common->quit_label;
5461  struct sljit_label *save_acceptlabel = common->acceptlabel;  struct sljit_label *save_accept_label = common->accept_label;
5462  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5463  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5464    BOOL save_local_exit = common->local_exit;
5465  struct sljit_jump *jump;  struct sljit_jump *jump;
5466  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5467    
# Line 4962  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5471  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5471    bra = *cc;    bra = *cc;
5472    cc++;    cc++;
5473    }    }
5474  localptr = PRIV_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5475  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5476  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE, &needs_control_head);
5477  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5478  backtrack->localptr = localptr;  backtrack->private_data_ptr = private_data_ptr;
5479  opcode = *cc;  opcode = *cc;
5480  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);  SLJIT_ASSERT(opcode >= OP_ASSERT && opcode <= OP_ASSERTBACK_NOT);
5481  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;  found = (opcode == OP_ASSERT || opcode == OP_ASSERTBACK) ? &tmp : target;
# Line 4983  if (bra == OP_BRAMINZERO) Line 5492  if (bra == OP_BRAMINZERO)
5492    
5493  if (framesize < 0)  if (framesize < 0)
5494    {    {
5495    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5496    allocate_stack(common, 1);    if (framesize == no_frame)
5497        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5498      allocate_stack(common, extrasize);
5499      if (needs_control_head)
5500        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5501    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5502      if (needs_control_head)
5503        {
5504        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5505        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5506        }
5507    }    }
5508  else  else
5509    {    {
5510    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5511    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    allocate_stack(common, framesize + extrasize);
5512    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5513    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5514      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5515      if (needs_control_head)
5516        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5517    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5518    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5519    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5520        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5521        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5522        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5523        }
5524      else
5525        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5526      init_frame(common, ccbegin, framesize + extrasize - 1, extrasize, FALSE);
5527    }    }
5528    
5529  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5530  common->quitlabel = NULL;  common->local_exit = TRUE;
5531    common->quit_label = NULL;
5532  common->quit = NULL;  common->quit = NULL;
5533  while (1)  while (1)
5534    {    {
5535    common->acceptlabel = NULL;    common->accept_label = NULL;
5536    common->accept = NULL;    common->accept = NULL;
5537    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5538    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5015  while (1) Line 5544  while (1)
5544    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5545    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5546      {      {
5547      common->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5548      common->acceptlabel = save_acceptlabel;      common->quit_label = save_quit_label;
5549        common->accept_label = save_accept_label;
5550      common->quit = save_quit;      common->quit = save_quit;
5551      common->accept = save_accept;      common->accept = save_accept;
5552      return NULL;      return NULL;
5553      }      }
5554    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5555    if (common->accept != NULL)    if (common->accept != NULL)
5556      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5557    
5558    /* Reset stack. */    /* Reset stack. */
5559    if (framesize < 0)    if (framesize < 0)
5560      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      {
5561    else {      if (framesize == no_frame)
5562          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5563        else
5564          free_stack(common, extrasize);
5565        if (needs_control_head)
5566          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5567        }
5568      else
5569        {
5570      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5571        {        {
5572        /* We don't need to keep the STR_PTR, only the previous localptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5573        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_sw));
5574          if (needs_control_head)
5575            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5576        }