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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 1012 by zherczeg, Sat Aug 25 15:34:13 2012 UTC revision 1282 by zherczeg, Fri Mar 15 08:01:41 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    /* Defines for debugging purposes. */
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.  /* Allocate memory for the regex stack on the real machine stack.
78  Fast, but limited size. */  Fast, but limited size. */
79  #define MACHINE_STACK_SIZE 32768  #define MACHINE_STACK_SIZE 32768
# Line 157  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 170  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 178  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 bytecode_flag_types {
200      flag_optimized_cbracket = 1,
201      flag_then_start = 2,
202    };
203    
204    enum frame_types {
205      no_frame = -1,
206      no_stack = -2
207    };
208    
209    enum control_types {
210      type_commit = 0,
211      type_prune = 1,
212      type_skip = 2,
213      type_skip_arg = 3,
214      type_mark = 4,
215      type_then_trap = 5
216    };
217    
218  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);  typedef int (SLJIT_CALL *jit_function)(jit_arguments *args);
219    
220  /* The following structure is the key data type for the recursive  /* The following structure is the key data type for the recursive
# Line 208  typedef struct backtrack_common { Line 235  typedef struct backtrack_common {
235  typedef struct assert_backtrack {  typedef struct assert_backtrack {
236    backtrack_common common;    backtrack_common common;
237    jump_list *condfailed;    jump_list *condfailed;
238    /* Less than 0 (-1) if a frame is not needed. */    /* Less than 0 if a frame is not needed. */
239    int framesize;    int framesize;
240    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
241    int private_data_ptr;    int private_data_ptr;
# Line 229  typedef struct bracket_backtrack { Line 256  typedef struct bracket_backtrack {
256      /* Both for OP_COND, OP_SCOND. */      /* Both for OP_COND, OP_SCOND. */
257      jump_list *condfailed;      jump_list *condfailed;
258      assert_backtrack *assert;      assert_backtrack *assert;
259      /* For OP_ONCE. -1 if not needed. */      /* For OP_ONCE. Less than 0 if not needed. */
260      int framesize;      int framesize;
261    } u;    } u;
262    /* Points to our private memory word on the stack. */    /* Points to our private memory word on the stack. */
# Line 264  typedef struct recurse_entry { Line 291  typedef struct recurse_entry {
291    /* Collects the calls until the function is not created. */    /* Collects the calls until the function is not created. */
292    jump_list *calls;    jump_list *calls;
293    /* Points to the starting opcode. */    /* Points to the starting opcode. */
294    int start;    sljit_sw start;
295  } recurse_entry;  } recurse_entry;
296    
297  typedef struct recurse_backtrack {  typedef struct recurse_backtrack {
298    backtrack_common common;    backtrack_common common;
299      BOOL inlined_pattern;
300  } recurse_backtrack;  } recurse_backtrack;
301    
302    #define OP_THEN_TRAP OP_TABLE_LENGTH
303    
304    typedef struct then_trap_backtrack {
305      backtrack_common common;
306      /* If then_trap is not NULL, this structure contains the real
307      then_trap for the backtracking path. */
308      struct then_trap_backtrack *then_trap;
309      /* Points to the starting opcode. */
310      sljit_sw start;
311      /* Exit point for the then opcodes of this alternative. */
312      jump_list *quit;
313      /* Frame size of the current alternative. */
314      int framesize;
315    } then_trap_backtrack;
316    
317  #define MAX_RANGE_SIZE 6  #define MAX_RANGE_SIZE 6
318    
319  typedef struct compiler_common {  typedef struct compiler_common {
320      /* The sljit ceneric compiler. */
321    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
322      /* First byte code. */
323    pcre_uchar *start;    pcre_uchar *start;
   
324    /* Maps private data offset to each opcode. */    /* Maps private data offset to each opcode. */
325    int *private_data_ptrs;    int *private_data_ptrs;
326    /* Tells whether the capturing bracket is optimized. */    /* Tells whether the capturing bracket is optimized. */
327    pcre_uint8 *optimized_cbracket;    pcre_uint8 *optimized_cbracket;
328      /* Tells whether the starting offset is a target of then. */
329      pcre_uint8 *then_offsets;
330      /* Current position where a THEN must jump. */
331      then_trap_backtrack *then_trap;
332    /* Starting offset of private data for capturing brackets. */    /* Starting offset of private data for capturing brackets. */
333    int cbraptr;    int cbra_ptr;
334    /* OVector starting point. Must be divisible by 2. */    /* Output vector starting point. Must be divisible by 2. */
335    int ovector_start;    int ovector_start;
336    /* Last known position of the requested byte. */    /* Last known position of the requested byte. */
337    int req_char_ptr;    int req_char_ptr;
338    /* Head of the last recursion. */    /* Head of the last recursion. */
339    int recursive_head;    int recursive_head_ptr;
340    /* First inspected character for partial matching. */    /* First inspected character for partial matching. */
341    int start_used_ptr;    int start_used_ptr;
342    /* Starting pointer for partial soft matches. */    /* Starting pointer for partial soft matches. */
# Line 297  typedef struct compiler_common { Line 345  typedef struct compiler_common {
345    int first_line_end;    int first_line_end;
346    /* Points to the marked string. */    /* Points to the marked string. */
347    int mark_ptr;    int mark_ptr;
348      /* Recursive control verb management chain. */
349      int control_head_ptr;
350      /* Points to the last matched capture block index. */
351      int capture_last_ptr;
352      /* Points to the starting position of the current match. */
353      int start_ptr;
354    
355    /* Flipped and lower case tables. */    /* Flipped and lower case tables. */
356    const pcre_uint8 *fcc;    const pcre_uint8 *fcc;
357    sljit_w lcc;    sljit_sw lcc;
358    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */    /* Mode can be PCRE_STUDY_JIT_COMPILE and others. */
359    int mode;    int mode;
360      /* \K is found in the pattern. */
361      BOOL has_set_som;
362      /* (*SKIP:arg) is found in the pattern. */
363      BOOL has_skip_arg;
364      /* (*THEN) is found in the pattern. */
365      BOOL has_then;
366      /* Needs to know the start position anytime. */
367      BOOL needs_start_ptr;
368      /* Currently in recurse or assert. */
369      BOOL local_exit;
370    /* Newline control. */    /* Newline control. */
371    int nltype;    int nltype;
372    int newline;    int newline;
373    int bsr_nltype;    int bsr_nltype;
374    /* Dollar endonly. */    /* Dollar endonly. */
375    int endonly;    int endonly;
   BOOL has_set_som;  
376    /* Tables. */    /* Tables. */
377    sljit_w ctypes;    sljit_sw ctypes;
378    int digits[2 + MAX_RANGE_SIZE];    int digits[2 + MAX_RANGE_SIZE];
379    /* Named capturing brackets. */    /* Named capturing brackets. */
380    sljit_uw name_table;    sljit_uw name_table;
381    sljit_w name_count;    sljit_sw name_count;
382    sljit_w name_entry_size;    sljit_sw name_entry_size;
383    
384    /* Labels and jump lists. */    /* Labels and jump lists. */
385    struct sljit_label *partialmatchlabel;    struct sljit_label *partialmatchlabel;
386    struct sljit_label *quitlabel;    struct sljit_label *quit_label;
387    struct sljit_label *acceptlabel;    struct sljit_label *forced_quit_label;
388      struct sljit_label *accept_label;
389    stub_list *stubs;    stub_list *stubs;
390    recurse_entry *entries;    recurse_entry *entries;
391    recurse_entry *currententry;    recurse_entry *currententry;
392    jump_list *partialmatch;    jump_list *partialmatch;
393    jump_list *quit;    jump_list *quit;
394      jump_list *forced_quit;
395    jump_list *accept;    jump_list *accept;
396    jump_list *calllimit;    jump_list *calllimit;
397    jump_list *stackalloc;    jump_list *stackalloc;
# Line 337  typedef struct compiler_common { Line 402  typedef struct compiler_common {
402    jump_list *vspace;    jump_list *vspace;
403    jump_list *casefulcmp;    jump_list *casefulcmp;
404    jump_list *caselesscmp;    jump_list *caselesscmp;
405      jump_list *reset_match;
406    BOOL jscript_compat;    BOOL jscript_compat;
407  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
408    BOOL utf;    BOOL utf;
409  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
410    BOOL use_ucp;    BOOL use_ucp;
411  #endif  #endif
412    #ifndef COMPILE_PCRE32
413    jump_list *utfreadchar;    jump_list *utfreadchar;
414    #endif
415  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
416    jump_list *utfreadtype8;    jump_list *utfreadtype8;
417  #endif  #endif
# Line 361  typedef struct compare_context { Line 429  typedef struct compare_context {
429  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
430    int ucharptr;    int ucharptr;
431    union {    union {
432      sljit_i asint;      sljit_si asint;
433      sljit_uh asushort;      sljit_uh asushort;
434  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
435      sljit_ub asbyte;      sljit_ub asbyte;
436      sljit_ub asuchars[4];      sljit_ub asuchars[4];
437  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
438      sljit_uh asuchars[2];      sljit_uh asuchars[2];
439  #endif  #elif defined COMPILE_PCRE32
440        sljit_ui asuchars[1];
441  #endif  #endif
442    } c;    } c;
443    union {    union {
444      sljit_i asint;      sljit_si asint;
445      sljit_uh asushort;      sljit_uh asushort;
446  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
447      sljit_ub asbyte;      sljit_ub asbyte;
448      sljit_ub asuchars[4];      sljit_ub asuchars[4];
449  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
450      sljit_uh asuchars[2];      sljit_uh asuchars[2];
451  #endif  #elif defined COMPILE_PCRE32
452        sljit_ui asuchars[1];
453  #endif  #endif
454    } oc;    } oc;
455  #endif  #endif
456  } compare_context;  } compare_context;
457    
 enum {  
   frame_end = 0,  
   frame_setstrbegin = -1,  
   frame_setmark = -2  
 };  
   
458  /* Undefine sljit macros. */  /* Undefine sljit macros. */
459  #undef CMP  #undef CMP
460    
461  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
462  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_sw))
463    
464  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_SCRATCH_REG1
465  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_SCRATCH_REG3
466  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
467  #define STR_PTR       SLJIT_SAVED_REG1  #define STR_PTR       SLJIT_SAVED_REG1
468  #define STR_END       SLJIT_SAVED_REG2  #define STR_END       SLJIT_SAVED_REG2
469  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_SCRATCH_REG2
470  #define STACK_LIMIT   SLJIT_SAVED_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
471  #define ARGUMENTS     SLJIT_SAVED_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
472  #define CALL_COUNT    SLJIT_SAVED_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
# Line 412  enum { Line 474  enum {
474    
475  /* Local space layout. */  /* Local space layout. */
476  /* These two locals can be used by the current opcode. */  /* These two locals can be used by the current opcode. */
477  #define LOCALS0          (0 * sizeof(sljit_w))  #define LOCALS0          (0 * sizeof(sljit_sw))
478  #define LOCALS1          (1 * sizeof(sljit_w))  #define LOCALS1          (1 * sizeof(sljit_sw))
479  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
480  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_sw))
481  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_sw))
482  /* Max limit of recursions. */  /* Max limit of recursions. */
483  #define CALL_LIMIT       (4 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_sw))
484  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
485  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
486  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
487  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. */
488  #define OVECTOR_START    (common->ovector_start)  #define OVECTOR_START    (common->ovector_start)
489  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_sw))
490  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbra_ptr + (i) * sizeof(sljit_sw))
491  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])  #define PRIVATE_DATA(cc) (common->private_data_ptrs[(cc) - common->start])
492    
493  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
494  #define MOV_UCHAR  SLJIT_MOV_UB  #define MOV_UCHAR  SLJIT_MOV_UB
495  #define MOVU_UCHAR SLJIT_MOVU_UB  #define MOVU_UCHAR SLJIT_MOVU_UB
496  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
497  #define MOV_UCHAR  SLJIT_MOV_UH  #define MOV_UCHAR  SLJIT_MOV_UH
498  #define MOVU_UCHAR SLJIT_MOVU_UH  #define MOVU_UCHAR SLJIT_MOVU_UH
499    #elif defined COMPILE_PCRE32
500    #define MOV_UCHAR  SLJIT_MOV_UI
501    #define MOVU_UCHAR SLJIT_MOVU_UI
502  #else  #else
503  #error Unsupported compiling mode  #error Unsupported compiling mode
504  #endif  #endif
 #endif  
505    
506  /* Shortcuts. */  /* Shortcuts. */
507  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 455  the start pointers when the end of the c Line 518  the start pointers when the end of the c
518    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))    sljit_set_label(sljit_emit_jump(compiler, (type)), (label))
519  #define JUMPHERE(jump) \  #define JUMPHERE(jump) \
520    sljit_set_label((jump), sljit_emit_label(compiler))    sljit_set_label((jump), sljit_emit_label(compiler))
521    #define SET_LABEL(jump, label) \
522      sljit_set_label((jump), (label))
523  #define CMP(type, src1, src1w, src2, src2w) \  #define CMP(type, src1, src1w, src2, src2w) \
524    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))    sljit_emit_cmp(compiler, (type), (src1), (src1w), (src2), (src2w))
525  #define CMPTO(type, src1, src1w, src2, src2w, label) \  #define CMPTO(type, src1, src1w, src2, src2w, label) \
526    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))
527  #define COND_VALUE(op, dst, dstw, type) \  #define OP_FLAGS(op, dst, dstw, src, srcw, type) \
528    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_op_flags(compiler, (op), (dst), (dstw), (src), (srcw), (type))
529  #define GET_LOCAL_BASE(dst, dstw, offset) \  #define GET_LOCAL_BASE(dst, dstw, offset) \
530    sljit_get_local_base(compiler, (dst), (dstw), (offset))    sljit_get_local_base(compiler, (dst), (dstw), (offset))
531    
# Line 479  return cc; Line 544  return cc;
544   set_private_data_ptrs   set_private_data_ptrs
545   get_framesize   get_framesize
546   init_frame   init_frame
547   get_private_data_length_for_copy   get_private_data_copy_length
548   copy_private_data   copy_private_data
549   compile_matchingpath   compile_matchingpath
550   compile_backtrackingpath   compile_backtrackingpath
# Line 503  switch(*cc) Line 568  switch(*cc)
568    case OP_WORDCHAR:    case OP_WORDCHAR:
569    case OP_ANY:    case OP_ANY:
570    case OP_ALLANY:    case OP_ALLANY:
571      case OP_NOTPROP:
572      case OP_PROP:
573    case OP_ANYNL:    case OP_ANYNL:
574    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
575    case OP_HSPACE:    case OP_HSPACE:
# Line 515  switch(*cc) Line 582  switch(*cc)
582    case OP_CIRCM:    case OP_CIRCM:
583    case OP_DOLL:    case OP_DOLL:
584    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:  
585    case OP_CRSTAR:    case OP_CRSTAR:
586    case OP_CRMINSTAR:    case OP_CRMINSTAR:
587    case OP_CRPLUS:    case OP_CRPLUS:
588    case OP_CRMINPLUS:    case OP_CRMINPLUS:
589    case OP_CRQUERY:    case OP_CRQUERY:
590    case OP_CRMINQUERY:    case OP_CRMINQUERY:
591      case OP_CRRANGE:
592      case OP_CRMINRANGE:
593      case OP_CLASS:
594      case OP_NCLASS:
595      case OP_REF:
596      case OP_REFI:
597      case OP_RECURSE:
598      case OP_CALLOUT:
599      case OP_ALT:
600      case OP_KET:
601      case OP_KETRMAX:
602      case OP_KETRMIN:
603      case OP_KETRPOS:
604      case OP_REVERSE:
605      case OP_ASSERT:
606      case OP_ASSERT_NOT:
607      case OP_ASSERTBACK:
608      case OP_ASSERTBACK_NOT:
609      case OP_ONCE:
610      case OP_ONCE_NC:
611      case OP_BRA:
612      case OP_BRAPOS:
613      case OP_CBRA:
614      case OP_CBRAPOS:
615      case OP_COND:
616      case OP_SBRA:
617      case OP_SBRAPOS:
618      case OP_SCBRA:
619      case OP_SCBRAPOS:
620      case OP_SCOND:
621      case OP_CREF:
622      case OP_NCREF:
623      case OP_RREF:
624      case OP_NRREF:
625    case OP_DEF:    case OP_DEF:
626    case OP_BRAZERO:    case OP_BRAZERO:
627    case OP_BRAMINZERO:    case OP_BRAMINZERO:
628    case OP_BRAPOSZERO:    case OP_BRAPOSZERO:
629      case OP_PRUNE:
630      case OP_SKIP:
631      case OP_THEN:
632    case OP_COMMIT:    case OP_COMMIT:
633    case OP_FAIL:    case OP_FAIL:
634    case OP_ACCEPT:    case OP_ACCEPT:
635    case OP_ASSERT_ACCEPT:    case OP_ASSERT_ACCEPT:
636      case OP_CLOSE:
637    case OP_SKIPZERO:    case OP_SKIPZERO:
638    return cc + 1;    return cc + PRIV(OP_lengths)[*cc];
   
   case OP_ANYBYTE:  
 #ifdef SUPPORT_UTF  
   if (common->utf) return NULL;  
 #endif  
   return cc + 1;  
639    
640    case OP_CHAR:    case OP_CHAR:
641    case OP_CHARI:    case OP_CHARI:
# Line 557  switch(*cc) Line 647  switch(*cc)
647    case OP_MINPLUS:    case OP_MINPLUS:
648    case OP_QUERY:    case OP_QUERY:
649    case OP_MINQUERY:    case OP_MINQUERY:
650      case OP_UPTO:
651      case OP_MINUPTO:
652      case OP_EXACT:
653    case OP_POSSTAR:    case OP_POSSTAR:
654    case OP_POSPLUS:    case OP_POSPLUS:
655    case OP_POSQUERY:    case OP_POSQUERY:
656      case OP_POSUPTO:
657    case OP_STARI:    case OP_STARI:
658    case OP_MINSTARI:    case OP_MINSTARI:
659    case OP_PLUSI:    case OP_PLUSI:
660    case OP_MINPLUSI:    case OP_MINPLUSI:
661    case OP_QUERYI:    case OP_QUERYI:
662    case OP_MINQUERYI:    case OP_MINQUERYI:
663      case OP_UPTOI:
664      case OP_MINUPTOI:
665      case OP_EXACTI:
666    case OP_POSSTARI:    case OP_POSSTARI:
667    case OP_POSPLUSI:    case OP_POSPLUSI:
668    case OP_POSQUERYI:    case OP_POSQUERYI:
669      case OP_POSUPTOI:
670    case OP_NOTSTAR:    case OP_NOTSTAR:
671    case OP_NOTMINSTAR:    case OP_NOTMINSTAR:
672    case OP_NOTPLUS:    case OP_NOTPLUS:
673    case OP_NOTMINPLUS:    case OP_NOTMINPLUS:
674    case OP_NOTQUERY:    case OP_NOTQUERY:
675    case OP_NOTMINQUERY:    case OP_NOTMINQUERY:
676      case OP_NOTUPTO:
677      case OP_NOTMINUPTO:
678      case OP_NOTEXACT:
679    case OP_NOTPOSSTAR:    case OP_NOTPOSSTAR:
680    case OP_NOTPOSPLUS:    case OP_NOTPOSPLUS:
681    case OP_NOTPOSQUERY:    case OP_NOTPOSQUERY:
682      case OP_NOTPOSUPTO:
683    case OP_NOTSTARI:    case OP_NOTSTARI:
684    case OP_NOTMINSTARI:    case OP_NOTMINSTARI:
685    case OP_NOTPLUSI:    case OP_NOTPLUSI:
686    case OP_NOTMINPLUSI:    case OP_NOTMINPLUSI:
687    case OP_NOTQUERYI:    case OP_NOTQUERYI:
688    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:  
689    case OP_NOTUPTOI:    case OP_NOTUPTOI:
690    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
691    case OP_NOTEXACTI:    case OP_NOTEXACTI:
692      case OP_NOTPOSSTARI:
693      case OP_NOTPOSPLUSI:
694      case OP_NOTPOSQUERYI:
695    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
696    cc += 2 + IMM2_SIZE;    cc += PRIV(OP_lengths)[*cc];
697  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
698    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
699  #endif  #endif
700    return cc;    return cc;
701    
702    case OP_NOTPROP:    /* Special cases. */
703    case OP_PROP:    case OP_TYPESTAR:
704    return cc + 1 + 2;    case OP_TYPEMINSTAR:
705      case OP_TYPEPLUS:
706      case OP_TYPEMINPLUS:
707      case OP_TYPEQUERY:
708      case OP_TYPEMINQUERY:
709    case OP_TYPEUPTO:    case OP_TYPEUPTO:
710    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
711    case OP_TYPEEXACT:    case OP_TYPEEXACT:
712      case OP_TYPEPOSSTAR:
713      case OP_TYPEPOSPLUS:
714      case OP_TYPEPOSQUERY:
715    case OP_TYPEPOSUPTO:    case OP_TYPEPOSUPTO:
716    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;  
717    
718    case OP_CRRANGE:    case OP_ANYBYTE:
719    case OP_CRMINRANGE:  #ifdef SUPPORT_UTF
720    return cc + 1 + 2 * IMM2_SIZE;    if (common->utf) return NULL;
721    #endif
722    case OP_CLASS:    return cc + 1;
   case OP_NCLASS:  
   return cc + 1 + 32 / sizeof(pcre_uchar);  
723    
724  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
725    case OP_XCLASS:    case OP_XCLASS:
726    return cc + GET(cc, 1);    return cc + GET(cc, 1);
727  #endif  #endif
728    
   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;  
   
729    case OP_MARK:    case OP_MARK:
730      case OP_PRUNE_ARG:
731      case OP_SKIP_ARG:
732      case OP_THEN_ARG:
733    return cc + 1 + 2 + cc[1];    return cc + 1 + 2 + cc[1];
734    
735    default:    default:
736      /* All opcodes are supported now! */
737      SLJIT_ASSERT_STOP();
738    return NULL;    return NULL;
739    }    }
740  }  }
# Line 764  int private_data_length = 0; Line 822  int private_data_length = 0;
822  pcre_uchar *alternative;  pcre_uchar *alternative;
823  pcre_uchar *name;  pcre_uchar *name;
824  pcre_uchar *end = NULL;  pcre_uchar *end = NULL;
825  int space, size, bracketlen, i;  int space, size, i;
826    pcre_uint32 bracketlen;
827    
828  /* 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. */
829  while (cc < ccend)  while (cc < ccend)
# Line 794  while (cc < ccend) Line 853  while (cc < ccend)
853      case OP_BRAPOS:      case OP_BRAPOS:
854      case OP_SBRA:      case OP_SBRA:
855      case OP_SBRAPOS:      case OP_SBRAPOS:
856      private_data_length += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
857      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
858      break;      break;
859    
860      case OP_CBRAPOS:      case OP_CBRAPOS:
861      case OP_SCBRAPOS:      case OP_SCBRAPOS:
862      private_data_length += sizeof(sljit_w);      private_data_length += sizeof(sljit_sw);
863      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;      common->optimized_cbracket[GET2(cc, 1 + LINK_SIZE)] = 0;
864      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
865      break;      break;
866    
867      case OP_COND:      case OP_COND:
868      case OP_SCOND:      case OP_SCOND:
869      bracketlen = cc[1 + LINK_SIZE];      /* Only AUTO_CALLOUT can insert this opcode. We do
870      if (bracketlen == OP_CREF)         not intend to support this case. */
871        {      if (cc[1 + LINK_SIZE] == OP_CALLOUT)
872        bracketlen = GET2(cc, 1 + LINK_SIZE + 1);        return -1;
       common->optimized_cbracket[bracketlen] = 0;  
       }  
     else if (bracketlen == OP_NCREF)  
       {  
       bracketlen = GET2(cc, 1 + LINK_SIZE + 1);  
       name = (pcre_uchar *)common->name_table;  
       alternative = name;  
       for (i = 0; i < common->name_count; i++)  
         {  
         if (GET2(name, 0) == bracketlen) break;  
         name += common->name_entry_size;  
         }  
       SLJIT_ASSERT(i != common->name_count);  
   
       for (i = 0; i < common->name_count; i++)  
         {  
         if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)  
           common->optimized_cbracket[GET2(alternative, 0)] = 0;  
         alternative += common->name_entry_size;  
         }  
       }  
873    
874      if (*cc == OP_COND)      if (*cc == OP_COND)
875        {        {
876        /* Might be a hidden SCOND. */        /* Might be a hidden SCOND. */
877        alternative = cc + GET(cc, 1);        alternative = cc + GET(cc, 1);
878        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
879          private_data_length += sizeof(sljit_w);          private_data_length += sizeof(sljit_sw);
880        }        }
881      else      else
882        private_data_length += sizeof(sljit_w);        private_data_length += sizeof(sljit_sw);
883      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
884      break;      break;
885    
886        case OP_CREF:
887        i = GET2(cc, 1);
888        common->optimized_cbracket[i] = 0;
889        cc += 1 + IMM2_SIZE;
890        break;
891    
892        case OP_NCREF:
893        bracketlen = GET2(cc, 1);
894        name = (pcre_uchar *)common->name_table;
895        alternative = name;
896        for (i = 0; i < common->name_count; i++)
897          {
898          if (GET2(name, 0) == bracketlen) break;
899          name += common->name_entry_size;
900          }
901        SLJIT_ASSERT(i != common->name_count);
902    
903        for (i = 0; i < common->name_count; i++)
904          {
905          if (STRCMP_UC_UC(alternative + IMM2_SIZE, name + IMM2_SIZE) == 0)
906            common->optimized_cbracket[GET2(alternative, 0)] = 0;
907          alternative += common->name_entry_size;
908          }
909        bracketlen = 0;
910        cc += 1 + IMM2_SIZE;
911        break;
912    
913      case OP_BRA:      case OP_BRA:
914      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
915      break;      break;
# Line 901  while (cc < ccend) Line 966  while (cc < ccend)
966    
967      case OP_RECURSE:      case OP_RECURSE:
968      /* Set its value only once. */      /* Set its value only once. */
969      if (common->recursive_head == 0)      if (common->recursive_head_ptr == 0)
970        {        {
971        common->recursive_head = common->ovector_start;        common->recursive_head_ptr = common->ovector_start;
972        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
973        }        }
974      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
975      break;      break;
976    
977        case OP_CALLOUT:
978        if (common->capture_last_ptr == 0)
979          {
980          common->capture_last_ptr = common->ovector_start;
981          common->ovector_start += sizeof(sljit_sw);
982          }
983        cc += 2 + 2 * LINK_SIZE;
984        break;
985    
986        case OP_THEN_ARG:
987        common->has_then = TRUE;
988        /* Fall through. */
989    
990        case OP_PRUNE_ARG:
991        common->needs_start_ptr = TRUE;
992        common->control_head_ptr = 1;
993        /* Fall through. */
994    
995      case OP_MARK:      case OP_MARK:
996      if (common->mark_ptr == 0)      if (common->mark_ptr == 0)
997        {        {
998        common->mark_ptr = common->ovector_start;        common->mark_ptr = common->ovector_start;
999        common->ovector_start += sizeof(sljit_w);        common->ovector_start += sizeof(sljit_sw);
1000        }        }
1001      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1002      break;      break;
1003    
1004        case OP_THEN:
1005        common->has_then = TRUE;
1006        /* Fall through. */
1007    
1008        case OP_PRUNE:
1009        case OP_SKIP:
1010        common->needs_start_ptr = TRUE;
1011        common->control_head_ptr = 1;
1012        cc += 1;
1013        break;
1014    
1015        case OP_SKIP_ARG:
1016        common->control_head_ptr = 1;
1017        common->has_skip_arg = TRUE;
1018        cc += 1 + 2 + cc[1];
1019        break;
1020    
1021      default:      default:
1022      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1023      if (cc == NULL)      if (cc == NULL)
# Line 926  while (cc < ccend) Line 1026  while (cc < ccend)
1026      }      }
1027    
1028    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1029      private_data_length += sizeof(sljit_w) * space;      private_data_length += sizeof(sljit_sw) * space;
1030    
1031    if (size != 0)    if (size != 0)
1032      {      {
# Line 941  while (cc < ccend) Line 1041  while (cc < ccend)
1041        cc += size;        cc += size;
1042      }      }
1043    
1044    if (bracketlen > 0)    if (bracketlen != 0)
1045      {      {
1046      if (cc >= end)      if (cc >= end)
1047        {        {
# Line 980  while (cc < ccend) Line 1080  while (cc < ccend)
1080      case OP_SBRAPOS:      case OP_SBRAPOS:
1081      case OP_SCOND:      case OP_SCOND:
1082      common->private_data_ptrs[cc - common->start] = private_data_ptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1083      private_data_ptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1084      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1085      break;      break;
1086    
1087      case OP_CBRAPOS:      case OP_CBRAPOS:
1088      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1089      common->private_data_ptrs[cc - common->start] = private_data_ptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1090      private_data_ptr += sizeof(sljit_w);      private_data_ptr += sizeof(sljit_sw);
1091      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;      bracketlen = 1 + LINK_SIZE + IMM2_SIZE;
1092      break;      break;
1093    
# Line 997  while (cc < ccend) Line 1097  while (cc < ccend)
1097      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)      if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1098        {        {
1099        common->private_data_ptrs[cc - common->start] = private_data_ptr;        common->private_data_ptrs[cc - common->start] = private_data_ptr;
1100        private_data_ptr += sizeof(sljit_w);        private_data_ptr += sizeof(sljit_sw);
1101        }        }
1102      bracketlen = 1 + LINK_SIZE;      bracketlen = 1 + LINK_SIZE;
1103      break;      break;
# Line 1065  while (cc < ccend) Line 1165  while (cc < ccend)
1165    if (space > 0 && cc >= end)    if (space > 0 && cc >= end)
1166      {      {
1167      common->private_data_ptrs[cc - common->start] = private_data_ptr;      common->private_data_ptrs[cc - common->start] = private_data_ptr;
1168      private_data_ptr += sizeof(sljit_w) * space;      private_data_ptr += sizeof(sljit_sw) * space;
1169      }      }
1170    
1171    if (size != 0)    if (size != 0)
# Line 1094  while (cc < ccend) Line 1194  while (cc < ccend)
1194    }    }
1195  }  }
1196    
1197  /* Returns with -1 if no need for frame. */  /* Returns with a frame_types (always < 0) if no need for frame. */
1198  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, BOOL recursive, BOOL* needs_control_head)
1199  {  {
 pcre_uchar *ccend = bracketend(cc);  
1200  int length = 0;  int length = 0;
1201  BOOL possessive = FALSE;  int possessive = 0;
1202    BOOL stack_restore = FALSE;
1203  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1204  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1205    /* The last capture is a local variable even for recursions. */
1206    BOOL capture_last_found = FALSE;
1207    
1208  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  #if defined DEBUG_FORCE_CONTROL_HEAD && DEBUG_FORCE_CONTROL_HEAD
1209    SLJIT_ASSERT(common->control_head_ptr != 0);
1210    *needs_control_head = TRUE;
1211    #else
1212    *needs_control_head = FALSE;
1213    #endif
1214    
1215    if (ccend == NULL)
1216    {    {
1217    length = 3;    ccend = bracketend(cc) - (1 + LINK_SIZE);
1218    possessive = TRUE;    if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
1219        {
1220        possessive = length = (common->capture_last_ptr != 0) ? 5 : 3;
1221        /* This is correct regardless of common->capture_last_ptr. */
1222        capture_last_found = TRUE;
1223        }
1224      cc = next_opcode(common, cc);
1225    }    }
1226    
 cc = next_opcode(common, cc);  
1227  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1228  while (cc < ccend)  while (cc < ccend)
1229    switch(*cc)    switch(*cc)
1230      {      {
1231      case OP_SET_SOM:      case OP_SET_SOM:
1232      SLJIT_ASSERT(common->has_set_som);      SLJIT_ASSERT(common->has_set_som);
1233        stack_restore = TRUE;
1234      if (!setsom_found)      if (!setsom_found)
1235        {        {
1236        length += 2;        length += 2;
# Line 1125  while (cc < ccend) Line 1240  while (cc < ccend)
1240      break;      break;
1241    
1242      case OP_MARK:      case OP_MARK:
1243        case OP_PRUNE_ARG:
1244        case OP_THEN_ARG:
1245      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1246        stack_restore = TRUE;
1247      if (!setmark_found)      if (!setmark_found)
1248        {        {
1249        length += 2;        length += 2;
1250        setmark_found = TRUE;        setmark_found = TRUE;
1251        }        }
1252        if (common->control_head_ptr != 0)
1253          *needs_control_head = TRUE;
1254      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
1255      break;      break;
1256    
1257      case OP_RECURSE:      case OP_RECURSE:
1258        stack_restore = TRUE;
1259      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1260        {        {
1261        length += 2;        length += 2;
# Line 1145  while (cc < ccend) Line 1266  while (cc < ccend)
1266        length += 2;        length += 2;
1267        setmark_found = TRUE;        setmark_found = TRUE;
1268        }        }
1269        if (common->capture_last_ptr != 0 && !capture_last_found)
1270          {
1271          length += 2;
1272          capture_last_found = TRUE;
1273          }
1274      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1275      break;      break;
1276    
# Line 1152  while (cc < ccend) Line 1278  while (cc < ccend)
1278      case OP_CBRAPOS:      case OP_CBRAPOS:
1279      case OP_SCBRA:      case OP_SCBRA:
1280      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1281        stack_restore = TRUE;
1282        if (common->capture_last_ptr != 0 && !capture_last_found)
1283          {
1284          length += 2;
1285          capture_last_found = TRUE;
1286          }
1287      length += 3;      length += 3;
1288      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1289      break;      break;
1290    
1291        case OP_PRUNE:
1292        case OP_SKIP:
1293        case OP_SKIP_ARG:
1294        case OP_COMMIT:
1295        if (common->control_head_ptr != 0)
1296          *needs_control_head = TRUE;
1297        /* Fall through. */
1298    
1299      default:      default:
1300        stack_restore = TRUE;
1301        /* Fall through. */
1302    
1303        case OP_NOT_WORD_BOUNDARY:
1304        case OP_WORD_BOUNDARY:
1305        case OP_NOT_DIGIT:
1306        case OP_DIGIT:
1307        case OP_NOT_WHITESPACE:
1308        case OP_WHITESPACE:
1309        case OP_NOT_WORDCHAR:
1310        case OP_WORDCHAR:
1311        case OP_ANY:
1312        case OP_ALLANY:
1313        case OP_ANYBYTE:
1314        case OP_NOTPROP:
1315        case OP_PROP:
1316        case OP_ANYNL:
1317        case OP_NOT_HSPACE:
1318        case OP_HSPACE:
1319        case OP_NOT_VSPACE:
1320        case OP_VSPACE:
1321        case OP_EXTUNI:
1322        case OP_EODN:
1323        case OP_EOD:
1324        case OP_CIRC:
1325        case OP_CIRCM:
1326        case OP_DOLL:
1327        case OP_DOLLM:
1328        case OP_CHAR:
1329        case OP_CHARI:
1330        case OP_NOT:
1331        case OP_NOTI:
1332    
1333        case OP_EXACT:
1334        case OP_POSSTAR:
1335        case OP_POSPLUS:
1336        case OP_POSQUERY:
1337        case OP_POSUPTO:
1338    
1339        case OP_EXACTI:
1340        case OP_POSSTARI:
1341        case OP_POSPLUSI:
1342        case OP_POSQUERYI:
1343        case OP_POSUPTOI:
1344    
1345        case OP_NOTEXACT:
1346        case OP_NOTPOSSTAR:
1347        case OP_NOTPOSPLUS:
1348        case OP_NOTPOSQUERY:
1349        case OP_NOTPOSUPTO:
1350    
1351        case OP_NOTEXACTI:
1352        case OP_NOTPOSSTARI:
1353        case OP_NOTPOSPLUSI:
1354        case OP_NOTPOSQUERYI:
1355        case OP_NOTPOSUPTOI:
1356    
1357        case OP_TYPEEXACT:
1358        case OP_TYPEPOSSTAR:
1359        case OP_TYPEPOSPLUS:
1360        case OP_TYPEPOSQUERY:
1361        case OP_TYPEPOSUPTO:
1362    
1363        case OP_CLASS:
1364        case OP_NCLASS:
1365        case OP_XCLASS:
1366    
1367      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
1368      SLJIT_ASSERT(cc != NULL);      SLJIT_ASSERT(cc != NULL);
1369      break;      break;
1370      }      }
1371    
1372  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
1373  if (SLJIT_UNLIKELY(possessive) && length == 3)  if (SLJIT_UNLIKELY(possessive == length))
1374    return -1;    return stack_restore ? no_frame : no_stack;
1375    
1376  if (length > 0)  if (length > 0)
1377    return length + 1;    return length + 1;
1378  return -1;  return stack_restore ? no_frame : no_stack;
1379  }  }
1380    
1381  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, pcre_uchar *ccend, int stackpos, int stacktop, BOOL recursive)
1382  {  {
1383  DEFINE_COMPILER;  DEFINE_COMPILER;
 pcre_uchar *ccend = bracketend(cc);  
1384  BOOL setsom_found = recursive;  BOOL setsom_found = recursive;
1385  BOOL setmark_found = recursive;  BOOL setmark_found = recursive;
1386    /* The last capture is a local variable even for recursions. */
1387    BOOL capture_last_found = FALSE;
1388  int offset;  int offset;
1389    
1390  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
# Line 1184  SLJIT_UNUSED_ARG(stacktop); Line 1392  SLJIT_UNUSED_ARG(stacktop);
1392  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
1393    
1394  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
1395  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (ccend == NULL)
1396    cc = next_opcode(common, cc);    {
1397      ccend = bracketend(cc) - (1 + LINK_SIZE);
1398      if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
1399        cc = next_opcode(common, cc);
1400      }
1401    
1402  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
1403  while (cc < ccend)  while (cc < ccend)
1404    switch(*cc)    switch(*cc)
# Line 1195  while (cc < ccend) Line 1408  while (cc < ccend)
1408      if (!setsom_found)      if (!setsom_found)
1409        {        {
1410        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1411        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1412        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1413        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1414        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1415        setsom_found = TRUE;        setsom_found = TRUE;
1416        }        }
1417      cc += 1;      cc += 1;
1418      break;      break;
1419    
1420      case OP_MARK:      case OP_MARK:
1421        case OP_PRUNE_ARG:
1422        case OP_THEN_ARG:
1423      SLJIT_ASSERT(common->mark_ptr != 0);      SLJIT_ASSERT(common->mark_ptr != 0);
1424      if (!setmark_found)      if (!setmark_found)
1425        {        {
1426        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);
1427        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);
1428        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1429        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1430        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1431        setmark_found = TRUE;        setmark_found = TRUE;
1432        }        }
1433      cc += 1 + 2 + cc[1];      cc += 1 + 2 + cc[1];
# Line 1222  while (cc < ccend) Line 1437  while (cc < ccend)
1437      if (common->has_set_som && !setsom_found)      if (common->has_set_som && !setsom_found)
1438        {        {
1439        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
1440        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -OVECTOR(0));
1441        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1442        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1443        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1444        setsom_found = TRUE;        setsom_found = TRUE;
1445        }        }
1446      if (common->mark_ptr != 0 && !setmark_found)      if (common->mark_ptr != 0 && !setmark_found)
1447        {        {
1448        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);
1449        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);
1450        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1451        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1452        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_sw);
1453        setmark_found = TRUE;        setmark_found = TRUE;
1454        }        }
1455        if (common->capture_last_ptr != 0 && !capture_last_found)
1456          {
1457          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1458          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1459          stackpos += (int)sizeof(sljit_sw);
1460          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1461          stackpos += (int)sizeof(sljit_sw);
1462          capture_last_found = TRUE;
1463          }
1464      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
1465      break;      break;
1466    
# Line 1244  while (cc < ccend) Line 1468  while (cc < ccend)
1468      case OP_CBRAPOS:      case OP_CBRAPOS:
1469      case OP_SCBRA:      case OP_SCBRA:
1470      case OP_SCBRAPOS:      case OP_SCBRAPOS:
1471        if (common->capture_last_ptr != 0 && !capture_last_found)
1472          {
1473          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
1474          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, -common->capture_last_ptr);
1475          stackpos += (int)sizeof(sljit_sw);
1476          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1477          stackpos += (int)sizeof(sljit_sw);
1478          capture_last_found = TRUE;
1479          }
1480      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
1481      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
1482      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1483      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
1484      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));
1485      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
1486      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1487      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
1488      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_sw);
1489    
1490      cc += 1 + LINK_SIZE + IMM2_SIZE;      cc += 1 + LINK_SIZE + IMM2_SIZE;
1491      break;      break;
# Line 1263  while (cc < ccend) Line 1496  while (cc < ccend)
1496      break;      break;
1497      }      }
1498    
1499  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, 0);
1500  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
1501  }  }
1502    
1503  static SLJIT_INLINE int get_private_data_length_for_copy(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)
1504  {  {
1505  int private_data_length = 2;  int private_data_length = needs_control_head ? 3 : 2;
1506  int size;  int size;
1507  pcre_uchar *alternative;  pcre_uchar *alternative;
1508  /* Calculate the sum of the private machine words. */  /* Calculate the sum of the private machine words. */
# Line 1382  return private_data_length; Line 1615  return private_data_length;
1615  }  }
1616    
1617  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,  static void copy_private_data(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1618    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop, BOOL needs_control_head)
1619  {  {
1620  DEFINE_COMPILER;  DEFINE_COMPILER;
1621  int srcw[2];  int srcw[2];
# Line 1403  stacktop = STACK(stacktop - 1); Line 1636  stacktop = STACK(stacktop - 1);
1636    
1637  if (!save)  if (!save)
1638    {    {
1639    stackptr += sizeof(sljit_w);    stackptr += (needs_control_head ? 2 : 1) * sizeof(sljit_sw);
1640    if (stackptr < stacktop)    if (stackptr < stacktop)
1641      {      {
1642      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1643      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1644      tmp1empty = FALSE;      tmp1empty = FALSE;
1645      }      }
1646    if (stackptr < stacktop)    if (stackptr < stacktop)
1647      {      {
1648      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1649      stackptr += sizeof(sljit_w);      stackptr += sizeof(sljit_sw);
1650      tmp2empty = FALSE;      tmp2empty = FALSE;
1651      }      }
1652    /* The tmp1next must be TRUE in either way. */    /* The tmp1next must be TRUE in either way. */
1653    }    }
1654    
1655  while (status != end)  do
1656    {    {
1657    count = 0;    count = 0;
1658    switch(status)    switch(status)
1659      {      {
1660      case start:      case start:
1661      SLJIT_ASSERT(save && common->recursive_head != 0);      SLJIT_ASSERT(save && common->recursive_head_ptr != 0);
1662      count = 1;      count = 1;
1663      srcw[0] = common->recursive_head;      srcw[0] = common->recursive_head_ptr;
1664        if (needs_control_head)
1665          {
1666          SLJIT_ASSERT(common->control_head_ptr != 0);
1667          count = 2;
1668          srcw[1] = common->control_head_ptr;
1669          }
1670      status = loop;      status = loop;
1671      break;      break;
1672    
# Line 1504  while (status != end) Line 1743  while (status != end)
1743          {          {
1744          count = 2;          count = 2;
1745          srcw[0] = PRIVATE_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1746          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1747          }          }
1748        cc += 2;        cc += 2;
1749  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1517  while (status != end) Line 1756  while (status != end)
1756          {          {
1757          count = 2;          count = 2;
1758          srcw[0] = PRIVATE_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1759          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_w);          srcw[1] = PRIVATE_DATA(cc) + sizeof(sljit_sw);
1760          }          }
1761        cc += 2 + IMM2_SIZE;        cc += 2 + IMM2_SIZE;
1762  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
# Line 1539  while (status != end) Line 1778  while (status != end)
1778          {          {
1779          count = 2;          count = 2;
1780          srcw[0] = PRIVATE_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1781          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_sw);
1782          }          }
1783        cc += 1;        cc += 1;
1784        break;        break;
# Line 1549  while (status != end) Line 1788  while (status != end)
1788          {          {
1789          count = 2;          count = 2;
1790          srcw[0] = PRIVATE_DATA(cc);          srcw[0] = PRIVATE_DATA(cc);
1791          srcw[1] = srcw[0] + sizeof(sljit_w);          srcw[1] = srcw[0] + sizeof(sljit_sw);
1792          }          }
1793        cc += 1 + IMM2_SIZE;        cc += 1 + IMM2_SIZE;
1794        break;        break;
# Line 1573  while (status != end) Line 1812  while (status != end)
1812            case 2:            case 2:
1813            count = 2;            count = 2;
1814            srcw[0] = PRIVATE_DATA(cc);            srcw[0] = PRIVATE_DATA(cc);
1815            srcw[1] = srcw[0] + sizeof(sljit_w);            srcw[1] = srcw[0] + sizeof(sljit_sw);
1816            break;            break;
1817    
1818            default:            default:
# Line 1605  while (status != end) Line 1844  while (status != end)
1844          if (!tmp1empty)          if (!tmp1empty)
1845            {            {
1846            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1847            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1848            }            }
1849          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1850          tmp1empty = FALSE;          tmp1empty = FALSE;
# Line 1616  while (status != end) Line 1855  while (status != end)
1855          if (!tmp2empty)          if (!tmp2empty)
1856            {            {
1857            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1858            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1859            }            }
1860          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), srcw[count]);
1861          tmp2empty = FALSE;          tmp2empty = FALSE;
# Line 1633  while (status != end) Line 1872  while (status != end)
1872          if (!tmp1empty)          if (!tmp1empty)
1873            {            {
1874            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1875            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1876            }            }
1877          tmp1next = FALSE;          tmp1next = FALSE;
1878          }          }
# Line 1645  while (status != end) Line 1884  while (status != end)
1884          if (!tmp2empty)          if (!tmp2empty)
1885            {            {
1886            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), stackptr);
1887            stackptr += sizeof(sljit_w);            stackptr += sizeof(sljit_sw);
1888            }            }
1889          tmp1next = TRUE;          tmp1next = TRUE;
1890          }          }
1891        }        }
1892      }      }
1893    }    }
1894    while (status != end);
1895    
1896  if (save)  if (save)
1897    {    {
# Line 1660  if (save) Line 1900  if (save)
1900      if (!tmp1empty)      if (!tmp1empty)
1901        {        {
1902        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1903        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1904        }        }
1905      if (!tmp2empty)      if (!tmp2empty)
1906        {        {
1907        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1908        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1909        }        }
1910      }      }
1911    else    else
# Line 1673  if (save) Line 1913  if (save)
1913      if (!tmp2empty)      if (!tmp2empty)
1914        {        {
1915        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP2, 0);
1916        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1917        }        }
1918      if (!tmp1empty)      if (!tmp1empty)
1919        {        {
1920        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackptr, TMP1, 0);
1921        stackptr += sizeof(sljit_w);        stackptr += sizeof(sljit_sw);
1922        }        }
1923      }      }
1924    }    }
1925  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));  SLJIT_ASSERT(cc == ccend && stackptr == stacktop && (save || (tmp1empty && tmp2empty)));
1926  }  }
1927    
1928    static SLJIT_INLINE pcre_uchar *set_then_offsets(compiler_common *common, pcre_uchar *cc, pcre_uint8 *current_offset)
1929    {
1930    pcre_uchar *end = bracketend(cc);
1931    BOOL has_alternatives = cc[GET(cc, 1)] == OP_ALT;
1932    
1933    /* Assert captures then. */
1934    if (*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT)
1935      current_offset = NULL;
1936    /* Conditional block does not. */
1937    if (*cc == OP_COND || *cc == OP_SCOND)
1938      has_alternatives = FALSE;
1939    
1940    cc = next_opcode(common, cc);
1941    if (has_alternatives)
1942      current_offset = common->then_offsets + (cc - common->start);
1943    
1944    while (cc < end)
1945      {
1946      if ((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND))
1947        cc = set_then_offsets(common, cc, current_offset);
1948      else
1949        {
1950        if (*cc == OP_ALT && has_alternatives)
1951          current_offset = common->then_offsets + (cc + 1 + LINK_SIZE - common->start);
1952        if (*cc >= OP_THEN && *cc <= OP_THEN_ARG && current_offset != NULL)
1953          *current_offset = 1;
1954        cc = next_opcode(common, cc);
1955        }
1956      }
1957    
1958    return end;
1959    }
1960    
1961  #undef CASE_ITERATOR_PRIVATE_DATA_1  #undef CASE_ITERATOR_PRIVATE_DATA_1
1962  #undef CASE_ITERATOR_PRIVATE_DATA_2A  #undef CASE_ITERATOR_PRIVATE_DATA_2A
1963  #undef CASE_ITERATOR_PRIVATE_DATA_2B  #undef CASE_ITERATOR_PRIVATE_DATA_2B
# Line 1692  SLJIT_ASSERT(cc == ccend && stackptr == Line 1965  SLJIT_ASSERT(cc == ccend && stackptr ==
1965  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2A
1966  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B  #undef CASE_ITERATOR_TYPE_PRIVATE_DATA_2B
1967    
1968  static SLJIT_INLINE BOOL ispowerof2(unsigned int value)  static SLJIT_INLINE BOOL is_powerof2(unsigned int value)
1969  {  {
1970  return (value & (value - 1)) == 0;  return (value & (value - 1)) == 0;
1971  }  }
# Line 1703  while (list) Line 1976  while (list)
1976    {    {
1977    /* sljit_set_label is clever enough to do nothing    /* sljit_set_label is clever enough to do nothing
1978    if either the jump or the label is NULL. */    if either the jump or the label is NULL. */
1979    sljit_set_label(list->jump, label);    SET_LABEL(list->jump, label);
1980    list = list->next;    list = list->next;
1981    }    }
1982  }  }
# Line 1719  if (list_item) Line 1992  if (list_item)
1992    }    }
1993  }  }
1994    
1995  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)
1996  {  {
1997  DEFINE_COMPILER;  DEFINE_COMPILER;
1998  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));  stub_list* list_item = sljit_alloc_memory(compiler, sizeof(stub_list));
1999    
2000  if (list_item)  if (list_item)
2001    {    {
   list_item->type = type;  
   list_item->data = data;  
2002    list_item->start = start;    list_item->start = start;
2003    list_item->quit = LABEL();    list_item->quit = LABEL();
2004    list_item->next = common->stubs;    list_item->next = common->stubs;
# Line 1743  stub_list* list_item = common->stubs; Line 2014  stub_list* list_item = common->stubs;
2014  while (list_item)  while (list_item)
2015    {    {
2016    JUMPHERE(list_item->start);    JUMPHERE(list_item->start);
2017    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;  
     }  
2018    JUMPTO(SLJIT_JUMP, list_item->quit);    JUMPTO(SLJIT_JUMP, list_item->quit);
2019    list_item = list_item->next;    list_item = list_item->next;
2020    }    }
# Line 1768  static SLJIT_INLINE void allocate_stack( Line 2034  static SLJIT_INLINE void allocate_stack(
2034  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
2035  DEFINE_COMPILER;  DEFINE_COMPILER;
2036    
2037  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));
2038  #ifdef DESTROY_REGISTERS  #ifdef DESTROY_REGISTERS
2039  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 12345);
2040  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);  OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
# Line 1776  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); Line 2042  OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0);
2042  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, TMP1, 0);
2043  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2044  #endif  #endif
2045  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));
2046  }  }
2047    
2048  static SLJIT_INLINE void free_stack(compiler_common *common, int size)  static SLJIT_INLINE void free_stack(compiler_common *common, int size)
2049  {  {
2050  DEFINE_COMPILER;  DEFINE_COMPILER;
2051  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));
2052  }  }
2053    
2054  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)  static SLJIT_INLINE void reset_ovector(compiler_common *common, int length)
# Line 1790  static SLJIT_INLINE void reset_ovector(c Line 2056  static SLJIT_INLINE void reset_ovector(c
2056  DEFINE_COMPILER;  DEFINE_COMPILER;
2057  struct sljit_label *loop;  struct sljit_label *loop;
2058  int i;  int i;
2059    
2060  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
2061    SLJIT_ASSERT(length > 1);
2062  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
2063  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));
2064  if (length < 8)  if (length < 8)
2065    {    {
2066    for (i = 0; i < length; i++)    for (i = 1; i < length; i++)
2067      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_TEMPORARY_REG1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), SLJIT_SCRATCH_REG1, 0);
2068    }    }
2069  else  else
2070    {    {
2071    GET_LOCAL_BASE(SLJIT_TEMPORARY_REG2, 0, OVECTOR_START - sizeof(sljit_w));    GET_LOCAL_BASE(SLJIT_SCRATCH_REG2, 0, OVECTOR_START);
2072    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, length - 1);
2073    loop = LABEL();    loop = LABEL();
2074    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(sljit_w), SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOVU, SLJIT_MEM1(SLJIT_SCRATCH_REG2), sizeof(sljit_sw), SLJIT_SCRATCH_REG1, 0);
2075    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 1);
2076    JUMPTO(SLJIT_C_NOT_ZERO, loop);    JUMPTO(SLJIT_C_NOT_ZERO, loop);
2077    }    }
2078  }  }
2079    
2080    static SLJIT_INLINE void do_reset_match(compiler_common *common, int length)
2081    {
2082    DEFINE_COMPILER;
2083    struct sljit_label *loop;
2084    int i;
2085    
2086    SLJIT_ASSERT(length > 1);
2087    /* OVECTOR(1) contains the "string begin - 1" constant. */
2088    if (length > 2)
2089      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
2090    if (length < 8)
2091      {
2092      for (i = 2; i < length; i++)
2093        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(i), TMP1, 0);
2094      }
2095    else
2096      {
2097      GET_LOCAL_BASE(TMP2, 0, OVECTOR_START + sizeof(sljit_sw));
2098      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_IMM, length - 2);
2099      loop = LABEL();
2100      OP1(SLJIT_MOVU, SLJIT_MEM1(TMP2), sizeof(sljit_sw), TMP1, 0);
2101      OP2(SLJIT_SUB | SLJIT_SET_E, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 1);
2102      JUMPTO(SLJIT_C_NOT_ZERO, loop);
2103      }
2104    
2105    OP1(SLJIT_MOV, STACK_TOP, 0, ARGUMENTS, 0);
2106    if (common->mark_ptr != 0)
2107      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, SLJIT_IMM, 0);
2108    SLJIT_ASSERT(common->control_head_ptr != 0);
2109    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
2110    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(jit_arguments, stack));
2111    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_ptr);
2112    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(STACK_TOP), SLJIT_OFFSETOF(struct sljit_stack, base));
2113    }
2114    
2115    static sljit_sw SLJIT_CALL do_check_control_chain(sljit_sw *current)
2116    {
2117    sljit_sw return_value = 0;
2118    const pcre_uchar *skip_arg = NULL;
2119    
2120    SLJIT_ASSERT(current != NULL);
2121    do
2122      {
2123      switch (current[-2])
2124        {
2125        case type_commit:
2126        /* Commit overwrites all. */
2127        return -1;
2128    
2129        case type_prune:
2130        case type_then_trap:
2131        break;
2132    
2133        case type_skip:
2134        /* Overwrites prune, but not other skips. */
2135        if (return_value == 0 && skip_arg == NULL)
2136          return_value = current[-3];
2137        break;
2138    
2139        case type_skip_arg:
2140        if (return_value == 0 && skip_arg == NULL)
2141          skip_arg = (pcre_uchar *)current[-3];
2142        break;
2143    
2144        case type_mark:
2145        if (return_value == 0 && skip_arg != NULL)
2146          if (STRCMP_UC_UC(skip_arg, (pcre_uchar *)current[-3]) == 0)
2147            return_value = current[-4];
2148        break;
2149    
2150        default:
2151        SLJIT_ASSERT_STOP();
2152        break;
2153        }
2154      current = (sljit_sw*)current[-1];
2155      }
2156    while (current != NULL);
2157    return (return_value != 0 || skip_arg == NULL) ? return_value : -2;
2158    }
2159    
2160    static sljit_sw SLJIT_CALL do_search_then_trap(sljit_sw *current, sljit_sw start)
2161    {
2162    do
2163      {
2164      switch (current[-2])
2165        {
2166        case type_commit:
2167        /* Commit overwrites all. */
2168        return 0;
2169    
2170        case type_then_trap:
2171        if (current[-3] == start)
2172          return (sljit_sw)current;
2173        break;
2174    
2175        case type_prune:
2176        case type_skip:
2177        case type_skip_arg:
2178        case type_mark:
2179        break;
2180    
2181        default:
2182        SLJIT_ASSERT_STOP();
2183        break;
2184        }
2185      current = (sljit_sw*)current[-1];
2186      SLJIT_ASSERT(current != NULL);
2187      }
2188    while (TRUE);
2189    }
2190    
2191  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
2192  {  {
2193  DEFINE_COMPILER;  DEFINE_COMPILER;
2194  struct sljit_label *loop;  struct sljit_label *loop;
2195  struct sljit_jump *earlyexit;  struct sljit_jump *early_quit;
2196    
2197  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
2198  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));
2199  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);
2200    
2201  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG1, 0, ARGUMENTS, 0);
2202  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2203    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);
2204  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));
2205  if (common->mark_ptr != 0)  if (common->mark_ptr != 0)
2206    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);
2207  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));
2208  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));
2209  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);  GET_LOCAL_BASE(SLJIT_SAVED_REG1, 0, OVECTOR_START);
2210  /* Unlikely, but possible */  /* Unlikely, but possible */
2211  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);
2212  loop = LABEL();  loop = LABEL();
2213  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);
2214  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));
2215  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
2216  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2217  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);
2218  #endif  #endif
2219  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);
2220  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);
2221  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
2222  JUMPHERE(earlyexit);  JUMPHERE(early_quit);
2223    
2224  /* Calculate the return value, which is the maximum ovector value. */  /* Calculate the return value, which is the maximum ovector value. */
2225  if (topbracket > 1)  if (topbracket > 1)
2226    {    {
2227    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));
2228    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, SLJIT_IMM, topbracket + 1);
2229    
2230    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
2231    loop = LABEL();    loop = LABEL();
2232    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)));
2233    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);
2234    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);
2235    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_SCRATCH_REG2, 0);
2236    }    }
2237  else  else
2238    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
# Line 1862  else Line 2241  else
2241  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)
2242  {  {
2243  DEFINE_COMPILER;  DEFINE_COMPILER;
2244    struct sljit_jump *jump;
2245    
2246  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);
2247  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
2248      && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
2249    
2250  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
2251  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
2252  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));
2253  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);
2254    
2255  /* Store match begin and end. */  /* Store match begin and end. */
2256  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));
2257  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));
2258  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);  
2259    jump = CMP(SLJIT_C_SIG_LESS, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, 3);
2260    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);
2261    #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2262    OP2(SLJIT_ASHR, SLJIT_SCRATCH_REG3, 0, SLJIT_SCRATCH_REG3, 0, SLJIT_IMM, UCHAR_SHIFT);
2263    #endif
2264    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_SCRATCH_REG2), 2 * sizeof(int), SLJIT_SCRATCH_REG3, 0);
2265    JUMPHERE(jump);
2266    
2267    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);
2268  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);
2269  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2270  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);
2271  #endif  #endif
2272  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);
2273    
2274  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);
2275  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2276  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);
2277  #endif  #endif
2278  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);
2279    
2280  JUMPTO(SLJIT_JUMP, quit);  JUMPTO(SLJIT_JUMP, quit);
2281  }  }
# Line 1998  if (c <= 127 && bit == 0x20) Line 2388  if (c <= 127 && bit == 0x20)
2388    return (0 << 8) | 0x20;    return (0 << 8) | 0x20;
2389    
2390  /* Since c != oc, they must have at least 1 bit difference. */  /* Since c != oc, they must have at least 1 bit difference. */
2391  if (!ispowerof2(bit))  if (!is_powerof2(bit))
2392    return 0;    return 0;
2393    
2394  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2395    
2396  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2397  if (common->utf && c > 127)  if (common->utf && c > 127)
# Line 2017  if (common->utf && c > 127) Line 2407  if (common->utf && c > 127)
2407  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2408  return (0 << 8) | bit;  return (0 << 8) | bit;
2409    
2410  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2411    
 #ifdef COMPILE_PCRE16  
2412  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2413  if (common->utf && c > 65535)  if (common->utf && c > 65535)
2414    {    {
# Line 2030  if (common->utf && c > 65535) Line 2419  if (common->utf && c > 65535)
2419    }    }
2420  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2421  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));  return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
 #endif /* COMPILE_PCRE16 */  
2422    
2423  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16|32] */
2424  }  }
2425    
2426  static void check_partial(compiler_common *common, BOOL force)  static void check_partial(compiler_common *common, BOOL force)
# Line 2052  else if (common->mode == JIT_PARTIAL_SOF Line 2440  else if (common->mode == JIT_PARTIAL_SOF
2440    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);
2441    
2442  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2443    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);
2444  else  else
2445    {    {
2446    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
# Line 2065  if (jump != NULL) Line 2453  if (jump != NULL)
2453    JUMPHERE(jump);    JUMPHERE(jump);
2454  }  }
2455    
2456  static struct sljit_jump *check_str_end(compiler_common *common)  static void check_str_end(compiler_common *common, jump_list **end_reached)
2457  {  {
2458  /* Does not affect registers. Usually used in a tight spot. */  /* Does not affect registers. Usually used in a tight spot. */
2459  DEFINE_COMPILER;  DEFINE_COMPILER;
2460  struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *nohit;  
 struct sljit_jump *return_value;  
2461    
2462  if (common->mode == JIT_COMPILE)  if (common->mode == JIT_COMPILE)
2463    return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    {
2464      add_jump(compiler, end_reached, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
2465      return;
2466      }
2467    
2468  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
2469  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2470    {    {
2471    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));
2472    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);
2473    JUMPHERE(nohit);    add_jump(compiler, end_reached, JUMP(SLJIT_JUMP));
   return_value = JUMP(SLJIT_JUMP);  
2474    }    }
2475  else  else
2476    {    {
2477    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));
2478    if (common->partialmatchlabel != NULL)    if (common->partialmatchlabel != NULL)
2479      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);      JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
2480    else    else
2481      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));      add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
2482    }    }
2483  JUMPHERE(jump);  JUMPHERE(jump);
 return return_value;  
2484  }  }
2485    
2486  static void detect_partial_match(compiler_common *common, jump_list **backtracks)  static void detect_partial_match(compiler_common *common, jump_list **backtracks)
# Line 2112  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR Line 2499  jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR
2499  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));
2500  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)  if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
2501    {    {
2502    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);
2503    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));    add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
2504    }    }
2505  else  else
# Line 2130  static void read_char(compiler_common *c Line 2517  static void read_char(compiler_common *c
2517  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
2518  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2519  DEFINE_COMPILER;  DEFINE_COMPILER;
2520  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2521  struct sljit_jump *jump;  struct sljit_jump *jump;
2522  #endif  #endif
2523    
2524  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2525  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2526  if (common->utf)  if (common->utf)
2527    {    {
2528  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2529    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2530  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2531    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2532  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2533    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2534    JUMPHERE(jump);    JUMPHERE(jump);
2535    }    }
2536  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2537  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));
2538  }  }
2539    
# Line 2157  static void peek_char(compiler_common *c Line 2542  static void peek_char(compiler_common *c
2542  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
2543  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
2544  DEFINE_COMPILER;  DEFINE_COMPILER;
2545  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2546  struct sljit_jump *jump;  struct sljit_jump *jump;
2547  #endif  #endif
2548    
2549  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2550  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2551  if (common->utf)  if (common->utf)
2552    {    {
2553  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2554    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2555  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2556    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2557  #endif  #endif /* COMPILE_PCRE[8|16] */
 #endif /* COMPILE_PCRE8 */  
2558    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
2559    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2560    JUMPHERE(jump);    JUMPHERE(jump);
2561    }    }
2562  #endif  #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2563  }  }
2564    
2565  static void read_char8_type(compiler_common *common)  static void read_char8_type(compiler_common *common)
2566  {  {
2567  /* 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. */
2568  DEFINE_COMPILER;  DEFINE_COMPILER;
2569  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2570  struct sljit_jump *jump;  struct sljit_jump *jump;
2571  #endif  #endif
2572    
# Line 2192  if (common->utf) Line 2575  if (common->utf)
2575    {    {
2576    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2577    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));
2578  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2579    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
2580    it is needed in most cases. */    it is needed in most cases. */
2581    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2582    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
2583    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
2584    JUMPHERE(jump);    JUMPHERE(jump);
2585  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
2586    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2587    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2588    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
# Line 2208  if (common->utf) Line 2590  if (common->utf)
2590    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2591    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
2592    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);
2593    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2594    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2595    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2596  #endif  #elif defined COMPILE_PCRE32
2597  #endif /* COMPILE_PCRE8 */    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2598      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2599      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2600      JUMPHERE(jump);
2601    #endif /* COMPILE_PCRE[8|16|32] */
2602    return;    return;
2603    }    }
2604  #endif  #endif /* SUPPORT_UTF */
2605  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
2606  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));
2607  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2608  /* The ctypes array contains only 256 values. */  /* The ctypes array contains only 256 values. */
2609  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2610  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);  jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
2611  #endif  #endif
2612  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
2613  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2614  JUMPHERE(jump);  JUMPHERE(jump);
2615  #endif  #endif
2616  }  }
# Line 2233  static void skip_char_back(compiler_comm Line 2619  static void skip_char_back(compiler_comm
2619  {  {
2620  /* 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. */
2621  DEFINE_COMPILER;  DEFINE_COMPILER;
2622  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2623    #if defined COMPILE_PCRE8
2624  struct sljit_label *label;  struct sljit_label *label;
2625    
2626  if (common->utf)  if (common->utf)
# Line 2245  if (common->utf) Line 2632  if (common->utf)
2632    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
2633    return;    return;
2634    }    }
2635  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2636  if (common->utf)  if (common->utf)
2637    {    {
2638    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 2254  if (common->utf) Line 2640  if (common->utf)
2640    /* Skip low surrogate if necessary. */    /* Skip low surrogate if necessary. */
2641    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2642    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);
2643    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2644    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2645    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2646    return;    return;
2647    }    }
2648  #endif  #endif /* COMPILE_PCRE[8|16] */
2649    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2650  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));
2651  }  }
2652    
# Line 2276  if (nltype == NLTYPE_ANY) Line 2663  if (nltype == NLTYPE_ANY)
2663  else if (nltype == NLTYPE_ANYCRLF)  else if (nltype == NLTYPE_ANYCRLF)
2664    {    {
2665    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);
2666    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2667    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);
2668    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);
2669    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));
2670    }    }
2671  else  else
# Line 2290  else Line 2677  else
2677    
2678  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
2679    
2680  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
2681  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2682  {  {
2683  /* Fast decoding a UTF-8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
# Line 2378  sljit_emit_fast_return(compiler, RETURN_ Line 2765  sljit_emit_fast_return(compiler, RETURN_
2765  JUMPHERE(jump);  JUMPHERE(jump);
2766    
2767  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
2768  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);
2769  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2770  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
2771  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2772  }  }
2773    
2774  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
2775    
 #ifdef COMPILE_PCRE16  
2776  static void do_utfreadchar(compiler_common *common)  static void do_utfreadchar(compiler_common *common)
2777  {  {
2778  /* 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 2411  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC Line 2797  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UC
2797  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
2798  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2799  }  }
 #endif /* COMPILE_PCRE16 */  
2800    
2801  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE[8|16] */
2802    
2803  #endif /* SUPPORT_UTF */  #endif /* SUPPORT_UTF */
2804    
# Line 2433  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 2818  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
2818    
2819  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
2820  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2821  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));
2822  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
2823  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
2824  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
2825  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_stage2));
2826  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
2827  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));
2828  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
2829  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2830  }  }
# Line 2453  struct sljit_label *newlinelabel = NULL; Line 2838  struct sljit_label *newlinelabel = NULL;
2838  struct sljit_jump *start;  struct sljit_jump *start;
2839  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
2840  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
2841  #ifdef SUPPORT_UTF  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2842  struct sljit_jump *singlechar;  struct sljit_jump *singlechar;
2843  #endif  #endif
2844  jump_list *newline = NULL;  jump_list *newline = NULL;
# Line 2508  if (newlinecheck) Line 2893  if (newlinecheck)
2893    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2894    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2895    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);
2896    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2897  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
2898    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
2899  #endif  #endif
2900    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2901    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
# Line 2531  if (newlinecheck) Line 2916  if (newlinecheck)
2916    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);
2917    
2918  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));
2919  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #if defined SUPPORT_UTF && !defined COMPILE_PCRE32
2920    #if defined COMPILE_PCRE8
2921  if (common->utf)  if (common->utf)
2922    {    {
2923    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2924    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);
2925    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2926    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2927    }    }
2928  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
2929  if (common->utf)  if (common->utf)
2930    {    {
2931    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2932    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2933    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);
2934    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
2935    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2936    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2937    JUMPHERE(singlechar);    JUMPHERE(singlechar);
2938    }    }
2939  #endif  #endif /* COMPILE_PCRE[8|16] */
2940    #endif /* SUPPORT_UTF && !COMPILE_PCRE32 */
2941  JUMPHERE(start);  JUMPHERE(start);
2942    
2943  if (newlinecheck)  if (newlinecheck)
# Line 2563  if (newlinecheck) Line 2949  if (newlinecheck)
2949  return mainloop;  return mainloop;
2950  }  }
2951    
2952  static SLJIT_INLINE BOOL fast_forward_first_two_chars(compiler_common *common, BOOL firstline)  #define MAX_N_CHARS 3
2953    
2954    static SLJIT_INLINE BOOL fast_forward_first_n_chars(compiler_common *common, BOOL firstline)
2955  {  {
2956  DEFINE_COMPILER;  DEFINE_COMPILER;
2957  struct sljit_label *start;  struct sljit_label *start;
2958  struct sljit_jump *quit;  struct sljit_jump *quit;
2959  struct sljit_jump *found;  pcre_uint32 chars[MAX_N_CHARS * 2];
2960  pcre_int32 chars[4];  pcre_uchar *cc = common->start + 1 + LINK_SIZE;
 pcre_uchar *cc = common->start + 1 + IMM2_SIZE;  
2961  int location = 0;  int location = 0;
2962  pcre_int32 len, c, bit, caseless;  pcre_int32 len, c, bit, caseless;
2963  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  
2964    
2965    /* We do not support alternatives now. */
2966  if (*(common->start + GET(common->start, 1)) == OP_ALT)  if (*(common->start + GET(common->start, 1)) == OP_ALT)
2967    return FALSE;    return FALSE;
2968    
2969  while (TRUE)  while (TRUE)
2970    {    {
2971    caseless = 0;    caseless = 0;
2972    must_end = TRUE;    must_stop = 1;
2973    switch(*cc)    switch(*cc)
2974      {      {
2975      case OP_CHAR:      case OP_CHAR:
2976      must_end = FALSE;      must_stop = 0;
2977      cc++;      cc++;
2978      break;      break;
2979    
2980      case OP_CHARI:      case OP_CHARI:
2981      caseless = 1;      caseless = 1;
2982      must_end = FALSE;      must_stop = 0;
2983      cc++;      cc++;
2984      break;      break;
2985    
# Line 2645  while (TRUE) Line 3021  while (TRUE)
3021      break;      break;
3022    
3023      default:      default:
3024      return FALSE;      must_stop = 2;
3025        break;
3026      }      }
3027    
3028      if (must_stop == 2)
3029          break;
3030    
3031    len = 1;    len = 1;
3032  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3033    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 2670  while (TRUE) Line 3050  while (TRUE)
3050    else    else
3051      caseless = 0;      caseless = 0;
3052    
3053    while (len > 0 && location < 2 * 2)    while (len > 0 && location < MAX_N_CHARS * 2)
3054      {      {
3055      c = *cc;      c = *cc;
3056      bit = 0;      bit = 0;
# Line 2688  while (TRUE) Line 3068  while (TRUE)
3068      cc++;      cc++;
3069      }      }
3070    
3071    if (location == 2 * 2)    if (location >= MAX_N_CHARS * 2 || must_stop != 0)
3072      break;      break;
   else if (must_end)  
     return FALSE;  
3073    }    }
3074    
3075    /* At least two characters are required. */
3076    if (location < 2 * 2)
3077        return FALSE;
3078    
3079  if (firstline)  if (firstline)
3080    {    {
3081    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
3082    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_END, 0);
3083    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));
3084    }    }
3085  else  else
3086    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));
3087    
3088  start = LABEL();  start = LABEL();
3089  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  
   
 #else /* SLJIT_UNALIGNED */  
3090    
3091  #if defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
 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 */  
3092  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3093  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3094  #endif /* SLJIT_BIG_ENDIAN */  if (chars[1] != 0)
3095      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[1]);
3096  #ifdef COMPILE_PCRE8  CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, chars[0], start);
3097  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 8);  if (location > 2 * 2)
3098  #else /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3099  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 16);  if (chars[3] != 0)
3100  #endif    OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, chars[3]);
3101  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, chars[2], start);
3102    if (location > 2 * 2)
3103  #endif    {
3104      if (chars[5] != 0)
3105  if (chars[1] != 0 || chars[3] != 0)      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, chars[5]);
3106    {    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);  
3107    }    }
3108    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3109    
 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);  
3110  JUMPHERE(quit);  JUMPHERE(quit);
3111    
3112  if (firstline)  if (firstline)
3113    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3114  else  else
3115    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));
3116  return TRUE;  return TRUE;
3117  }  }
3118    
3119    #undef MAX_N_CHARS
3120    
3121  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)
3122  {  {
3123  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 2787  if (first_char == oc) Line 3151  if (first_char == oc)
3151  else  else
3152    {    {
3153    bit = first_char ^ oc;    bit = first_char ^ oc;
3154    if (ispowerof2(bit))    if (is_powerof2(bit))
3155      {      {
3156      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
3157      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 2795  else Line 3159  else
3159    else    else
3160      {      {
3161      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);
3162      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3163      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);
3164      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);
3165      found = JUMP(SLJIT_C_NOT_ZERO);      found = JUMP(SLJIT_C_NOT_ZERO);
3166      }      }
3167    }    }
# Line 2839  if (common->nltype == NLTYPE_FIXED && co Line 3203  if (common->nltype == NLTYPE_FIXED && co
3203    
3204    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
3205    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);
3206    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_GREATER_EQUAL);
3207  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3208    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCHAR_SHIFT);
3209  #endif  #endif
3210    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3211    
# Line 2882  if (common->nltype == NLTYPE_ANY || comm Line 3246  if (common->nltype == NLTYPE_ANY || comm
3246    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3247    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3248    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);
3249    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3250  #ifdef COMPILE_PCRE16  #if defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3251    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT);
3252  #endif  #endif
3253    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3254    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
# Line 2897  if (firstline) Line 3261  if (firstline)
3261    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_END, 0, TMP3, 0);
3262  }  }
3263    
3264    static BOOL check_class_ranges(compiler_common *common, const pcre_uint8 *bits, BOOL nclass, jump_list **backtracks);
3265    
3266  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)
3267  {  {
3268  DEFINE_COMPILER;  DEFINE_COMPILER;
3269  struct sljit_label *start;  struct sljit_label *start;
3270  struct sljit_jump *quit;  struct sljit_jump *quit;
3271  struct sljit_jump *found;  struct sljit_jump *found = NULL;
3272    jump_list *matches = NULL;
3273    pcre_uint8 inverted_start_bits[32];
3274    int i;
3275  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3276  struct sljit_jump *jump;  struct sljit_jump *jump;
3277  #endif  #endif
3278    
3279    for (i = 0; i < 32; ++i)
3280      inverted_start_bits[i] = ~(((pcre_uint8*)start_bits)[i]);
3281    
3282  if (firstline)  if (firstline)
3283    {    {
3284    SLJIT_ASSERT(common->first_line_end != 0);    SLJIT_ASSERT(common->first_line_end != 0);
# Line 2921  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P Line 3293  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_P
3293  if (common->utf)  if (common->utf)
3294    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
3295  #endif  #endif
3296    
3297    if (!check_class_ranges(common, inverted_start_bits, (inverted_start_bits[31] & 0x80) != 0, &matches))
3298      {
3299  #ifndef COMPILE_PCRE8  #ifndef COMPILE_PCRE8
3300  jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
3301  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
3302  JUMPHERE(jump);    JUMPHERE(jump);
3303  #endif  #endif
3304  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3305  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3306  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
3307  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3308  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);
3309  found = JUMP(SLJIT_C_NOT_ZERO);    found = JUMP(SLJIT_C_NOT_ZERO);
3310      }
3311    
3312  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
3313  if (common->utf)  if (common->utf)
3314    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
3315  #endif  #endif
3316  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));
3317  #if defined SUPPORT_UTF && defined COMPILE_PCRE8  #ifdef SUPPORT_UTF
3318    #if defined COMPILE_PCRE8
3319  if (common->utf)  if (common->utf)
3320    {    {
3321    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
3322    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);
3323    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3324    }    }
3325  #endif  #elif defined COMPILE_PCRE16
 #if defined SUPPORT_UTF && defined COMPILE_PCRE16  
3326  if (common->utf)  if (common->utf)
3327    {    {
3328    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
3329    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3330    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);
3331    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3332    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3333    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3334    }    }
3335  #endif  #endif /* COMPILE_PCRE[8|16] */
3336    #endif /* SUPPORT_UTF */
3337  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
3338  JUMPHERE(found);  if (found != NULL)
3339      JUMPHERE(found);
3340    if (matches != NULL)
3341      set_jumps(matches, LABEL());
3342  JUMPHERE(quit);  JUMPHERE(quit);
3343    
3344  if (firstline)  if (firstline)
# Line 2974  struct sljit_jump *alreadyfound; Line 3354  struct sljit_jump *alreadyfound;
3354  struct sljit_jump *found;  struct sljit_jump *found;
3355  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
3356  struct sljit_jump *notfound;  struct sljit_jump *notfound;
3357  pcre_uchar oc, bit;  pcre_uint32 oc, bit;
3358    
3359  SLJIT_ASSERT(common->req_char_ptr != 0);  SLJIT_ASSERT(common->req_char_ptr != 0);
3360  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 3005  if (req_char == oc) Line 3385  if (req_char == oc)
3385  else  else
3386    {    {
3387    bit = req_char ^ oc;    bit = req_char ^ oc;
3388    if (ispowerof2(bit))    if (is_powerof2(bit))
3389      {      {
3390      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
3391      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 3041  GET_LOCAL_BASE(TMP3, 0, 0); Line 3421  GET_LOCAL_BASE(TMP3, 0, 0);
3421  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
3422  mainloop = LABEL();  mainloop = LABEL();
3423  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
3424  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);
3425    jump = JUMP(SLJIT_C_SIG_LESS_EQUAL);
3426    
3427  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3428  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));
3429  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));
3430  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));
3431  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3432    
3433  JUMPHERE(jump);  JUMPHERE(jump);
3434  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = JUMP(SLJIT_C_SIG_LESS);
3435  /* End of dropping frames. */  /* End of dropping frames. */
3436  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3437    
3438  JUMPHERE(jump);  JUMPHERE(jump);
3439  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  OP1(SLJIT_NEG, TMP2, 0, TMP2, 0);
3440  /* Set string begin. */  OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP3, 0);
3441  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(TMP1), sizeof(sljit_sw));
3442  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));  
3443  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
3444  }  }
3445    
# Line 3082  static void check_wordboundary(compiler_ Line 3447  static void check_wordboundary(compiler_
3447  {  {
3448  DEFINE_COMPILER;  DEFINE_COMPILER;
3449  struct sljit_jump *skipread;  struct sljit_jump *skipread;
3450    jump_list *skipread_list = NULL;
3451  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
3452  struct sljit_jump *jump;  struct sljit_jump *jump;
3453  #endif  #endif
# Line 3107  if (common->use_ucp) Line 3473  if (common->use_ucp)
3473    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3474    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3475    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);
3476    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3477    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);
3478    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);
3479    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3480    JUMPHERE(jump);    JUMPHERE(jump);
3481    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP2, 0);
3482    }    }
# Line 3139  else Line 3505  else
3505  JUMPHERE(skipread);  JUMPHERE(skipread);
3506    
3507  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
3508  skipread = check_str_end(common);  check_str_end(common, &skipread_list);
3509  peek_char(common);  peek_char(common);
3510    
3511  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
# Line 3151  if (common->use_ucp) Line 3517  if (common->use_ucp)
3517    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3518    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll);
3519    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);
3520    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3521    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);
3522    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);
3523    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3524    JUMPHERE(jump);    JUMPHERE(jump);
3525    }    }
3526  else  else
# Line 3180  else Line 3546  else
3546      JUMPHERE(jump);      JUMPHERE(jump);
3547  #endif /* COMPILE_PCRE8 */  #endif /* COMPILE_PCRE8 */
3548    }    }
3549  JUMPHERE(skipread);  set_jumps(skipread_list, LABEL());
3550    
3551  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);
3552  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 3235  switch(ranges[0]) Line 3601  switch(ranges[0])
3601        }        }
3602      return TRUE;      return TRUE;
3603      }      }
3604    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]))
3605      {      {
3606      if (readch)      if (readch)
3607        read_char(common);        read_char(common);
# Line 3334  sljit_emit_fast_enter(compiler, RETURN_A Line 3700  sljit_emit_fast_enter(compiler, RETURN_A
3700    
3701  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3702  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);
3703  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3704  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);
3705  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3706  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3707  if (common->utf)  if (common->utf)
3708    {    {
3709  #endif  #endif
3710    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3711    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3712    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);
3713  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3714    }    }
3715  #endif  #endif
3716  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3717  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);
3718  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3719  }  }
3720    
# Line 3360  DEFINE_COMPILER; Line 3726  DEFINE_COMPILER;
3726  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0);
3727    
3728  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);
3729  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
3730  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);
3731  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3732  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);
3733  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3734  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3735  if (common->utf)  if (common->utf)
3736    {    {
3737  #endif  #endif
3738    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3739    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);
3740    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3741    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);
3742    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3743    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2000);
3744    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);
3745    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_LESS_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
3746    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);
3747    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3748    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);
3749    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
3750    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);
3751  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3752    }    }
3753  #endif  #endif
3754  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3755  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);
3756    
3757  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3758  }  }
# Line 3400  sljit_emit_fast_enter(compiler, RETURN_A Line 3766  sljit_emit_fast_enter(compiler, RETURN_A
3766    
3767  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
3768  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);
3769  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
3770  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);
3771  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3772  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3773  if (common->utf)  if (common->utf)
3774    {    {
3775  #endif  #endif
3776    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);
3777    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
3778    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);
3779  #ifdef COMPILE_PCRE8  #ifdef COMPILE_PCRE8
3780    }    }
3781  #endif  #endif
3782  #endif /* SUPPORT_UTF || COMPILE_PCRE16 */  #endif /* SUPPORT_UTF || COMPILE_PCRE16 || COMPILE_PCRE32 */
3783  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);
3784    
3785  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
3786  }  }
# Line 3500  sljit_emit_fast_return(compiler, RETURN_ Line 3866  sljit_emit_fast_return(compiler, RETURN_
3866    
3867  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3868    
3869  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)
3870  {  {
3871  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
3872  int c1, c2;  pcre_uint32 c1, c2;
3873  const pcre_uchar *src2 = args->uchar_ptr;  const pcre_uchar *src2 = args->uchar_ptr;
3874  const pcre_uchar *end2 = args->end;  const pcre_uchar *end2 = args->end;
3875    const ucd_record *ur;
3876    const pcre_uint32 *pp;
3877    
3878  while (src1 < end1)  while (src1 < end1)
3879    {    {
# Line 3513  while (src1 < end1) Line 3881  while (src1 < end1)
3881      return (pcre_uchar*)1;      return (pcre_uchar*)1;
3882    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
3883    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
3884    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;    ur = GET_UCD(c2);
3885      if (c1 != c2 && c1 != c2 + ur->other_case)
3886        {
3887        pp = PRIV(ucd_caseless_sets) + ur->caseset;
3888        for (;;)
3889          {
3890          if (c1 < *pp) return NULL;
3891          if (c1 == *pp++) break;
3892          }
3893        }
3894    }    }
3895  return src2;  return src2;
3896  }  }
# Line 3535  if (caseless && char_has_othercase(commo Line 3912  if (caseless && char_has_othercase(commo
3912    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
3913    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
3914    /* Extracting bit difference info. */    /* Extracting bit difference info. */
3915  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3916    othercasechar = cc + (othercasebit >> 8);    othercasechar = cc + (othercasebit >> 8);
3917    othercasebit &= 0xff;    othercasebit &= 0xff;
3918  #else  #elif defined COMPILE_PCRE16 || defined COMPILE_PCRE32
3919  #ifdef COMPILE_PCRE16    /* Note that this code only handles characters in the BMP. If there
3920      ever are characters outside the BMP whose othercase differs in only one
3921      bit from itself (there currently are none), this code will need to be
3922      revised for COMPILE_PCRE32. */
3923    othercasechar = cc + (othercasebit >> 9);    othercasechar = cc + (othercasebit >> 9);
3924    if ((othercasebit & 0x100) != 0)    if ((othercasebit & 0x100) != 0)
3925      othercasebit = (othercasebit & 0xff) << 8;      othercasebit = (othercasebit & 0xff) << 8;
3926    else    else
3927      othercasebit &= 0xff;      othercasebit &= 0xff;
3928  #endif  #endif /* COMPILE_PCRE[8|16|32] */
 #endif  
3929    }    }
3930    
3931  if (context->sourcereg == -1)  if (context->sourcereg == -1)
3932    {    {
3933  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3934  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3935    if (context->length >= 4)    if (context->length >= 4)
3936      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 3560  if (context->sourcereg == -1) Line 3939  if (context->sourcereg == -1)
3939    else    else
3940  #endif  #endif
3941      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3942  #else  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
3943  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3944    if (context->length >= 4)    if (context->length >= 4)
3945      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3946    else    else
3947  #endif  #endif
3948      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3949  #endif  #elif defined COMPILE_PCRE32
3950  #endif /* COMPILE_PCRE8 */    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
3951    #endif /* COMPILE_PCRE[8|16|32] */
3952    context->sourcereg = TMP2;    context->sourcereg = TMP2;
3953    }    }
3954    
# Line 3583  do Line 3962  do
3962  #endif  #endif
3963    
3964    context->length -= IN_UCHARS(1);    context->length -= IN_UCHARS(1);
3965  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if (defined SLJIT_UNALIGNED && SLJIT_UNALIGNED) && (defined COMPILE_PCRE8 || defined COMPILE_PCRE16)
3966    
3967    /* Unaligned read is supported. */    /* Unaligned read is supported. */
3968    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3598  do Line 3977  do
3977      }      }
3978    context->ucharptr++;    context->ucharptr++;
3979    
3980  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8
3981    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))
3982  #else  #else
3983    if (context->ucharptr >= 2 || context->length == 0)    if (context->ucharptr >= 2 || context->length == 0)
# Line 3606  do Line 3985  do
3985      {      {
3986      if (context->length >= 4)      if (context->length >= 4)
3987        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  
3988      else if (context->length >= 2)      else if (context->length >= 2)
3989        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);
3990    #if defined COMPILE_PCRE8
3991      else if (context->length >= 1)      else if (context->length >= 1)
3992        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);
3993  #else  #endif /* COMPILE_PCRE8 */
     else if (context->length >= 2)  
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);  
 #endif  
3994      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
3995    
3996      switch(context->ucharptr)      switch(context->ucharptr)
# Line 3648  do Line 4024  do
4024    
4025  #else  #else
4026    
4027    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported or in 32 bit mode. */
4028  #ifdef COMPILE_PCRE8    if (context->length >= 1)
4029    if (context->length > 0)      OP1(MOV_UCHAR, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
4030      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  
4031    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
4032    
4033    if (othercasebit != 0 && othercasechar == cc)    if (othercasebit != 0 && othercasechar == cc)
# Line 3705  static void compile_xclass_matchingpath( Line 4077  static void compile_xclass_matchingpath(
4077  DEFINE_COMPILER;  DEFINE_COMPILER;
4078  jump_list *found = NULL;  jump_list *found = NULL;
4079  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : backtracks;
4080  unsigned int c;  pcre_int32 c, charoffset;
4081  int compares;  const pcre_uint32 *other_cases;
4082  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4083  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
4084    int compares, invertcmp, numberofcmps;
4085  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
4086  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
4087  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
4088  int typereg = TMP1, scriptreg = TMP1;  int typereg = TMP1, scriptreg = TMP1;
4089  unsigned int typeoffset;  pcre_int32 typeoffset;
4090  #endif  #endif
 int invertcmp, numberofcmps;  
 unsigned int charoffset;  
4091    
4092  /* Although SUPPORT_UTF must be defined, we are  /* Although SUPPORT_UTF must be defined, we are
4093     not necessary in utf mode even in 8 bit mode. */     not necessary in utf mode even in 8 bit mode. */
# Line 3737  if ((*cc++ & XCL_MAP) != 0) Line 4108  if ((*cc++ & XCL_MAP) != 0)
4108      {      {
4109      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);      OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4110      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);      OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4111      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4112      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);      OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4113      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);
4114      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));      add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
# Line 3814  while (*cc != XCL_END) Line 4185  while (*cc != XCL_END)
4185        needschar = TRUE;        needschar = TRUE;
4186        break;        break;
4187    
4188          case PT_CLIST:
4189          case PT_UCNC:
4190          needschar = TRUE;
4191          break;
4192    
4193        default:        default:
4194        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
4195        break;        break;
# Line 3850  if (needstype || needsscript) Line 4226  if (needstype || needsscript)
4226      {      {
4227      if (scriptreg == TMP1)      if (scriptreg == TMP1)
4228        {        {
4229        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));
4230        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
4231        }        }
4232      else      else
4233        {        {
4234        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
4235        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));
4236        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
4237        }        }
4238      }      }
# Line 3892  while (*cc != XCL_END) Line 4268  while (*cc != XCL_END)
4268      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4269        {        {
4270        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);
4271        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);
4272        numberofcmps++;        numberofcmps++;
4273        }        }
4274      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4275        {        {
4276        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);
4277        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);
4278        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4279        numberofcmps = 0;        numberofcmps = 0;
4280        }        }
# Line 3931  while (*cc != XCL_END) Line 4307  while (*cc != XCL_END)
4307      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))      if (numberofcmps < 3 && (*cc == XCL_SINGLE || *cc == XCL_RANGE))
4308        {        {
4309        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);
4310        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);
4311        numberofcmps++;        numberofcmps++;
4312        }        }
4313      else if (numberofcmps > 0)      else if (numberofcmps > 0)
4314        {        {
4315        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);
4316        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);
4317        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4318        numberofcmps = 0;        numberofcmps = 0;
4319        }        }
# Line 3968  while (*cc != XCL_END) Line 4344  while (*cc != XCL_END)
4344    
4345        case PT_LAMP:        case PT_LAMP:
4346        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);
4347        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4348        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);
4349        COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4350        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);
4351        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);
4352        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4353        break;        break;
4354    
# Line 3999  while (*cc != XCL_END) Line 4375  while (*cc != XCL_END)
4375          }          }
4376        SET_CHAR_OFFSET(9);        SET_CHAR_OFFSET(9);
4377        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);
4378        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS_EQUAL);
4379        if (*cc == PT_SPACE)        if (*cc == PT_SPACE)
4380          JUMPHERE(jump);          JUMPHERE(jump);
4381    
4382        SET_TYPE_OFFSET(ucp_Zl);        SET_TYPE_OFFSET(ucp_Zl);
4383        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);
4384        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);
4385        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4386        break;        break;
4387    
4388        case PT_WORD:        case PT_WORD:
4389        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);
4390        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4391        /* ... fall through */        /* Fall through. */
4392    
4393        case PT_ALNUM:        case PT_ALNUM:
4394        SET_TYPE_OFFSET(ucp_Ll);        SET_TYPE_OFFSET(ucp_Ll);
4395        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);
4396        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);
4397        SET_TYPE_OFFSET(ucp_Nd);        SET_TYPE_OFFSET(ucp_Nd);
4398        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);
4399        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);
4400          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4401          break;
4402    
4403          case PT_CLIST:
4404          other_cases = PRIV(ucd_caseless_sets) + cc[1];
4405    
4406          /* At least three characters are required.
4407             Otherwise this case would be handled by the normal code path. */
4408          SLJIT_ASSERT(other_cases[0] != NOTACHAR && other_cases[1] != NOTACHAR && other_cases[2] != NOTACHAR);
4409          SLJIT_ASSERT(other_cases[0] < other_cases[1] && other_cases[1] < other_cases[2]);
4410    
4411          /* Optimizing character pairs, if their difference is power of 2. */
4412          if (is_powerof2(other_cases[1] ^ other_cases[0]))
4413            {
4414            if (charoffset == 0)
4415              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4416            else
4417              {
4418              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4419              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4420              }
4421            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[1]);
4422            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4423            other_cases += 2;
4424            }
4425          else if (is_powerof2(other_cases[2] ^ other_cases[1]))
4426            {
4427            if (charoffset == 0)
4428              OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, other_cases[2] ^ other_cases[1]);
4429            else
4430              {
4431              OP2(SLJIT_ADD, TMP2, 0, TMP1, 0, SLJIT_IMM, (sljit_sw)charoffset);
4432              OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, other_cases[1] ^ other_cases[0]);
4433              }
4434            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, other_cases[2]);
4435            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4436    
4437            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, other_cases[0] - charoffset);
4438            OP_FLAGS(SLJIT_OR | ((other_cases[3] == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4439    
4440            other_cases += 3;
4441            }
4442          else
4443            {
4444            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4445            OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4446            }
4447    
4448          while (*other_cases != NOTACHAR)
4449            {
4450            OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, *other_cases++ - charoffset);
4451            OP_FLAGS(SLJIT_OR | ((*other_cases == NOTACHAR) ? SLJIT_SET_E : 0), TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4452            }
4453          jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4454          break;
4455    
4456          case PT_UCNC:
4457          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_DOLLAR_SIGN - charoffset);
4458          OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4459          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_COMMERCIAL_AT - charoffset);
4460          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4461          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, CHAR_GRAVE_ACCENT - charoffset);
4462          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_EQUAL);
4463    
4464          SET_CHAR_OFFSET(0xa0);
4465          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd7ff - charoffset);
4466          OP_FLAGS(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_C_LESS_EQUAL);
4467          SET_CHAR_OFFSET(0);
4468          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xe000 - 0);
4469          OP_FLAGS(SLJIT_OR | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_C_GREATER_EQUAL);
4470        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);        jump = JUMP(SLJIT_C_NOT_ZERO ^ invertcmp);
4471        break;        break;
4472        }        }
# Line 4048  int length; Line 4494  int length;
4494  unsigned int c, oc, bit;  unsigned int c, oc, bit;
4495  compare_context context;  compare_context context;
4496  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
4497    jump_list *end_list;
4498  #ifdef SUPPORT_UTF  #ifdef SUPPORT_UTF
4499  struct sljit_label *label;  struct sljit_label *label;
4500  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
# Line 4116  switch(type) Line 4563  switch(type)
4563    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
4564      {      {
4565      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);
4566        end_list = NULL;
4567      if (common->mode != JIT_PARTIAL_HARD_COMPILE)      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4568        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));
4569      else      else
4570        jump[1] = check_str_end(common);        check_str_end(common, &end_list);
4571    
4572      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4573      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));
4574      if (jump[1] != NULL)      set_jumps(end_list, LABEL());
       JUMPHERE(jump[1]);  
4575      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4576      }      }
4577    else    else
# Line 4138  switch(type) Line 4585  switch(type)
4585      {      {
4586      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4587      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));
4588  #ifdef COMPILE_PCRE8  #if defined COMPILE_PCRE8 || defined COMPILE_PCRE16
4589    #if defined COMPILE_PCRE8
4590      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4591      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);
4592      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4593  #else /* COMPILE_PCRE8 */  #elif defined COMPILE_PCRE16
 #ifdef COMPILE_PCRE16  
4594      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
4595      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
4596      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);
4597      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4598      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
4599      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4600  #endif /* COMPILE_PCRE16 */  #endif
 #endif /* COMPILE_PCRE8 */  
4601      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
4602    #endif /* COMPILE_PCRE[8|16] */
4603      return cc;      return cc;
4604      }      }
4605  #endif  #endif
# Line 4183  switch(type) Line 4630  switch(type)
4630    read_char(common);    read_char(common);
4631    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);
4632    /* We don't need to handle soft partial matching case. */    /* We don't need to handle soft partial matching case. */
4633      end_list = NULL;
4634    if (common->mode != JIT_PARTIAL_HARD_COMPILE)    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
4635      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));
4636    else    else
4637      jump[1] = check_str_end(common);      check_str_end(common, &end_list);
4638    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
4639    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);
4640    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));
4641    jump[3] = JUMP(SLJIT_JUMP);    jump[2] = JUMP(SLJIT_JUMP);
4642    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4643    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);    check_newlinechar(common, common->bsr_nltype, backtracks, FALSE);
4644      set_jumps(end_list, LABEL());
4645    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
4646    JUMPHERE(jump[2]);    JUMPHERE(jump[2]);
   JUMPHERE(jump[3]);  
4647    return cc;    return cc;
4648    
4649    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
# Line 4219  switch(type) Line 4667  switch(type)
4667    detect_partial_match(common, backtracks);    detect_partial_match(common, backtracks);
4668    read_char(common);    read_char(common);
4669    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4670    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4671    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM2(TMP1, TMP2), 3);    /* Optimize register allocation: use a real register. */
4672      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
4673      OP1(SLJIT_MOV_UB, STACK_TOP, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4674    
4675    label = LABEL();    label = LABEL();
4676    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);
4677    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0);
4678    read_char(common);    read_char(common);
4679    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
4680    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, gbprop));
4681    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM2(TMP1, TMP2), 3);
4682    
4683    OP2(SLJIT_MUL, TMP1, 0, TMP3, 0, SLJIT_IMM, ucp_gbCount);    OP2(SLJIT_SHL, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2);
4684    OP1(SLJIT_MOV, TMP3, 0, TMP2, 0);    OP1(SLJIT_MOV_UI, TMP1, 0, SLJIT_MEM1(STACK_TOP), (sljit_sw)PRIV(ucp_gbtable));
4685    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);    OP1(SLJIT_MOV, STACK_TOP, 0, TMP2, 0);
4686    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(ucp_gbtable));    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
4687    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0, label);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, TMP2, 0);
4688      JUMPTO(SLJIT_C_NOT_ZERO, label);
4689    
4690    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
4691    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
4692      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
4693    
4694    if (common->mode == JIT_PARTIAL_HARD_COMPILE)    if (common->mode == JIT_PARTIAL_HARD_COMPILE)
4695      {      {
4696      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 4261  switch(type) Line 4714  switch(type)
4714        {        {
4715        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);        jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
4716        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);
4717        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);        OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_LESS);
4718        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);
4719        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);
4720        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));        add_jump(compiler, backtracks, JUMP(SLJIT_C_NOT_EQUAL));
4721        check_partial(common, TRUE);        check_partial(common, TRUE);
4722        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));        add_jump(compiler, backtracks, JUMP(SLJIT_JUMP));
# Line 4443  switch(type) Line 4896  switch(type)
4896      }      }
4897    oc = char_othercase(common, c);    oc = char_othercase(common, c);
4898    bit = c ^ oc;    bit = c ^ oc;
4899    if (ispowerof2(bit))    if (is_powerof2(bit))
4900      {      {
4901      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4902      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));
4903      return cc + length;      return cc + length;
4904      }      }
4905    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);
4906    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
4907    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);
4908    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);
4909    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
4910    return cc + length;    return cc + length;
4911    
# Line 4479  switch(type) Line 4932  switch(type)
4932        /* Skip the variable-length character. */        /* Skip the variable-length character. */
4933        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));
4934        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
4935        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);
4936        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
4937        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
4938        return cc + 1;        return cc + 1;
# Line 4504  switch(type) Line 4957  switch(type)
4957      {      {
4958      oc = char_othercase(common, c);      oc = char_othercase(common, c);
4959      bit = c ^ oc;      bit = c ^ oc;
4960      if (ispowerof2(bit))      if (is_powerof2(bit))
4961        {        {
4962        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
4963        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 4542  switch(type) Line 4995  switch(type)
4995  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
4996    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
4997    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
4998    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)cc);
4999    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
5000    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);
5001    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, backtracks, JUMP(SLJIT_C_ZERO));
# Line 4552  switch(type) Line 5005  switch(type)
5005  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
5006    return cc + 32 / sizeof(pcre_uchar);    return cc + 32 / sizeof(pcre_uchar);
5007    
5008  #if defined SUPPORT_UTF || defined COMPILE_PCRE16  #if defined SUPPORT_UTF || defined COMPILE_PCRE16 || defined COMPILE_PCRE32
5009    case OP_XCLASS:    case OP_XCLASS:
5010    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);    compile_xclass_matchingpath(common, cc + LINK_SIZE, backtracks);
5011    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 4666  if (!common->jscript_compat) Line 5119  if (!common->jscript_compat)
5119      {      {
5120      /* OVECTOR(1) contains the "string begin - 1" constant. */      /* OVECTOR(1) contains the "string begin - 1" constant. */
5121      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));
5122      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_UNUSED, 0, SLJIT_C_EQUAL);
5123      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));
5124      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);
5125      return JUMP(SLJIT_C_NOT_ZERO);      return JUMP(SLJIT_C_NOT_ZERO);
5126      }      }
5127    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 4724  if (withchecks && !common->jscript_compa Line 5177  if (withchecks && !common->jscript_compa
5177  #if defined SUPPORT_UTF && defined SUPPORT_UCP  #if defined SUPPORT_UTF && defined SUPPORT_UCP
5178  if (common->utf && *cc == OP_REFI)  if (common->utf && *cc == OP_REFI)
5179    {    {
5180    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);
5181    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));
5182    if (withchecks)    if (withchecks)
5183      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);      jump = CMP(SLJIT_C_EQUAL, TMP1, 0, TMP2, 0);
5184    
5185    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
5186    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5187    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_SCRATCH_REG2, 0, ARGUMENTS, 0);
5188    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);
5189    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));
5190    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5191    if (common->mode == JIT_COMPILE)    if (common->mode == JIT_COMPILE)
# Line 4845  if (!minimize) Line 5298  if (!minimize)
5298      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5299      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), SLJIT_IMM, 0);
5300      /* Temporary release of STR_PTR. */      /* Temporary release of STR_PTR. */
5301      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));
5302      zerolength = compile_ref_checks(common, ccbegin, NULL);      zerolength = compile_ref_checks(common, ccbegin, NULL);
5303      /* Restore if not zero length. */      /* Restore if not zero length. */
5304      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));
5305      }      }
5306    else    else
5307      {      {
# Line 4940  DEFINE_COMPILER; Line 5393  DEFINE_COMPILER;
5393  backtrack_common *backtrack;  backtrack_common *backtrack;
5394  recurse_entry *entry = common->entries;  recurse_entry *entry = common->entries;
5395  recurse_entry *prev = NULL;  recurse_entry *prev = NULL;
5396  int start = GET(cc, 1);  sljit_sw start = GET(cc, 1);
5397    pcre_uchar *start_cc;
5398    BOOL needs_control_head;
5399    
5400  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);  PUSH_BACKTRACK(sizeof(recurse_backtrack), cc, NULL);
5401    
5402    /* Inlining simple patterns. */
5403    if (get_framesize(common, common->start + start, NULL, TRUE, &needs_control_head) == no_stack)
5404      {
5405      start_cc = common->start + start;
5406      compile_matchingpath(common, next_opcode(common, start_cc), bracketend(start_cc) - (1 + LINK_SIZE), backtrack);
5407      BACKTRACK_AS(recurse_backtrack)->inlined_pattern = TRUE;
5408      return cc + 1 + LINK_SIZE;
5409      }
5410    
5411  while (entry != NULL)  while (entry != NULL)
5412    {    {
5413    if (entry->start == start)    if (entry->start == start)
# Line 4991  add_jump(compiler, &backtrack->topbacktr Line 5456  add_jump(compiler, &backtrack->topbacktr
5456  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5457  }  }
5458    
5459    static int SLJIT_CALL do_callout(struct jit_arguments* arguments, PUBL(callout_block) *callout_block, pcre_uchar **jit_ovector)
5460    {
5461    const pcre_uchar *begin = arguments->begin;
5462    int *offset_vector = arguments->offsets;
5463    int offset_count = arguments->offset_count;
5464    int i;
5465    
5466    if (PUBL(callout) == NULL)
5467      return 0;
5468    
5469    callout_block->version = 2;
5470    callout_block->callout_data = arguments->callout_data;
5471    
5472    /* Offsets in subject. */
5473    callout_block->subject_length = arguments->end - arguments->begin;
5474    callout_block->start_match = (pcre_uchar*)callout_block->subject - arguments->begin;
5475    callout_block->current_position = (pcre_uchar*)callout_block->offset_vector - arguments->begin;
5476    #if defined COMPILE_PCRE8
5477    callout_block->subject = (PCRE_SPTR)begin;
5478    #elif defined COMPILE_PCRE16
5479    callout_block->subject = (PCRE_SPTR16)begin;
5480    #elif defined COMPILE_PCRE32
5481    callout_block->subject = (PCRE_SPTR32)begin;
5482    #endif
5483    
5484    /* Convert and copy the JIT offset vector to the offset_vector array. */
5485    callout_block->capture_top = 0;
5486    callout_block->offset_vector = offset_vector;
5487    for (i = 2; i < offset_count; i += 2)
5488      {
5489      offset_vector[i] = jit_ovector[i] - begin;
5490      offset_vector[i + 1] = jit_ovector[i + 1] - begin;
5491      if (jit_ovector[i] >= begin)
5492        callout_block->capture_top = i;
5493      }
5494    
5495    callout_block->capture_top = (callout_block->capture_top >> 1) + 1;
5496    if (offset_count > 0)
5497      offset_vector[0] = -1;
5498    if (offset_count > 1)
5499      offset_vector[1] = -1;
5500    return (*PUBL(callout))(callout_block);
5501    }
5502    
5503    /* Aligning to 8 byte. */
5504    #define CALLOUT_ARG_SIZE \
5505        (((int)sizeof(PUBL(callout_block)) + 7) & ~7)
5506    
5507    #define CALLOUT_ARG_OFFSET(arg) \
5508        (-CALLOUT_ARG_SIZE + SLJIT_OFFSETOF(PUBL(callout_block), arg))
5509    
5510    static SLJIT_INLINE pcre_uchar *compile_callout_matchingpath(compiler_common *common, pcre_uchar *cc, backtrack_common *parent)
5511    {
5512    DEFINE_COMPILER;
5513    backtrack_common *backtrack;
5514    
5515    PUSH_BACKTRACK(sizeof(backtrack_common), cc, NULL);
5516    
5517    allocate_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5518    
5519    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->capture_last_ptr);
5520    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5521    SLJIT_ASSERT(common->capture_last_ptr != 0);
5522    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(callout_number), SLJIT_IMM, cc[1]);
5523    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(capture_last), TMP2, 0);
5524    
5525    /* These pointer sized fields temporarly stores internal variables. */
5526    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5527    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(offset_vector), STR_PTR, 0);
5528    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(subject), TMP2, 0);
5529    
5530    if (common->mark_ptr != 0)
5531      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr));
5532    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(pattern_position), SLJIT_IMM, GET(cc, 2));
5533    OP1(SLJIT_MOV_SI, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(next_item_length), SLJIT_IMM, GET(cc, 2 + LINK_SIZE));
5534    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), CALLOUT_ARG_OFFSET(mark), (common->mark_ptr != 0) ? TMP2 : SLJIT_IMM, 0);
5535    
5536    /* Needed to save important temporary registers. */
5537    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
5538    OP2(SLJIT_SUB, SLJIT_SCRATCH_REG2, 0, STACK_TOP, 0, SLJIT_IMM, CALLOUT_ARG_SIZE);
5539    GET_LOCAL_BASE(SLJIT_SCRATCH_REG3, 0, OVECTOR_START);
5540    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_callout));
5541    OP1(SLJIT_MOV_SI, SLJIT_RETURN_REG, 0, SLJIT_RETURN_REG, 0);
5542    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
5543    free_stack(common, CALLOUT_ARG_SIZE / sizeof(sljit_sw));
5544    
5545    /* Check return value. */
5546    OP2(SLJIT_SUB | SLJIT_SET_S, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
5547    add_jump(compiler, &backtrack->topbacktracks, JUMP(SLJIT_C_SIG_GREATER));
5548    if (common->forced_quit_label == NULL)
5549      add_jump(compiler, &common->forced_quit, JUMP(SLJIT_C_SIG_LESS));
5550    else
5551      JUMPTO(SLJIT_C_SIG_LESS, common->forced_quit_label);
5552    return cc + 2 + 2 * LINK_SIZE;
5553    }
5554    
5555    #undef CALLOUT_ARG_SIZE
5556    #undef CALLOUT_ARG_OFFSET
5557    
5558  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)
5559  {  {
5560  DEFINE_COMPILER;  DEFINE_COMPILER;
5561  int framesize;  int framesize;
5562    int extrasize;
5563    BOOL needs_control_head;
5564  int private_data_ptr;  int private_data_ptr;
5565  backtrack_common altbacktrack;  backtrack_common altbacktrack;
5566  pcre_uchar *ccbegin;  pcre_uchar *ccbegin;
# Line 5004  jump_list *tmp = NULL; Line 5570  jump_list *tmp = NULL;
5570  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;  jump_list **target = (conditional) ? &backtrack->condfailed : &backtrack->common.topbacktracks;
5571  jump_list **found;  jump_list **found;
5572  /* Saving previous accept variables. */  /* Saving previous accept variables. */
5573  struct sljit_label *save_quitlabel = common->quitlabel;  BOOL save_local_exit = common->local_exit;
5574  struct sljit_label *save_acceptlabel = common->acceptlabel;  then_trap_backtrack *save_then_trap = common->then_trap;
5575    struct sljit_label *save_quit_label = common->quit_label;
5576    struct sljit_label *save_accept_label = common->accept_label;
5577  jump_list *save_quit = common->quit;  jump_list *save_quit = common->quit;
5578  jump_list *save_accept = common->accept;  jump_list *save_accept = common->accept;
5579  struct sljit_jump *jump;  struct sljit_jump *jump;
5580  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5581    
5582    /* Assert captures then. */
5583    common->then_trap = NULL;
5584    
5585  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
5586    {    {
5587    SLJIT_ASSERT(!conditional);    SLJIT_ASSERT(!conditional);
# Line 5019  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 5590  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
5590    }    }
5591  private_data_ptr = PRIVATE_DATA(cc);  private_data_ptr = PRIVATE_DATA(cc);
5592  SLJIT_ASSERT(private_data_ptr != 0);  SLJIT_ASSERT(private_data_ptr != 0);
5593  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, NULL, FALSE, &needs_control_head);
5594  backtrack->framesize = framesize;  backtrack->framesize = framesize;
5595  backtrack->private_data_ptr = private_data_ptr;  backtrack->private_data_ptr = private_data_ptr;
5596  opcode = *cc;  opcode = *cc;
# Line 5038  if (bra == OP_BRAMINZERO) Line 5609  if (bra == OP_BRAMINZERO)
5609    
5610  if (framesize < 0)  if (framesize < 0)
5611    {    {
5612    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);    extrasize = needs_control_head ? 2 : 1;
5613    allocate_stack(common, 1);    if (framesize == no_frame)
5614        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, STACK_TOP, 0);
5615      allocate_stack(common, extrasize);
5616      if (needs_control_head)
5617        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5618    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5619      if (needs_control_head)
5620        {
5621        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5622        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5623        }
5624    }    }
5625  else  else
5626    {    {
5627    allocate_stack(common, framesize + 2);    extrasize = needs_control_head ? 3 : 2;
5628      allocate_stack(common, framesize + extrasize);
5629    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5630    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, -STACK(framesize + 1));    OP2(SLJIT_SUB, TMP2, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5631    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP2, 0);
5632      if (needs_control_head)
5633        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr);
5634    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5635    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);    if (needs_control_head)
5636    init_frame(common, ccbegin, framesize + 1, 2, FALSE);      {
5637        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
5638        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
5639        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_IMM, 0);
5640        }
5641      else
5642        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
5643      init_frame(common, ccbegin, NULL, framesize + extrasize - 1, extrasize, FALSE);
5644    }    }
5645    
5646  memset(&altbacktrack, 0, sizeof(backtrack_common));  memset(&altbacktrack, 0, sizeof(backtrack_common));
5647  common->quitlabel = NULL;  common->local_exit = TRUE;
5648    common->quit_label = NULL;
5649  common->quit = NULL;  common->quit = NULL;
5650  while (1)  while (1)
5651    {    {
5652    common->acceptlabel = NULL;    common->accept_label = NULL;
5653    common->accept = NULL;    common->accept = NULL;
5654    altbacktrack.top = NULL;    altbacktrack.top = NULL;
5655    altbacktrack.topbacktracks = NULL;    altbacktrack.topbacktracks = NULL;
# Line 5070  while (1) Line 5661  while (1)
5661    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);    compile_matchingpath(common, ccbegin + 1 + LINK_SIZE, cc, &altbacktrack);
5662    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5663      {      {
5664      common->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5665      common->acceptlabel = save_acceptlabel;      common->then_trap = save_then_trap;
5666        common->quit_label = save_quit_label;
5667        common->accept_label = save_accept_label;
5668      common->quit = save_quit;      common->quit = save_quit;
5669      common->accept = save_accept;      common->accept = save_accept;
5670      return NULL;      return NULL;
5671      }      }
5672    common->acceptlabel = LABEL();    common->accept_label = LABEL();
5673    if (common->accept != NULL)    if (common->accept != NULL)
5674      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->accept_label);
5675    
5676    /* Reset stack. */    /* Reset stack. */
5677    if (framesize < 0)    if (framesize < 0)
5678      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);      {
5679    else {      if (framesize == no_frame)
5680          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5681        else
5682          free_stack(common, extrasize);
5683        if (needs_control_head)
5684          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5685        }
5686      else
5687        {
5688      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)      if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
5689        {        {
5690        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5691        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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));
5692          if (needs_control_head)
5693            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), 0);
5694        }        }
5695      else      else
5696        {        {
5697        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5698          if (needs_control_head)
5699            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_sw));
5700        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5701        }        }
5702    }      }
5703    
5704    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
5705      {      {
5706      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5707      if (conditional)      if (conditional)
5708        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), needs_control_head ? sizeof(sljit_sw) : 0);
5709      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
5710        {        {
5711        if (framesize < 0)        if (framesize < 0)
5712          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5713        else        else
5714          {          {
5715          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5716          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + extrasize - 1) * sizeof(sljit_sw));
5717          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5718          }          }
5719        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));
5720        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5721        }        }
5722      else if (framesize >= 0)      else if (framesize >= 0)
5723        {        {
5724        /* For OP_BRA and OP_BRAMINZERO. */        /* For OP_BRA and OP_BRAMINZERO. */
5725        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5726        }        }
5727      }      }
5728    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 5125  while (1) Line 5730  while (1)
5730    compile_backtrackingpath(common, altbacktrack.top);    compile_backtrackingpath(common, altbacktrack.top);
5731    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))    if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
5732      {      {
5733      common->quitlabel = save_quitlabel;      common->local_exit = save_local_exit;
5734      common->acceptlabel = save_acceptlabel;      common->then_trap = save_then_trap;
5735        common->quit_label = save_quit_label;
5736        common->accept_label = save_accept_label;
5737      common->quit = save_quit;      common->quit = save_quit;
5738      common->accept = save_accept;      common->accept = save_accept;
5739      return NULL;      return NULL;
# Line 5139  while (1) Line 5746  while (1)
5746    ccbegin = cc;    ccbegin = cc;
5747    cc += GET(cc, 1);    cc += GET(cc, 1);
5748    }    }
5749    
5750  /* None of them matched. */  /* None of them matched. */
5751  if (common->quit != NULL)  if (common->quit != NULL)
5752      {
5753      jump = JUMP(SLJIT_JUMP);
5754    set_jumps(common->quit, LABEL());    set_jumps(common->quit, LABEL());
5755      SLJIT_ASSERT(framesize != no_stack);
5756      if (framesize < 0)
5757        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, extrasize * sizeof(sljit_sw));
5758      else
5759        {
5760        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5761        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5762        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + extrasize) * sizeof(sljit_sw));
5763        }
5764      JUMPHERE(jump);
5765      }
5766    
5767    if (needs_control_head)
5768      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->control_head_ptr, SLJIT_MEM1(STACK_TOP), STACK(1));
5769    
5770  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)  if (opcode == OP_ASSERT || opcode == OP_ASSERTBACK)
5771    {    {
# Line 5153  if (opcode == OP_ASSERT || opcode == OP_ Line 5777  if (opcode == OP_ASSERT || opcode == OP_
5777      {      {
5778      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5779      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5780          {
5781          if (extrasize == 2)
5782            free_stack(common, 1);
5783        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5784          }
5785      else      else
5786        free_stack(common, 1);        free_stack(common, extrasize);
5787      }      }
5788    else    else
5789      {      {
5790      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5791      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5792      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5793        {        {
5794        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5795        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5796        }        }
5797      else      else
5798        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5799      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5800      }      }
5801    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
# Line 5179  if (opcode == OP_ASSERT || opcode == OP_ Line 5807  if (opcode == OP_ASSERT || opcode == OP_
5807    if (framesize < 0)    if (framesize < 0)
5808      {      {
5809      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
5810      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 1) * sizeof(sljit_sw));
5811      /* Keep the STR_PTR on the top of the stack. */      /* Keep the STR_PTR on the top of the stack. */
5812      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
5813        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        {
5814          OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_sw));
5815          if (extrasize == 2)
5816            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
5817          }
5818      else if (bra == OP_BRAMINZERO)      else if (bra == OP_BRAMINZERO)
5819        {        {
5820        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));
5821        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5822        }        }
5823      }      }
# Line 5194  if (opcode == OP_ASSERT || opcode == OP_ Line 5826  if (opcode == OP_ASSERT || opcode == OP_
5826      if (bra == OP_BRA)      if (bra == OP_BRA)
5827        {        {
5828        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5829        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, 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));
5830        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (extrasize - 2) * sizeof(sljit_sw));
5831        }        }
5832      else      else
5833        {        {
5834        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */        /* We don't need to keep the STR_PTR, only the previous private_data_ptr. */
5835        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_sw));
5836        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));        if (extrasize == 2)
5837        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);          {
5838            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5839            if (bra == OP_BRAMINZERO)
5840              OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5841            }
5842          else
5843            {
5844            OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
5845            OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
5846            }
5847        }        }
5848      }      }
5849    
5850    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
5851      {      {
5852      backtrack->matchingpath = LABEL();      backtrack->matchingpath = LABEL();
5853      sljit_set_label(jump, backtrack->matchingpath);      SET_LABEL(jump, backtrack->matchingpath);
5854      }      }
5855    else if (bra == OP_BRAMINZERO)    else if (bra == OP_BRAMINZERO)
5856      {      {
# Line 5219  if (opcode == OP_ASSERT || opcode == OP_ Line 5860  if (opcode == OP_ASSERT || opcode == OP_
5860        {        {
5861        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr);
5862        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5863        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_sw));
5864        }        }
5865      set_jumps(backtrack->common.topbacktracks, LABEL());      set_jumps(backtrack->common.topbacktracks, LABEL());
5866      }      }
# Line 5231  else Line 5872  else
5872      {      {
5873      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5874      if (bra != OP_BRA)      if (bra != OP_BRA)
5875          {
5876          if (extrasize == 2)
5877            free_stack(common, 1);
5878        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5879          }
5880      else      else
5881        free_stack(common, 1);        free_stack(common, extrasize);
5882      }      }
5883    else    else
5884      {      {
5885      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5886      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(extrasize - 1));
5887      /* The topmost item should be 0. */      /* The topmost item should be 0. */
5888      if (bra != OP_BRA)      if (bra != OP_BRA)
5889        {        {
5890        free_stack(common, framesize + 1);        free_stack(common, framesize + extrasize - 1);
5891        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5892        }        }
5893      else      else
5894        free_stack(common, framesize + 2);        free_stack(common, framesize + extrasize);
5895      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), private_data_ptr, TMP1, 0);
5896      }      }
5897    
# Line 5266  else Line 5911  else
5911      }      }
5912    }    }
5913    
5914  common->quitlabel = save_quitlabel;  common->local_exit = save_local_exit;
5915  common->acceptlabel = save_acceptlabel;  common->then_trap = save_then_trap;
5916    common->quit_label = save_quit_label;
5917    common->accept_label = save_accept_label;
5918  common->quit = save_quit;  common->quit = save_quit;
5919  common->accept = save_accept;  common->accept = save_accept;
5920  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5921  }  }
5922    
5923  static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)  static sljit_sw SLJIT_CALL do_searchovector(sljit_uw refno, sljit_sw* locals, pcre_uchar *name_table)
5924  {  {
5925  int condition = FALSE;  int condition = FALSE;
5926  pcre_uchar *slotA = name_table;  pcre_uchar *slotA = name_table;
5927  pcre_uchar *slotB;  pcre_uchar *slotB;
5928  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_sw name_count = locals[LOCALS0 / sizeof(sljit_sw)];
5929  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_sw name_entry_size = locals[LOCALS1 / sizeof(sljit_sw)];
5930  sljit_w no_capture;  sljit_sw no_capture;
5931  int i;  int i;
5932    
5933  locals += refno & 0xff;  locals += refno & 0xff;
# Line 5330  if (i < name_count) Line 5977  if (i < name_count)