/[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 708 by ph10, Fri Sep 23 11:03:03 2011 UTC revision 915 by zherczeg, Tue Feb 14 13:05:39 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_functions {
166    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
167    pcre_jit_callback callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170    } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 194  typedef struct fallback_common { Line 198  typedef struct fallback_common {
198    struct fallback_common *top;    struct fallback_common *top;
199    jump_list *topfallbacks;    jump_list *topfallbacks;
200    /* Opcode pointer. */    /* Opcode pointer. */
201    uschar *cc;    pcre_uchar *cc;
202  } fallback_common;  } fallback_common;
203    
204  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 265  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
269    
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    uschar *start;    pcre_uchar *start;
273    int localsize;    int localsize;
274    int *localptrs;    int *localptrs;
275    const uschar *fcc;    const pcre_uint8 *fcc;
276    sljit_w lcc;    sljit_w lcc;
277    int cbraptr;    int cbraptr;
278      int mode;
279    int nltype;    int nltype;
280    int newline;    int newline;
281    int bsr_nltype;    int bsr_nltype;
282    int endonly;    int endonly;
283    sljit_w ctypes;    sljit_w ctypes;
284      sljit_uw name_table;
285      sljit_w name_count;
286      sljit_w name_entry_size;
287      struct sljit_label *partialmatchlabel;
288    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
289    stub_list *stubs;    stub_list *stubs;
290    recurse_entry *entries;    recurse_entry *entries;
291    recurse_entry *currententry;    recurse_entry *currententry;
292      jump_list *partialmatch;
293    jump_list *accept;    jump_list *accept;
294    jump_list *calllimit;    jump_list *calllimit;
295    jump_list *stackalloc;    jump_list *stackalloc;
# Line 291  typedef struct compiler_common { Line 301  typedef struct compiler_common {
301    jump_list *casefulcmp;    jump_list *casefulcmp;
302    jump_list *caselesscmp;    jump_list *caselesscmp;
303    BOOL jscript_compat;    BOOL jscript_compat;
304  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
305    BOOL utf8;    BOOL utf;
306  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
307    BOOL useucp;    BOOL use_ucp;
308  #endif  #endif
309    jump_list *utf8readchar;    jump_list *utfreadchar;
310    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
311      jump_list *utfreadtype8;
312  #endif  #endif
313    #endif /* SUPPORT_UTF */
314  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
315    jump_list *getucd;    jump_list *getucd;
316  #endif  #endif
# Line 310  typedef struct compare_context { Line 322  typedef struct compare_context {
322    int length;    int length;
323    int sourcereg;    int sourcereg;
324  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
325    int byteptr;    int ucharptr;
326    union {    union {
327      int asint;      sljit_i asint;
328      short asshort;      sljit_uh asushort;
329    #ifdef COMPILE_PCRE8
330      sljit_ub asbyte;      sljit_ub asbyte;
331      sljit_ub asbytes[4];      sljit_ub asuchars[4];
332    #else
333    #ifdef COMPILE_PCRE16
334        sljit_uh asuchars[2];
335    #endif
336    #endif
337    } c;    } c;
338    union {    union {
339      int asint;      sljit_i asint;
340      short asshort;      sljit_uh asushort;
341    #ifdef COMPILE_PCRE8
342      sljit_ub asbyte;      sljit_ub asbyte;
343      sljit_ub asbytes[4];      sljit_ub asuchars[4];
344    #else
345    #ifdef COMPILE_PCRE16
346        sljit_uh asuchars[2];
347    #endif
348    #endif
349    } oc;    } oc;
350  #endif  #endif
351  } compare_context;  } compare_context;
# Line 331  enum { Line 355  enum {
355    frame_setstrbegin = -1    frame_setstrbegin = -1
356  };  };
357    
358    /* Undefine sljit macros. */
359    #undef CMP
360    
361  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
362  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
363    
364  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
365  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
366  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
367  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
368  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
369  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
370  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
371  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
372  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
373  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
374    
375  /* Locals layout. */  /* Locals layout. */
# Line 352  enum { Line 379  enum {
379  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
380  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
381  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
382  /* Head of the last recursion. */  /* Head of the last recursion. */
383  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
384  /* Max limit of recursions. */  /* Max limit of recursions. */
385  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
386  /* Last known position of the requested byte. */  /* Last known position of the requested byte.
387  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  Same as START_USED_PTR. (Partial matching and req_char are exclusive) */
388    #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
389    /* First inspected character for partial matching.
390    Same as REQ_CHAR_PTR. (Partial matching and req_char are exclusive) */
391    #define START_USED_PTR   (6 * sizeof(sljit_w))
392    /* Starting pointer for partial soft matches. */
393    #define HIT_START        (8 * sizeof(sljit_w))
394  /* End pointer of the first line. */  /* End pointer of the first line. */
395  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (9 * sizeof(sljit_w))
396  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
# Line 369  the start pointers when the end of the c Line 400  the start pointers when the end of the c
400  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (10 * sizeof(sljit_w))
401  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
402  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
403  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
404    
405    #ifdef COMPILE_PCRE8
406    #define MOV_UCHAR  SLJIT_MOV_UB
407    #define MOVU_UCHAR SLJIT_MOVU_UB
408    #else
409    #ifdef COMPILE_PCRE16
410    #define MOV_UCHAR  SLJIT_MOV_UH
411    #define MOVU_UCHAR SLJIT_MOVU_UH
412    #else
413    #error Unsupported compiling mode
414    #endif
415    #endif
416    
417  /* Shortcuts. */  /* Shortcuts. */
418  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 393  the start pointers when the end of the c Line 436  the start pointers when the end of the c
436  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
437    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
438    
439  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
440  {  {
441  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
442  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 414  return cc; Line 457  return cc;
457   compile_fallbackpath   compile_fallbackpath
458  */  */
459    
460  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
461  {  {
462  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
463  switch(*cc)  switch(*cc)
# Line 469  switch(*cc) Line 512  switch(*cc)
512    case OP_SKIPZERO:    case OP_SKIPZERO:
513    return cc + 1;    return cc + 1;
514    
515      case OP_ANYBYTE:
516    #ifdef SUPPORT_UTF
517      if (common->utf) return NULL;
518    #endif
519      return cc + 1;
520    
521    case OP_CHAR:    case OP_CHAR:
522    case OP_CHARI:    case OP_CHARI:
523    case OP_NOT:    case OP_NOT:
524    case OP_NOTI:    case OP_NOTI:
   
525    case OP_STAR:    case OP_STAR:
526    case OP_MINSTAR:    case OP_MINSTAR:
527    case OP_PLUS:    case OP_PLUS:
# Line 511  switch(*cc) Line 559  switch(*cc)
559    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
560    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
561    cc += 2;    cc += 2;
562  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
563    if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
564  #endif  #endif
565    return cc;    return cc;
566    
# Line 532  switch(*cc) Line 580  switch(*cc)
580    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
581    case OP_NOTEXACTI:    case OP_NOTEXACTI:
582    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
583    cc += 4;    cc += 2 + IMM2_SIZE;
584  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
585    if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
586  #endif  #endif
587    return cc;    return cc;
588    
589    case OP_NOTPROP:    case OP_NOTPROP:
590    case OP_PROP:    case OP_PROP:
591      return cc + 1 + 2;
592    
593    case OP_TYPEUPTO:    case OP_TYPEUPTO:
594    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
595    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 547  switch(*cc) Line 597  switch(*cc)
597    case OP_REF:    case OP_REF:
598    case OP_REFI:    case OP_REFI:
599    case OP_CREF:    case OP_CREF:
600      case OP_NCREF:
601      case OP_RREF:
602      case OP_NRREF:
603    case OP_CLOSE:    case OP_CLOSE:
604    cc += 3;    cc += 1 + IMM2_SIZE;
605    return cc;    return cc;
606    
607    case OP_CRRANGE:    case OP_CRRANGE:
608    case OP_CRMINRANGE:    case OP_CRMINRANGE:
609    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
610    
611    case OP_CLASS:    case OP_CLASS:
612    case OP_NCLASS:    case OP_NCLASS:
613    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
614    
615  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
616    case OP_XCLASS:    case OP_XCLASS:
617    return cc + GET(cc, 1);    return cc + GET(cc, 1);
618  #endif  #endif
# Line 571  switch(*cc) Line 624  switch(*cc)
624    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
625    case OP_REVERSE:    case OP_REVERSE:
626    case OP_ONCE:    case OP_ONCE:
627      case OP_ONCE_NC:
628    case OP_BRA:    case OP_BRA:
629    case OP_BRAPOS:    case OP_BRAPOS:
630    case OP_COND:    case OP_COND:
# Line 588  switch(*cc) Line 642  switch(*cc)
642    case OP_CBRAPOS:    case OP_CBRAPOS:
643    case OP_SCBRA:    case OP_SCBRA:
644    case OP_SCBRAPOS:    case OP_SCBRAPOS:
645    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
646    
647    default:    default:
648    return NULL;    return NULL;
649    }    }
650  }  }
651    
652  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
653  {  {
654  int localspace = 0;  int localspace = 0;
655  uschar *alternative;  pcre_uchar *alternative;
656  /* 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. */
657  while (cc < ccend)  while (cc < ccend)
658    {    {
# Line 609  while (cc < ccend) Line 663  while (cc < ccend)
663      case OP_ASSERTBACK:      case OP_ASSERTBACK:
664      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
665      case OP_ONCE:      case OP_ONCE:
666        case OP_ONCE_NC:
667      case OP_BRAPOS:      case OP_BRAPOS:
668      case OP_SBRA:      case OP_SBRA:
669      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 620  while (cc < ccend) Line 675  while (cc < ccend)
675      case OP_CBRAPOS:      case OP_CBRAPOS:
676      case OP_SCBRAPOS:      case OP_SCBRAPOS:
677      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
678      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
679      break;      break;
680    
681      case OP_COND:      case OP_COND:
# Line 641  while (cc < ccend) Line 696  while (cc < ccend)
696  return localspace;  return localspace;
697  }  }
698    
699  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
700  {  {
701  uschar *cc = common->start;  pcre_uchar *cc = common->start;
702  uschar *alternative;  pcre_uchar *alternative;
703  while (cc < ccend)  while (cc < ccend)
704    {    {
705    switch(*cc)    switch(*cc)
# Line 654  while (cc < ccend) Line 709  while (cc < ccend)
709      case OP_ASSERTBACK:      case OP_ASSERTBACK:
710      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
711      case OP_ONCE:      case OP_ONCE:
712        case OP_ONCE_NC:
713      case OP_BRAPOS:      case OP_BRAPOS:
714      case OP_SBRA:      case OP_SBRA:
715      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 667  while (cc < ccend) Line 723  while (cc < ccend)
723      case OP_SCBRAPOS:      case OP_SCBRAPOS:
724      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
725      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
726      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
727      break;      break;
728    
729      case OP_COND:      case OP_COND:
# Line 690  while (cc < ccend) Line 746  while (cc < ccend)
746  }  }
747    
748  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
749  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
750  {  {
751  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
752  int length = 0;  int length = 0;
753  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
754  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
755    
756  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
# Line 720  while (cc < ccend) Line 774  while (cc < ccend)
774      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
775      break;      break;
776    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
       {  
       cc = bracketend(cc);  
       break;  
       }  
     /* Check whether a frame must be created. */  
     end = bracketend(cc);  
     while (cc < end)  
       {  
       if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS  
           || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)  
         needs_frame = TRUE;  
       cc = next_opcode(common, cc);  
       SLJIT_ASSERT(cc != NULL);  
       }  
     break;  
   
777      case OP_CBRA:      case OP_CBRA:
778      case OP_CBRAPOS:      case OP_CBRAPOS:
779      case OP_SCBRA:      case OP_SCBRA:
780      case OP_SCBRAPOS:      case OP_SCBRAPOS:
781      length += 3;      length += 3;
782      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
783      break;      break;
784    
785      default:      default:
# Line 757  while (cc < ccend) Line 789  while (cc < ccend)
789      }      }
790    
791  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
792  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
793    return -1;    return -1;
794    
795  if (length > 0)  if (length > 0)
796    return length + 2;    return length + 1;
797  return needs_frame ? 0 : -1;  return -1;
798  }  }
799    
800  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
801  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
802  DEFINE_COMPILER;  DEFINE_COMPILER;
803  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
804  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
805  int offset;  int offset;
806    
807  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
808    {  SLJIT_UNUSED_ARG(stacktop);
809    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
810    
811  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacktop), TMP1, 0);  
   
812  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
813    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
814  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 804  while (cc < ccend) Line 829  while (cc < ccend)
829      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
830      break;      break;
831    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
832      case OP_CBRA:      case OP_CBRA:
833      case OP_CBRAPOS:      case OP_CBRAPOS:
834      case OP_SCBRA:      case OP_SCBRA:
# Line 826  while (cc < ccend) Line 843  while (cc < ccend)
843      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
844      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
845    
846      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
847      break;      break;
848    
849      default:      default:
# Line 836  while (cc < ccend) Line 853  while (cc < ccend)
853      }      }
854    
855  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
856  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
857  }  }
858    
859  static SLJIT_INLINE int get_localsize(compiler_common *common, uschar *cc, uschar *ccend)  static SLJIT_INLINE int get_localsize(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
860  {  {
861  int localsize = 2;  int localsize = 2;
862  uschar *alternative;  pcre_uchar *alternative;
863  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
864  while (cc < ccend)  while (cc < ccend)
865    {    {
# Line 853  while (cc < ccend) Line 870  while (cc < ccend)
870      case OP_ASSERTBACK:      case OP_ASSERTBACK:
871      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
872      case OP_ONCE:      case OP_ONCE:
873        case OP_ONCE_NC:
874      case OP_BRAPOS:      case OP_BRAPOS:
875      case OP_SBRA:      case OP_SBRA:
876      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 864  while (cc < ccend) Line 882  while (cc < ccend)
882      case OP_CBRA:      case OP_CBRA:
883      case OP_SCBRA:      case OP_SCBRA:
884      localsize++;      localsize++;
885      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
886      break;      break;
887    
888      case OP_CBRAPOS:      case OP_CBRAPOS:
889      case OP_SCBRAPOS:      case OP_SCBRAPOS:
890      localsize += 2;      localsize += 2;
891      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
892      break;      break;
893    
894      case OP_COND:      case OP_COND:
# Line 891  SLJIT_ASSERT(cc == ccend); Line 909  SLJIT_ASSERT(cc == ccend);
909  return localsize;  return localsize;
910  }  }
911    
912  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
913    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
914  {  {
915  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 900  int count; Line 918  int count;
918  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
919  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
920  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
921  uschar *alternative;  pcre_uchar *alternative;
922  enum {  enum {
923    start,    start,
924    loop,    loop,
# Line 955  while (status != end) Line 973  while (status != end)
973        case OP_ASSERTBACK:        case OP_ASSERTBACK:
974        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
975        case OP_ONCE:        case OP_ONCE:
976          case OP_ONCE_NC:
977        case OP_BRAPOS:        case OP_BRAPOS:
978        case OP_SBRA:        case OP_SBRA:
979        case OP_SBRAPOS:        case OP_SBRAPOS:
980        case OP_SCOND:        case OP_SCOND:
981        count = 1;        count = 1;
982        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
983        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
984        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
985        break;        break;
# Line 969  while (status != end) Line 988  while (status != end)
988        case OP_SCBRA:        case OP_SCBRA:
989        count = 1;        count = 1;
990        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
991        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
992        break;        break;
993    
994        case OP_CBRAPOS:        case OP_CBRAPOS:
995        case OP_SCBRAPOS:        case OP_SCBRAPOS:
996        count = 2;        count = 2;
997        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
998        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
999        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1000        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1001        break;        break;
1002    
1003        case OP_COND:        case OP_COND:
# Line 987  while (status != end) Line 1006  while (status != end)
1006        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1007          {          {
1008          count = 1;          count = 1;
1009          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1010          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1011          }          }
1012        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1195  struct sljit_label *loop; Line 1214  struct sljit_label *loop;
1214  int i;  int i;
1215  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1216  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1217  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
1218  if (length < 8)  if (length < 8)
1219    {    {
1220    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1219  struct sljit_label *loop; Line 1238  struct sljit_label *loop;
1238  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1239    
1240  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1241  OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1242  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);
1243    
1244  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1245  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));  OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1246  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, offsets), SLJIT_IMM, sizeof(int));
1247  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1248  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
1249  /* Unlikely, but possible */  /* Unlikely, but possible */
1250  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1251  loop = LABEL();  loop = LABEL();
1252  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1253  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1254  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1255  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1256    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1257    #endif
1258    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1259  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1260  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1261  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1244  if (topbracket > 1) Line 1266  if (topbracket > 1)
1266    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));    OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1267    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1268    
1269    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1270    loop = LABEL();    loop = LABEL();
1271    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * sizeof(sljit_w)));    OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1272    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1273    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);    CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1274    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1275    }    }
1276  else  else
1277    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1278  }  }
1279    
1280  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1281    {
1282    DEFINE_COMPILER;
1283    
1284    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1285    
1286    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1287    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1288    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1289    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1290    
1291    /* Store match begin and end. */
1292    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1293    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1294    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? START_USED_PTR : HIT_START);
1295    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1296    #ifdef COMPILE_PCRE16
1297    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1298    #endif
1299    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1300    
1301    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1302    #ifdef COMPILE_PCRE16
1303    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1304    #endif
1305    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1306    
1307    JUMPTO(SLJIT_JUMP, leave);
1308    }
1309    
1310    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1311    {
1312    /* May destroy TMP1. */
1313    DEFINE_COMPILER;
1314    struct sljit_jump *jump;
1315    
1316    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1317      {
1318      /* The value of -1 must be kept for START_USED_PTR! */
1319      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, 1);
1320      /* Jumps if START_USED_PTR < STR_PTR, or START_USED_PTR == -1. Although overwriting
1321      is not necessary if START_USED_PTR == STR_PTR, it does not hurt as well. */
1322      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1323      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1324      JUMPHERE(jump);
1325      }
1326    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1327      {
1328      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1329      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1330      JUMPHERE(jump);
1331      }
1332    }
1333    
1334    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1335  {  {
1336  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1337  unsigned int c;  unsigned int c;
1338    
1339  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1340  if (common->utf8)  if (common->utf)
1341    {    {
1342    GETCHAR(c, cc);    GETCHAR(c, cc);
1343    if (c > 127)    if (c > 127)
# Line 1272  if (common->utf8) Line 1348  if (common->utf8)
1348      return FALSE;      return FALSE;
1349  #endif  #endif
1350      }      }
1351    #ifndef COMPILE_PCRE8
1352      return common->fcc[c] != c;
1353    #endif
1354    }    }
1355  else  else
1356  #endif  #endif
1357    c = *cc;    c = *cc;
1358  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1359  }  }
1360    
1361  static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)  static SLJIT_INLINE unsigned int char_othercase(compiler_common *common, unsigned int c)
1362  {  {
1363  /* Returns with the othercase. */  /* Returns with the othercase. */
1364  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1365  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1366    {    {
1367  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1368    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1292  if (common->utf8 && c > 127) Line 1371  if (common->utf8 && c > 127)
1371  #endif  #endif
1372    }    }
1373  #endif  #endif
1374  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1375  }  }
1376    
1377  static unsigned int char_get_othercase_bit(compiler_common *common, uschar* cc)  static unsigned int char_get_othercase_bit(compiler_common *common, pcre_uchar* cc)
1378  {  {
1379  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1380  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1381  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1382  int n;  int n;
1383  #endif  #endif
1384    
1385  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1386  if (common->utf8)  if (common->utf)
1387    {    {
1388    GETCHAR(c, cc);    GETCHAR(c, cc);
1389    if (c <= 127)    if (c <= 127)
# Line 1321  if (common->utf8) Line 1400  if (common->utf8)
1400  else  else
1401    {    {
1402    c = *cc;    c = *cc;
1403    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1404    }    }
1405  #else  #else
1406  c = *cc;  c = *cc;
1407  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1408  #endif  #endif
1409    
1410  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1339  if (c <= 127 && bit == 0x20) Line 1418  if (c <= 127 && bit == 0x20)
1418  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1419    return 0;    return 0;
1420    
1421  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1422  if (common->utf8 && c > 127)  
1423    #ifdef SUPPORT_UTF
1424    if (common->utf && c > 127)
1425    {    {
1426    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1427    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1428      {      {
1429      n--;      n--;
# Line 1350  if (common->utf8 && c > 127) Line 1431  if (common->utf8 && c > 127)
1431      }      }
1432    return (n << 8) | bit;    return (n << 8) | bit;
1433    }    }
1434  #endif  #endif /* SUPPORT_UTF */
1435  return (0 << 8) | bit;  return (0 << 8) | bit;
1436    
1437    #else /* COMPILE_PCRE8 */
1438    
1439    #ifdef COMPILE_PCRE16
1440    #ifdef SUPPORT_UTF
1441    if (common->utf && c > 65535)
1442      {
1443      if (bit >= (1 << 10))
1444        bit >>= 10;
1445      else
1446        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1447      }
1448    #endif /* SUPPORT_UTF */
1449    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1450    #endif /* COMPILE_PCRE16 */
1451    
1452    #endif /* COMPILE_PCRE8 */
1453  }  }
1454    
1455  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void check_partial(compiler_common *common)
1456  {  {
1457  DEFINE_COMPILER;  DEFINE_COMPILER;
1458  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1459    
1460    if (common->mode == JIT_COMPILE)
1461      return;
1462    
1463    jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1464    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1465      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1466    else
1467      {
1468      if (common->partialmatchlabel != NULL)
1469        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1470      else
1471        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1472      }
1473    JUMPHERE(jump);
1474    }
1475    
1476    static struct sljit_jump *check_str_end(compiler_common *common)
1477    {
1478    /* Does not affect registers. Usually used in a tight spot. */
1479    DEFINE_COMPILER;
1480    struct sljit_jump *jump;
1481    struct sljit_jump *nohit;
1482    struct sljit_jump *return_value;
1483    
1484    if (common->mode == JIT_COMPILE)
1485      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1486    
1487    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1488    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1489      {
1490      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1491      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1492      JUMPHERE(nohit);
1493      return_value = JUMP(SLJIT_JUMP);
1494      }
1495    else
1496      {
1497      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1498      if (common->partialmatchlabel != NULL)
1499        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1500      else
1501        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1502      }
1503    JUMPHERE(jump);
1504    return return_value;
1505    }
1506    
1507    static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1508    {
1509    DEFINE_COMPILER;
1510    struct sljit_jump *jump;
1511    
1512    if (common->mode == JIT_COMPILE)
1513      {
1514      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1515      return;
1516      }
1517    
1518    /* Partial matching mode. */
1519    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1520    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0));
1521    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1522      {
1523      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1524      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1525      }
1526    else
1527      {
1528      if (common->partialmatchlabel != NULL)
1529        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1530      else
1531        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1532      }
1533    JUMPHERE(jump);
1534  }  }
1535    
1536  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1365  static void read_char(compiler_common *c Line 1538  static void read_char(compiler_common *c
1538  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1539  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1540  DEFINE_COMPILER;  DEFINE_COMPILER;
1541  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1542  struct sljit_jump *jump;  struct sljit_jump *jump;
1543  #endif  #endif
1544    
1545  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1546  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1547  if (common->utf8)  if (common->utf)
1548    {    {
1549    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1550    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1551    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1552    #ifdef COMPILE_PCRE16
1553      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1554    #endif
1555    #endif /* COMPILE_PCRE8 */
1556      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1557    JUMPHERE(jump);    JUMPHERE(jump);
1558    }    }
1559  #endif  #endif
1560  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1561  }  }
1562    
1563  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1387  static void peek_char(compiler_common *c Line 1565  static void peek_char(compiler_common *c
1565  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1566  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1567  DEFINE_COMPILER;  DEFINE_COMPILER;
1568  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1569  struct sljit_jump *jump;  struct sljit_jump *jump;
1570  #endif  #endif
1571    
1572  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1573  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1574  if (common->utf8)  if (common->utf)
1575    {    {
1576    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1577    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1578    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1579    #ifdef COMPILE_PCRE16
1580      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1581    #endif
1582    #endif /* COMPILE_PCRE8 */
1583      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1584    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1585    JUMPHERE(jump);    JUMPHERE(jump);
1586    }    }
# Line 1408  static void read_char8_type(compiler_com Line 1591  static void read_char8_type(compiler_com
1591  {  {
1592  /* 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. */
1593  DEFINE_COMPILER;  DEFINE_COMPILER;
1594  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1595  struct sljit_jump *jump;  struct sljit_jump *jump;
1596  #endif  #endif
1597    
1598  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1599  if (common->utf8)  if (common->utf)
1600    {    {
1601    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1602    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1603    #ifdef COMPILE_PCRE8
1604    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1605    it is a clever early read in most cases. */    it is needed in most cases. */
1606    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1607    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1608    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  
1609    JUMPHERE(jump);    JUMPHERE(jump);
1610    #else
1611    #ifdef COMPILE_PCRE16
1612      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1613      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1614      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1615      JUMPHERE(jump);
1616      /* Skip low surrogate if necessary. */
1617      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1618      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1619      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1620      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1621      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1622    #endif
1623    #endif /* COMPILE_PCRE8 */
1624    return;    return;
1625    }    }
1626  #endif  #endif
1627  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1628  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1629  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1630    /* The ctypes array contains only 256 values. */
1631    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1632    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1633    #endif
1634    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1635    #ifdef COMPILE_PCRE16
1636    JUMPHERE(jump);
1637    #endif
1638  }  }
1639    
1640  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1641  {  {
1642  /* Goes one character back. Only affects STR_PTR. Does not check begin. */  /* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */
1643  DEFINE_COMPILER;  DEFINE_COMPILER;
1644  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1645  struct sljit_label *label;  struct sljit_label *label;
1646    
1647  if (common->utf8)  if (common->utf)
1648    {    {
1649    label = LABEL();    label = LABEL();
1650    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1651    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1652    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1653    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1654    return;    return;
1655    }    }
1656  #endif  #endif
1657  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1658    if (common->utf)
1659      {
1660      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1661      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1662      /* Skip low surrogate if necessary. */
1663      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1664      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1665      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1666      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1667      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1668      return;
1669      }
1670    #endif
1671    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1672  }  }
1673    
1674  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
# Line 1472  else if (nltype == NLTYPE_ANYCRLF) Line 1691  else if (nltype == NLTYPE_ANYCRLF)
1691    }    }
1692  else  else
1693    {    {
1694    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1695    add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));    add_jump(compiler, fallbacks, CMP(jumpiftrue ? SLJIT_C_EQUAL : SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
1696    }    }
1697  }  }
1698    
1699  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1700  static void do_utf8readchar(compiler_common *common)  
1701    #ifdef COMPILE_PCRE8
1702    static void do_utfreadchar(compiler_common *common)
1703  {  {
1704  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1705  of the character (>= 192). Return char value in TMP1, length - 1 in TMP2. */  of the character (>= 0xc0). Return char value in TMP1, length - 1 in TMP2. */
1706  DEFINE_COMPILER;  DEFINE_COMPILER;
1707  struct sljit_jump *jump;  struct sljit_jump *jump;
1708    
# Line 1489  sljit_emit_fast_enter(compiler, RETURN_A Line 1710  sljit_emit_fast_enter(compiler, RETURN_A
1710  /* Searching for the first zero. */  /* Searching for the first zero. */
1711  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x20);
1712  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1713  /* 2 byte sequence */  /* Two byte sequence. */
1714  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1715  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1716  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1717  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1718  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1719  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1720  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1721  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1722  JUMPHERE(jump);  JUMPHERE(jump);
1723    
1724  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10);
1725  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1726  /* 3 byte sequence */  /* Three byte sequence. */
1727  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1728  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1729  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1730  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1731  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1732  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1733  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1734  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 2);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
1735  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1736  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1737  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1738  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1739  JUMPHERE(jump);  JUMPHERE(jump);
1740    
1741  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1742  jump = JUMP(SLJIT_C_NOT_ZERO);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
 /* 4 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
1743  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1744  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1745  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1746  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1747  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1748  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
1749  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1750  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1751  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1752  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1753  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1754  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1755  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1756  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1757  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1758  }  }
1759    
1760  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1761  {  {
1762  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1763  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1764  DEFINE_COMPILER;  DEFINE_COMPILER;
1765  struct sljit_jump *jump;  struct sljit_jump *jump;
1766  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1573  sljit_emit_fast_enter(compiler, RETURN_A Line 1769  sljit_emit_fast_enter(compiler, RETURN_A
1769    
1770  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x20);
1771  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1772  /* 2 byte sequence */  /* Two byte sequence. */
1773  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1774  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1775  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1776  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1777  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1590  sljit_emit_fast_return(compiler, RETURN_ Line 1786  sljit_emit_fast_return(compiler, RETURN_
1786  JUMPHERE(jump);  JUMPHERE(jump);
1787    
1788  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1789  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_utf8_char_sizes);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
1790  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1791  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1792  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1793  }  }
1794    
1795  #endif  #else /* COMPILE_PCRE8 */
1796    
1797    #ifdef COMPILE_PCRE16
1798    static void do_utfreadchar(compiler_common *common)
1799    {
1800    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1801    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1802    DEFINE_COMPILER;
1803    struct sljit_jump *jump;
1804    
1805    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1806    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1807    /* Do nothing, only return. */
1808    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1809    
1810    JUMPHERE(jump);
1811    /* Combine two 16 bit characters. */
1812    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1813    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1814    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1815    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1816    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1817    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1818    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1819    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1820    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1821    }
1822    #endif /* COMPILE_PCRE16 */
1823    
1824    #endif /* COMPILE_PCRE8 */
1825    
1826    #endif /* SUPPORT_UTF */
1827    
1828  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1829    
# Line 1615  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1841  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1841    
1842  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1843  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1844  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)_pcre_ucd_stage1);  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(ucd_stage1));
1845  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1846  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1847  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1848  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1849  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1850  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, chartype));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype));
1851  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1852  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1853  }  }
# Line 1635  struct sljit_label *newlinelabel = NULL; Line 1861  struct sljit_label *newlinelabel = NULL;
1861  struct sljit_jump *start;  struct sljit_jump *start;
1862  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1863  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1864    #ifdef SUPPORT_UTF
1865    struct sljit_jump *singlechar;
1866    #endif
1867  jump_list *newline = NULL;  jump_list *newline = NULL;
1868  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1869  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1870    
1871  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1872      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1652  if (firstline) Line 1881  if (firstline)
1881    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1882      {      {
1883      mainloop = LABEL();      mainloop = LABEL();
1884      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1885      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1886      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1887      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1888      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, mainloop);
1889      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);      CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, mainloop);
1890      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1891      }      }
1892    else    else
1893      {      {
# Line 1682  start = JUMP(SLJIT_JUMP); Line 1911  start = JUMP(SLJIT_JUMP);
1911  if (newlinecheck)  if (newlinecheck)
1912    {    {
1913    newlinelabel = LABEL();    newlinelabel = LABEL();
1914    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1915    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1916    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1917    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);
1918    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1919    #ifdef COMPILE_PCRE16
1920      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1921    #endif
1922    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1923    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1924    }    }
# Line 1694  if (newlinecheck) Line 1926  if (newlinecheck)
1926  mainloop = LABEL();  mainloop = LABEL();
1927    
1928  /* Increasing the STR_PTR here requires one less jump in the most common case. */  /* Increasing the STR_PTR here requires one less jump in the most common case. */
1929  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1930  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1931  #endif  #endif
1932  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1933    
1934  if (readbyte)  if (readuchar)
1935    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1936    
1937  if (newlinecheck)  if (newlinecheck)
1938    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);
1939    
1940  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1941  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1942    if (common->utf)
1943    {    {
1944    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1945      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1946    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1947      JUMPHERE(singlechar);
1948      }
1949    #endif
1950    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1951    if (common->utf)
1952      {
1953      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1954      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1955      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1956      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1957      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1958      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1959      JUMPHERE(singlechar);
1960    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
1961  #endif  #endif
1962  JUMPHERE(start);  JUMPHERE(start);
1963    
# Line 1727  if (newlinecheck) Line 1970  if (newlinecheck)
1970  return mainloop;  return mainloop;
1971  }  }
1972    
1973  static SLJIT_INLINE void fast_forward_first_byte(compiler_common *common, pcre_uint16 firstbyte, BOOL firstline)  static SLJIT_INLINE void fast_forward_first_char(compiler_common *common, pcre_uchar first_char, BOOL caseless, BOOL firstline)
1974  {  {
1975  DEFINE_COMPILER;  DEFINE_COMPILER;
1976  struct sljit_label *start;  struct sljit_label *start;
1977  struct sljit_jump *leave;  struct sljit_jump *leave;
1978  struct sljit_jump *found;  struct sljit_jump *found;
1979  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1980    
1981  if (firstline)  if (firstline)
1982    {    {
# Line 1743  if (firstline) Line 1986  if (firstline)
1986    
1987  start = LABEL();  start = LABEL();
1988  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1989  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1990    
1991  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1992    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
1993      {
1994      oc = TABLE_GET(first_char, common->fcc, first_char);
1995    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1996      if (first_char > 127 && common->utf)
1997        oc = UCD_OTHERCASE(first_char);
1998    #endif
1999      }
2000    if (first_char == oc)
2001      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2002  else  else
2003    {    {
2004    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2005    if (ispowerof2(bit))    if (ispowerof2(bit))
2006      {      {
2007      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2008      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2009      }      }
2010    else    else
2011      {      {
2012      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, firstbyte);      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, first_char);
2013      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2014      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);
2015      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1767  else Line 2017  else
2017      }      }
2018    }    }
2019    
2020  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2021  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2022    if (common->utf)
2023    {    {
2024    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2025      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2026      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2027      }
2028    #endif
2029    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2030    if (common->utf)
2031      {
2032      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2033      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2034      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2035      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2036      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2037    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2038    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
2039  #endif  #endif
2040  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2041  JUMPHERE(found);  JUMPHERE(found);
# Line 1811  if (common->nltype == NLTYPE_FIXED && co Line 2070  if (common->nltype == NLTYPE_FIXED && co
2070    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2071    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2072    
2073    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2074    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);
2075    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2076    #ifdef COMPILE_PCRE16
2077      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2078    #endif
2079    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2080    
2081    loop = LABEL();    loop = LABEL();
2082    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2083    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2084    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2085    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2086    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff, loop);
2087    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);    CMPTO(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff, loop);
2088    
# Line 1851  if (common->nltype == NLTYPE_ANY || comm Line 2113  if (common->nltype == NLTYPE_ANY || comm
2113    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2114    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2115    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2116    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2117    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);
2118    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2119    #ifdef COMPILE_PCRE16
2120      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2121    #endif
2122    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2123    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2124    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1871  DEFINE_COMPILER; Line 2136  DEFINE_COMPILER;
2136  struct sljit_label *start;  struct sljit_label *start;
2137  struct sljit_jump *leave;  struct sljit_jump *leave;
2138  struct sljit_jump *found;  struct sljit_jump *found;
2139    #ifndef COMPILE_PCRE8
2140    struct sljit_jump *jump;
2141    #endif
2142    
2143  if (firstline)  if (firstline)
2144    {    {
# Line 1880  if (firstline) Line 2148  if (firstline)
2148    
2149  start = LABEL();  start = LABEL();
2150  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2151  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2152  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2153  if (common->utf8)  if (common->utf)
2154    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2155    #endif
2156    #ifndef COMPILE_PCRE8
2157    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2158    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2159    JUMPHERE(jump);
2160  #endif  #endif
2161  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2162  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1892  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2165  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2165  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);
2166  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2167    
2168  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2169  if (common->utf8)  if (common->utf)
2170    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2171  else  #endif
2172    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2173  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2174  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2175      {
2176      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2177      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2178      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2179      }
2180    #endif
2181    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2182    if (common->utf)
2183      {
2184      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2185      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2186      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2187      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2188      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2189      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2190      }
2191  #endif  #endif
2192  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2193  JUMPHERE(found);  JUMPHERE(found);
# Line 1908  if (firstline) Line 2197  if (firstline)
2197    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2198  }  }
2199    
2200  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uint16 reqbyte, BOOL has_firstbyte)  static SLJIT_INLINE struct sljit_jump *search_requested_char(compiler_common *common, pcre_uchar req_char, BOOL caseless, BOOL has_firstchar)
2201  {  {
2202  DEFINE_COMPILER;  DEFINE_COMPILER;
2203  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1917  struct sljit_jump *alreadyfound; Line 2206  struct sljit_jump *alreadyfound;
2206  struct sljit_jump *found;  struct sljit_jump *found;
2207  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2208  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2209  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2210    
2211  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);
2212  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, REQ_BYTE_MAX);
2213  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2214  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2215    
2216  if (has_firstbyte)  if (has_firstchar)
2217    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2218  else  else
2219    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2220    
2221  loop = LABEL();  loop = LABEL();
2222  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2223    
2224  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2225  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2226    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2227      {
2228      oc = TABLE_GET(req_char, common->fcc, req_char);
2229    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2230      if (req_char > 127 && common->utf)
2231        oc = UCD_OTHERCASE(req_char);
2232    #endif
2233      }
2234    if (req_char == oc)
2235      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2236  else  else
2237    {    {
2238    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2239    if (ispowerof2(bit))    if (ispowerof2(bit))
2240      {      {
2241      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2242      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2243      }      }
2244    else    else
2245      {      {
2246      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2247      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2248      }      }
2249    }    }
2250  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2251  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2252    
2253  JUMPHERE(found);  JUMPHERE(found);
2254  if (foundoc)  if (foundoc)
2255    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2256  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);
2257  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2258  JUMPHERE(toolong);  JUMPHERE(toolong);
2259  return notfound;  return notfound;
# Line 1966  return notfound; Line 2262  return notfound;
2262  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2263  {  {
2264  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2265  struct sljit_jump *jump;  struct sljit_jump *jump;
2266  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2267    
2268  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
2269  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2270    
2271  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2272  mainloop = LABEL();  mainloop = LABEL();
2273  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2274  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1987  JUMPTO(SLJIT_JUMP, mainloop); Line 2281  JUMPTO(SLJIT_JUMP, mainloop);
2281  JUMPHERE(jump);  JUMPHERE(jump);
2282  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2283  /* End of dropping frames. */  /* End of dropping frames. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
 CMPTO(SLJIT_C_GREATER_EQUAL, TMP1, 0, STACK_TOP, 0, mainloop);  
 JUMPHERE(earlyexit);  
2284  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2285    
2286  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2010  JUMPTO(SLJIT_JUMP, mainloop); Line 2300  JUMPTO(SLJIT_JUMP, mainloop);
2300  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2301  {  {
2302  DEFINE_COMPILER;  DEFINE_COMPILER;
2303  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2304  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2305  struct sljit_jump *jump;  struct sljit_jump *jump;
2306  #endif  #endif
2307    
2308  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2309    
2310  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
2311  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
2312  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2313  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
2314  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2315  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2316  skip_char_back(common);  skip_char_back(common);
2317    check_start_used_ptr(common);
2318  read_char(common);  read_char(common);
2319    
2320  /* Testing char type. */  /* Testing char type. */
2321  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2322  if (common->useucp)  if (common->use_ucp)
2323    {    {
2324    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2325    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2045  if (common->useucp) Line 2336  if (common->useucp)
2336  else  else
2337  #endif  #endif
2338    {    {
2339  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2340      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2341    #elif defined SUPPORT_UTF
2342    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2343    jump = NULL;    jump = NULL;
2344    if (common->utf8)    if (common->utf)
2345      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2346  #endif  #endif /* COMPILE_PCRE8 */
2347    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2348    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2349    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2350    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2351  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2352      JUMPHERE(jump);
2353    #elif defined SUPPORT_UTF
2354    if (jump != NULL)    if (jump != NULL)
2355      JUMPHERE(jump);      JUMPHERE(jump);
2356  #endif  #endif /* COMPILE_PCRE8 */
2357    }    }
2358  JUMPHERE(beginend);  JUMPHERE(skipread);
2359    
2360  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2361  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2362  peek_char(common);  peek_char(common);
2363    
2364  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2365  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2366  if (common->useucp)  if (common->use_ucp)
2367    {    {
2368    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2369    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2084  if (common->useucp) Line 2379  if (common->useucp)
2379  else  else
2380  #endif  #endif
2381    {    {
2382  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2383      /* TMP2 may be destroyed by peek_char. */
2384      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2385      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2386    #elif defined SUPPORT_UTF
2387    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2388    jump = NULL;    jump = NULL;
2389    if (common->utf8)    if (common->utf)
2390      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2391  #endif  #endif
2392    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2393    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2394    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2395  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2396      JUMPHERE(jump);
2397    #elif defined SUPPORT_UTF
2398    if (jump != NULL)    if (jump != NULL)
2399      JUMPHERE(jump);      JUMPHERE(jump);
2400  #endif  #endif /* COMPILE_PCRE8 */
2401    }    }
2402  JUMPHERE(beginend);  JUMPHERE(skipread);
2403    
2404  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);
2405  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2115  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2416  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2416  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);
2417  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2418  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);
2419  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2420  if (common->utf8)  #ifdef COMPILE_PCRE8
2421    if (common->utf)
2422    {    {
2423    #endif
2424    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2425    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2426    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);
2427    #ifdef COMPILE_PCRE8
2428    }    }
2429  #endif  #endif
2430    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2431  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2432  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2433  }  }
# Line 2139  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2444  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2444  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);
2445  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2446  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);
2447  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2448  if (common->utf8)  #ifdef COMPILE_PCRE8
2449    if (common->utf)
2450    {    {
2451    #endif
2452    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2453    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);
2454    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2155  if (common->utf8) Line 2462  if (common->utf8)
2462    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);
2463    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2464    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);
2465    #ifdef COMPILE_PCRE8
2466    }    }
2467  #endif  #endif
2468    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2469  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2470    
2471  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2173  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2482  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2482  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);
2483  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2484  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);
2485  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2486  if (common->utf8)  #ifdef COMPILE_PCRE8
2487    if (common->utf)
2488    {    {
2489    #endif
2490    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2491    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2492    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);
2493    #ifdef COMPILE_PCRE8
2494    }    }
2495  #endif  #endif
2496    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2497  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2498    
2499  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2199  sljit_emit_fast_enter(compiler, RETURN_A Line 2512  sljit_emit_fast_enter(compiler, RETURN_A
2512  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2513  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2514  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2515  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2516  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2517    
2518  label = LABEL();  label = LABEL();
2519  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2520  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2521  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2522  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2523  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2524    
2525  JUMPHERE(jump);  JUMPHERE(jump);
2526  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2527  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2528  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2529  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2231  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2544  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2544  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2545  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2546  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2547  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2548  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2549    
2550  label = LABEL();  label = LABEL();
2551  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2552  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2553    #ifndef COMPILE_PCRE8
2554    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2555    #endif
2556  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2557    #ifndef COMPILE_PCRE8
2558    JUMPHERE(jump);
2559    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2560    #endif
2561  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2562    #ifndef COMPILE_PCRE8
2563    JUMPHERE(jump);
2564    #endif
2565  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2566  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
2567  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2568    
2569  JUMPHERE(jump);  JUMPHERE(jump);
2570  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2571  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2572  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2573  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2255  sljit_emit_fast_return(compiler, RETURN_ Line 2578  sljit_emit_fast_return(compiler, RETURN_
2578  #undef CHAR1  #undef CHAR1
2579  #undef CHAR2  #undef CHAR2
2580    
2581  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2582    
2583  static uschar * SLJIT_CALL do_utf8caselesscmp(uschar *src1, jit_arguments *args, uschar *end1)  static const pcre_uchar *SLJIT_CALL do_utf_caselesscmp(pcre_uchar *src1, jit_arguments *args, pcre_uchar *end1)
2584  {  {
2585  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2586  int c1, c2;  int c1, c2;
2587  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2588  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2589    
2590  while (src1 < end1)  while (src1 < end1)
2591    {    {
2592    if (src2 >= end2)    if (src2 >= end2)
2593      return 0;      return (pcre_uchar*)1;
2594    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2595    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2596    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2597    }    }
2598  return src2;  return src2;
2599  }  }
2600    
2601  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2602    
2603  static uschar *byte_sequence_compare(compiler_common *common, BOOL caseless, uschar *cc,  static pcre_uchar *byte_sequence_compare(compiler_common *common, BOOL caseless, pcre_uchar *cc,
2604      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2605  {  {
2606  DEFINE_COMPILER;  DEFINE_COMPILER;
2607  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2608  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2609  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2610  int utf8length;  int utflength;
2611  #endif  #endif
2612    
2613  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2294  if (caseless && char_has_othercase(commo Line 2615  if (caseless && char_has_othercase(commo
2615    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2616    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2617    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2618    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2619      othercasechar = cc + (othercasebit >> 8);
2620    othercasebit &= 0xff;    othercasebit &= 0xff;
2621    #else
2622    #ifdef COMPILE_PCRE16
2623      othercasechar = cc + (othercasebit >> 9);
2624      if ((othercasebit & 0x100) != 0)
2625        othercasebit = (othercasebit & 0xff) << 8;
2626      else
2627        othercasebit &= 0xff;
2628    #endif
2629    #endif
2630    }    }
2631    
2632  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2633    {    {
2634    #ifdef COMPILE_PCRE8
2635  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2636    if (context->length >= 4)    if (context->length >= 4)
2637      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2638    else if (context->length >= 2)    else if (context->length >= 2)
2639      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2640    else    else
2641  #endif  #endif
2642      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2643    #else
2644    #ifdef COMPILE_PCRE16
2645    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2646      if (context->length >= 4)
2647        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2648      else
2649    #endif
2650        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2651    #endif
2652    #endif /* COMPILE_PCRE8 */
2653    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2654    }    }
2655    
2656  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2657  utf8length = 1;  utflength = 1;
2658  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2659    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2660    
2661  do  do
2662    {    {
2663  #endif  #endif
2664    
2665    context->length--;    context->length -= IN_UCHARS(1);
2666  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2667    
2668    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2669    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2670      {      {
2671      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2672      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2673      }      }
2674    else    else
2675      {      {
2676      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2677      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2678      }      }
2679    context->byteptr++;    context->ucharptr++;
2680    
2681    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2682      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2683    #else
2684      if (context->ucharptr >= 2 || context->length == 0)
2685    #endif
2686      {      {
2687      if (context->length >= 4)      if (context->length >= 4)
2688        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);
2689    #ifdef COMPILE_PCRE8
2690      else if (context->length >= 2)      else if (context->length >= 2)
2691        OP1(SLJIT_MOV_SH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2692      else if (context->length >= 1)      else if (context->length >= 1)
2693        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);
2694    #else
2695        else if (context->length >= 2)
2696          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2697    #endif
2698      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2699    
2700      switch(context->byteptr)      switch(context->ucharptr)
2701        {        {
2702        case 4:        case 4 / sizeof(pcre_uchar):
2703        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2704          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asint);
2705        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asint | context->oc.asint));
2706        break;        break;
2707    
2708        case 2:        case 2 / sizeof(pcre_uchar):
2709        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2710          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asshort);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asushort);
2711        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asshort | context->oc.asshort));        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asushort | context->oc.asushort));
2712        break;        break;
2713    
2714    #ifdef COMPILE_PCRE8
2715        case 1:        case 1:
2716        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2717          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);          OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, context->oc.asbyte);
2718        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, context->c.asbyte | context->oc.asbyte));
2719        break;        break;
2720    #endif
2721    
2722        default:        default:
2723        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2724        break;        break;
2725        }        }
2726      context->byteptr = 0;      context->ucharptr = 0;
2727      }      }
2728    
2729  #else  #else
2730    
2731    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2732    #ifdef COMPILE_PCRE8
2733    if (context->length > 0)    if (context->length > 0)
2734      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);
2735    #else
2736      if (context->length > 0)
2737        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2738    #endif
2739    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2740    
2741    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2742      {      {
2743      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2744      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
# Line 2391  do Line 2749  do
2749  #endif  #endif
2750    
2751    cc++;    cc++;
2752  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2753    utf8length--;    utflength--;
2754    }    }
2755  while (utf8length > 0);  while (utflength > 0);
2756  #endif  #endif
2757    
2758  return cc;  return cc;
2759  }  }
2760    
2761  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2762    
2763  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2764    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2422  return cc; Line 2780  return cc;
2780      } \      } \
2781    charoffset = (value);    charoffset = (value);
2782    
2783  static void compile_xclass_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks)  static void compile_xclass_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
2784  {  {
2785  DEFINE_COMPILER;  DEFINE_COMPILER;
2786  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2430  jump_list **list = (*cc & XCL_NOT) == 0 Line 2788  jump_list **list = (*cc & XCL_NOT) == 0
2788  unsigned int c;  unsigned int c;
2789  int compares;  int compares;
2790  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2791  uschar *ccbegin;  pcre_uchar *ccbegin;
2792  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2793  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2794  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2795  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2796    unsigned int typeoffset;
2797  #endif  #endif
2798  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2799    unsigned int charoffset;
2800    
2801  /* Although SUPPORT_UTF8 must be defined, we are not necessary in utf8 mode. */  /* Although SUPPORT_UTF must be defined, we are not necessary in utf mode. */
2802  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2803  read_char(common);  read_char(common);
2804    
2805  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2806    {    {
2807    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2808    if (common->utf8)  #ifndef COMPILE_PCRE8
2809      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2810    #elif defined SUPPORT_UTF
2811      if (common->utf)
2812      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2813    #endif
2814    
2815    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2816    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2455  if ((*cc++ & XCL_MAP) != 0) Line 2819  if ((*cc++ & XCL_MAP) != 0)
2819    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);
2820    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2821    
2822    if (common->utf8)  #ifndef COMPILE_PCRE8
2823      JUMPHERE(jump);
2824    #elif defined SUPPORT_UTF
2825      if (common->utf)
2826      JUMPHERE(jump);      JUMPHERE(jump);
2827    #endif
2828    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2829  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2830    charsaved = TRUE;    charsaved = TRUE;
2831  #endif  #endif
2832    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2833    }    }
2834    
2835  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2473  while (*cc != XCL_END) Line 2841  while (*cc != XCL_END)
2841    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2842      {      {
2843      cc += 2;      cc += 2;
2844  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2845      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2846  #endif  #endif
2847  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2848      needschar = TRUE;      needschar = TRUE;
# Line 2483  while (*cc != XCL_END) Line 2851  while (*cc != XCL_END)
2851    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2852      {      {
2853      cc += 2;      cc += 2;
2854  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2855      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2856  #endif  #endif
2857      cc++;      cc++;
2858  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2859      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2860  #endif  #endif
2861  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2862      needschar = TRUE;      needschar = TRUE;
# Line 2558  if (needstype || needsscript) Line 2926  if (needstype || needsscript)
2926      {      {
2927      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2928        {        {
2929        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, script));        OP1(SLJIT_MOV, scriptreg, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
2930        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2931        }        }
2932      else      else
2933        {        {
2934        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2935        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_records + SLJIT_OFFSETOF(ucd_record, script));        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, script));
2936        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2937        }        }
2938      }      }
# Line 2588  while (*cc != XCL_END) Line 2956  while (*cc != XCL_END)
2956    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2957      {      {
2958      cc ++;      cc ++;
2959  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2960      if (common->utf8)      if (common->utf)
2961        {        {
2962        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2963        }        }
# Line 2619  while (*cc != XCL_END) Line 2987  while (*cc != XCL_END)
2987    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2988      {      {
2989      cc ++;      cc ++;
2990  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2991      if (common->utf8)      if (common->utf)
2992        {        {
2993        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2994        }        }
# Line 2628  while (*cc != XCL_END) Line 2996  while (*cc != XCL_END)
2996  #endif  #endif
2997        c = *cc++;        c = *cc++;
2998      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
2999  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3000      if (common->utf8)      if (common->utf)
3001        {        {
3002        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3003        }        }
# Line 2685  while (*cc != XCL_END) Line 3053  while (*cc != XCL_END)
3053        break;        break;
3054    
3055        case PT_GC:        case PT_GC:
3056        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3057        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3058        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, _pcre_ucp_typerange[(int)cc[1] * 2 + 1] - c);        jump = CMP(SLJIT_C_LESS_EQUAL ^ invertcmp, typereg, 0, SLJIT_IMM, PRIV(ucp_typerange)[(int)cc[1] * 2 + 1] - c);
3059        break;        break;
3060    
3061        case PT_PC:        case PT_PC:
# Line 2749  if (found != NULL) Line 3117  if (found != NULL)
3117    
3118  #endif  #endif
3119    
3120  static uschar *compile_char1_hotpath(compiler_common *common, uschar type, uschar *cc, jump_list **fallbacks)  static pcre_uchar *compile_char1_hotpath(compiler_common *common, pcre_uchar type, pcre_uchar *cc, jump_list **fallbacks)
3121  {  {
3122  DEFINE_COMPILER;  DEFINE_COMPILER;
3123  int length;  int length;
3124  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3125  compare_context context;  compare_context context;
3126  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3127  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3128  struct sljit_label *label;  struct sljit_label *label;
3129  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3130  uschar propdata[5];  pcre_uchar propdata[5];
3131  #endif  #endif
3132  #endif  #endif
3133    
# Line 2785  switch(type) Line 3153  switch(type)
3153    
3154    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3155    case OP_DIGIT:    case OP_DIGIT:
3156    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3157    read_char8_type(common);    read_char8_type(common);
3158    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3159    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2793  switch(type) Line 3161  switch(type)
3161    
3162    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3163    case OP_WHITESPACE:    case OP_WHITESPACE:
3164    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3165    read_char8_type(common);    read_char8_type(common);
3166    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3167    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2801  switch(type) Line 3169  switch(type)
3169    
3170    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3171    case OP_WORDCHAR:    case OP_WORDCHAR:
3172    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3173    read_char8_type(common);    read_char8_type(common);
3174    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3175    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3176    return cc;    return cc;
3177    
3178    case OP_ANY:    case OP_ANY:
3179    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3180    read_char(common);    read_char(common);
3181    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3182      {      {
3183      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);
3184      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3185      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3186      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, common->newline & 0xff));
3187      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3188      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 2824  switch(type) Line 3192  switch(type)
3192    return cc;    return cc;
3193    
3194    case OP_ALLANY:    case OP_ALLANY:
3195    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3196  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3197    if (common->utf8)    if (common->utf)
3198      {      {
3199      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3200      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3201    #ifdef COMPILE_PCRE8
3202        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3203        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3204      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3205    #else /* COMPILE_PCRE8 */
3206    #ifdef COMPILE_PCRE16
3207        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3208        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3209        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3210        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3211        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3212        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3213    #endif /* COMPILE_PCRE16 */
3214    #endif /* COMPILE_PCRE8 */
3215        JUMPHERE(jump[0]);
3216      return cc;      return cc;
3217      }      }
3218  #endif  #endif
3219    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3220      return cc;
3221    
3222      case OP_ANYBYTE:
3223      fallback_at_str_end(common, fallbacks);
3224      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3225    return cc;    return cc;
3226    
3227  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3228  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3229    case OP_NOTPROP:    case OP_NOTPROP:
3230    case OP_PROP:    case OP_PROP:
# Line 2852  switch(type) Line 3239  switch(type)
3239  #endif  #endif
3240    
3241    case OP_ANYNL:    case OP_ANYNL:
3242    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3243    read_char(common);    read_char(common);
3244    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);
3245    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3246    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3247    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);    jump[2] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3248    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3249    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3250    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3251    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2869  switch(type) Line 3256  switch(type)
3256    
3257    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3258    case OP_HSPACE:    case OP_HSPACE:
3259    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3260    read_char(common);    read_char(common);
3261    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3262    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2877  switch(type) Line 3264  switch(type)
3264    
3265    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3266    case OP_VSPACE:    case OP_VSPACE:
3267    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3268    read_char(common);    read_char(common);
3269    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3270    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2885  switch(type) Line 3272  switch(type)
3272    
3273  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3274    case OP_EXTUNI:    case OP_EXTUNI:
3275    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3276    read_char(common);    read_char(common);
3277    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3278    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 2901  switch(type) Line 3288  switch(type)
3288    
3289    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3290    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3291      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3292        {
3293        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3294        check_partial(common);
3295        JUMPHERE(jump[0]);
3296        }
3297    return cc;    return cc;
3298  #endif  #endif
3299    
# Line 2908  switch(type) Line 3301  switch(type)
3301    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);
3302    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3303      {      {
3304      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3305      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3306      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3307      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3308      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3309      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3310      }      }
3311    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3312      {      {
3313      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3314      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3315      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3316      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, common->newline));
3317      }      }
3318    else    else
3319      {      {
3320      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3321      jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);      jump[1] = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR);
3322      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3323      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);
3324      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3325      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3326      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3327        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3328      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3329      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3330    
3331      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3332      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3333        {        {
3334        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3335        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, STR_END, 0));
3336        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL));
3337        }        }
# Line 2954  switch(type) Line 3348  switch(type)
3348      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3349      }      }
3350    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3351      check_partial(common);
3352    return cc;    return cc;
3353    
3354    case OP_EOD:    case OP_EOD:
3355    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));
3356      check_partial(common);
3357    return cc;    return cc;
3358    
3359    case OP_CIRC:    case OP_CIRC:
# Line 2977  switch(type) Line 3373  switch(type)
3373    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3374    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3375    
3376    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end));    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0));  
   
3377    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3378      {      {
3379      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3380      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3381      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3382      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3383      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3384      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3385      }      }
# Line 3006  switch(type) Line 3400  switch(type)
3400    if (!common->endonly)    if (!common->endonly)
3401      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3402    else    else
3403        {
3404      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3405        check_partial(common);
3406        }
3407    return cc;    return cc;
3408    
3409    case OP_DOLLM:    case OP_DOLLM:
# Line 3014  switch(type) Line 3411  switch(type)
3411    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3412    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3413    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3414      check_partial(common);
3415    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3416    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3417    
3418    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3419      {      {
3420      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3421      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3422      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3423      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3424      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3425      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, common->newline & 0xff));
3426      }      }
# Line 3037  switch(type) Line 3435  switch(type)
3435    case OP_CHAR:    case OP_CHAR:
3436    case OP_CHARI:    case OP_CHARI:
3437    length = 1;    length = 1;
3438  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3439    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3440  #endif  #endif
3441    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
3442      {      {
3443      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3444      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));
3445    
3446      context.length = length;      context.length = IN_UCHARS(length);
3447      context.sourcereg = -1;      context.sourcereg = -1;
3448  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3449      context.byteptr = 0;      context.ucharptr = 0;
3450  #endif  #endif
3451      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3452      }      }
3453    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3454    read_char(common);    read_char(common);
3455  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3456    if (common->utf8)    if (common->utf)
3457      {      {
3458      GETCHAR(c, cc);      GETCHAR(c, cc);
3459      }      }
3460    else    else
3461  #endif  #endif
3462      c = *cc;      c = *cc;
3463      if (type == OP_CHAR || !char_has_othercase(common, cc))
3464        {
3465        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3466        return cc + length;
3467        }
3468      oc = char_othercase(common, c);
3469      bit = c ^ oc;
3470      if (ispowerof2(bit))
3471        {
3472        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3473        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3474        return cc + length;
3475        }
3476    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);
3477    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3478    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
# Line 3071  switch(type) Line 3482  switch(type)
3482    
3483    case OP_NOT:    case OP_NOT:
3484    case OP_NOTI:    case OP_NOTI:
3485      fallback_at_str_end(common, fallbacks);
3486    length = 1;    length = 1;
3487  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3488    if (common->utf8)    if (common->utf)
3489      {      {
3490      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3491        c = *cc;
3492      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3493        {        {
3494        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
       OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
3495        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3496          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3497        else        else
3498          {          {
3499          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3500          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3501          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c | 0x20));          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, c | 0x20));
3502          }          }
3503        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3504        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3505        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3506          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3507          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3508          JUMPHERE(jump[0]);
3509          return cc + 1;
3510        }        }
3511      else      else
3512    #endif /* COMPILE_PCRE8 */
3513          {
3514          GETCHARLEN(c, cc, length);
3515        read_char(common);        read_char(common);
3516          }
3517      }      }
3518    else    else
3519  #endif  #endif /* SUPPORT_UTF */
3520      {      {
3521      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      read_char(common);
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);  
3522      c = *cc;      c = *cc;
3523      }      }
3524    
# Line 3125  switch(type) Line 3539  switch(type)
3539        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3540        }        }
3541      }      }
3542    return cc + length;    return cc + 1;
3543    
3544    case OP_CLASS:    case OP_CLASS:
3545    case OP_NCLASS:    case OP_NCLASS:
3546    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3547    read_char(common);    read_char(common);
3548  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3549    jump[0] = NULL;    jump[0] = NULL;
3550    if (common->utf8)  #ifdef COMPILE_PCRE8
3551      /* This check only affects 8 bit mode. In other modes, we
3552      always need to compare the value with 255. */
3553      if (common->utf)
3554    #endif /* COMPILE_PCRE8 */
3555      {      {
3556      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3557      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3142  switch(type) Line 3560  switch(type)
3560        jump[0] = NULL;        jump[0] = NULL;
3561        }        }
3562      }      }
3563  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3564    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3565    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3566    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3567    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3568    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);
3569    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3570  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3571    if (jump[0] != NULL)    if (jump[0] != NULL)
3572      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3573  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3574    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3575    
3576  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3577    case OP_XCLASS:    case OP_XCLASS:
3578    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3579    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3165  switch(type) Line 3583  switch(type)
3583    length = GET(cc, 0);    length = GET(cc, 0);
3584    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3585    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3586    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3587  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3588      {      {
3589        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3590      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3591      label = LABEL();      label = LABEL();
3592      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP3, 0));
3593      skip_char_back(common);      skip_char_back(common);
3594      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
3595      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3596      }      }
3597      else
3598  #endif  #endif
3599    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3600    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3601        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3602        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3603        }
3604      check_start_used_ptr(common);
3605    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3606    }    }
3607  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3608  return cc;  return cc;
3609  }  }
3610    
3611  static SLJIT_INLINE uschar *compile_charn_hotpath(compiler_common *common, uschar *cc, uschar *ccend, jump_list **fallbacks)  static SLJIT_INLINE pcre_uchar *compile_charn_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, jump_list **fallbacks)
3612  {  {
3613  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3614  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */  /* To decrease the number of length checks, we try to concatenate the fixed length character sequences. */
3615  DEFINE_COMPILER;  DEFINE_COMPILER;
3616  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3617  compare_context context;  compare_context context;
3618  int size;  int size;
3619    
# Line 3204  do Line 3626  do
3626    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3627      {      {
3628      size = 1;      size = 1;
3629  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3630      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3631        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3632  #endif  #endif
3633      }      }
3634    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3635      {      {
3636      size = 1;      size = 1;
3637  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3638      if (common->utf8)      if (common->utf)
3639        {        {
3640        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)        if (char_has_othercase(common, cc + 1) && char_get_othercase_bit(common, cc + 1) == 0)
3641          size = 0;          size = 0;
3642        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3643          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3644        }        }
3645      else      else
3646  #endif  #endif
# Line 3229  do Line 3651  do
3651      size = 0;      size = 0;
3652    
3653    cc += 1 + size;    cc += 1 + size;
3654    context.length += size;    context.length += IN_UCHARS(size);
3655    }    }
3656  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3657    
# Line 3242  if (context.length > 0) Line 3664  if (context.length > 0)
3664    
3665    context.sourcereg = -1;    context.sourcereg = -1;
3666  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3667    context.byteptr = 0;    context.ucharptr = 0;
3668  #endif  #endif
3669    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);    do cc = byte_sequence_compare(common, *cc == OP_CHARI, cc + 1, &context, fallbacks); while (context.length > 0);
3670    return cc;    return cc;
# Line 3252  if (context.length > 0) Line 3674  if (context.length > 0)
3674  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3675  }  }
3676    
3677  static struct sljit_jump *compile_ref_checks(compiler_common *common, uschar *cc, jump_list **fallbacks)  static struct sljit_jump *compile_ref_checks(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks)
3678  {  {
3679  DEFINE_COMPILER;  DEFINE_COMPILER;
3680  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3262  if (!common->jscript_compat) Line 3684  if (!common->jscript_compat)
3684    {    {
3685    if (fallbacks == NULL)    if (fallbacks == NULL)
3686      {      {
3687        /* OVECTOR(1) contains the "string begin - 1" constant. */
3688      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));
3689      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3690      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));
# Line 3274  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3697  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3697  }  }
3698    
3699  /* Forward definitions. */  /* Forward definitions. */
3700  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3701  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3702    
3703  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3303  static void compile_fallbackpath(compile Line 3726  static void compile_fallbackpath(compile
3726      } \      } \
3727    while (0)    while (0)
3728    
3729  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3730    
3731  static uschar *compile_ref_hotpath(compiler_common *common, uschar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)  static pcre_uchar *compile_ref_hotpath(compiler_common *common, pcre_uchar *cc, jump_list **fallbacks, BOOL withchecks, BOOL emptyfail)
3732  {  {
3733  DEFINE_COMPILER;  DEFINE_COMPILER;
3734  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3735  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3736    struct sljit_jump *partial;
3737    struct sljit_jump *nopartial;
3738    
3739  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3740    /* OVECTOR(1) contains the "string begin - 1" constant. */
3741  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3742    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
3743    
3744  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3745  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3746    {    {
3747    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);    SLJIT_ASSERT(TMP1 == SLJIT_TEMPORARY_REG1 && STACK_TOP == SLJIT_TEMPORARY_REG2 && TMP2 == SLJIT_TEMPORARY_REG3);
3748    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));
# Line 3328  if (common->utf8 && *cc == OP_REFI) Line 3753  if (common->utf8 && *cc == OP_REFI)
3753    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3754    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3755    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
3756    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf8caselesscmp));    sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp));
3757    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3758    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3759        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3760      else
3761        {
3762        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3763        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3764        check_partial(common);
3765        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3766        JUMPHERE(nopartial);
3767        }
3768    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3769    }    }
3770  else  else
3771  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3772    {    {
3773    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);    OP2(SLJIT_SUB | SLJIT_SET_E, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP1, 0);
3774    if (withchecks)    if (withchecks)
3775      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3776    
3777    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3778      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3779      if (common->mode == JIT_COMPILE)
3780        add_jump(compiler, fallbacks, partial);
3781    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3782    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3783    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3784    
3785      if (common->mode != JIT_COMPILE)
3786        {
3787        nopartial = JUMP(SLJIT_JUMP);
3788        JUMPHERE(partial);
3789        /* TMP2 -= STR_END - STR_PTR */
3790        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3791        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3792        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3793        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3794        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3795        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3796        JUMPHERE(partial);
3797        check_partial(common);
3798        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3799        JUMPHERE(nopartial);
3800        }
3801    }    }
3802    
3803  if (jump != NULL)  if (jump != NULL)
# Line 3354  if (jump != NULL) Line 3807  if (jump != NULL)
3807    else    else
3808      JUMPHERE(jump);      JUMPHERE(jump);
3809    }    }
3810  return cc + 3;  return cc + 1 + IMM2_SIZE;
3811  }  }
3812    
3813  static SLJIT_INLINE uschar *compile_ref_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_ref_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
3814  {  {
3815  DEFINE_COMPILER;  DEFINE_COMPILER;
3816  fallback_common *fallback;  fallback_common *fallback;
3817  uschar type;  pcre_uchar type;
3818  struct sljit_label *label;  struct sljit_label *label;
3819  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3820  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3821  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3822  int min = 0, max = 0;  int min = 0, max = 0;
3823  BOOL minimize;  BOOL minimize;
3824    
3825  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3826    
3827  type = cc[3];  type = cc[1 + IMM2_SIZE];
3828  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3829  switch(type)  switch(type)
3830    {    {
# Line 3379  switch(type) Line 3832  switch(type)
3832    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3833    min = 0;    min = 0;
3834    max = 0;    max = 0;
3835    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3836    break;    break;
3837    case OP_CRPLUS:    case OP_CRPLUS:
3838    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3839    min = 1;    min = 1;
3840    max = 0;    max = 0;
3841    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3842    break;    break;
3843    case OP_CRQUERY:    case OP_CRQUERY:
3844    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3845    min = 0;    min = 0;
3846    max = 1;    max = 1;
3847    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3848    break;    break;
3849    case OP_CRRANGE:    case OP_CRRANGE:
3850    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3851    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3852    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3853    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3854    break;    break;
3855    default:    default:
3856    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3501  decrease_call_count(common); Line 3954  decrease_call_count(common);
3954  return cc;  return cc;
3955  }  }
3956    
3957  static SLJIT_INLINE uschar *compile_recurse_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_recurse_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
3958  {  {
3959  DEFINE_COMPILER;  DEFINE_COMPILER;
3960  fallback_common *fallback;  fallback_common *fallback;
# Line 3547  add_jump(compiler, &fallback->topfallbac Line 4000  add_jump(compiler, &fallback->topfallbac
4000  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4001  }  }
4002    
4003  static uschar *compile_assert_hotpath(compiler_common *common, uschar *cc, assert_fallback *fallback, BOOL conditional)  static pcre_uchar *compile_assert_hotpath(compiler_common *common, pcre_uchar *cc, assert_fallback *fallback, BOOL conditional)
4004  {  {
4005  DEFINE_COMPILER;  DEFINE_COMPILER;
4006  int framesize;  int framesize;
4007  int localptr;  int localptr;
4008  fallback_common altfallback;  fallback_common altfallback;
4009  uschar *ccbegin;  pcre_uchar *ccbegin;
4010  uschar opcode;  pcre_uchar opcode;
4011  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4012  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4013  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4014  jump_list **found;  jump_list **found;
# Line 3571  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4024  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4024    bra = *cc;    bra = *cc;
4025    cc++;    cc++;
4026    }    }
4027  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4028  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4029  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4030  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3630  while (1) Line 4083  while (1)
4083    if (common->accept != NULL)    if (common->accept != NULL)
4084      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
4085    
4086      /* Reset stack. */
4087    if (framesize < 0)    if (framesize < 0)
4088      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4089      else {
4090        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4091          {
4092          /* We don't need to keep the STR_PTR, only the previous localptr. */
4093          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4094          }
4095        else
4096          {
4097          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4098          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4099          }
4100      }
4101    
4102    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4103      {      {
4104      /* 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. */
4105      if (conditional)      if (conditional)
4106        {        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
       if (framesize < 0)  
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);  
       else  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
         }  
       }  
4107      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
4108        {        {
4109        if (framesize < 0)        if (framesize < 0)
4110          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4111        else        else
4112          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
4113          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_w));
4114          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 + 1) * sizeof(sljit_w));
4115          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3661  while (1) Line 4117  while (1)
4117        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_w));
4118        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4119        }        }
4120      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
4121        {        {
4122        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
4123          {        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));  
         }  
4124        }        }
4125      }      }
4126    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3695  if (opcode == OP_ASSERT || opcode == OP_ Line 4147  if (opcode == OP_ASSERT || opcode == OP_
4147    /* Assert is failed. */    /* Assert is failed. */
4148    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
4149      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4150    
4151    if (framesize < 0)    if (framesize < 0)
4152      {      {
4153      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3706  if (opcode == OP_ASSERT || opcode == OP_ Line 4159  if (opcode == OP_ASSERT || opcode == OP_
4159    else    else
4160      {      {
4161      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
     if (framesize > 0)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
4162      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4163      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
4164        {        {
# Line 3717  if (opcode == OP_ASSERT || opcode == OP_ Line 4168  if (opcode == OP_ASSERT || opcode == OP_
4168      else      else
4169        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4170      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
     if (framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
4171      }      }
4172    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4173    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3741  if (opcode == OP_ASSERT || opcode == OP_ Line 4190  if (opcode == OP_ASSERT || opcode == OP_
4190      }      }
4191    else    else
4192      {      {
4193      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      if (bra == OP_BRA)
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
     if (bra == OP_BRAZERO)  
4194        {        {
4195        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4196        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4197          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4198        }        }
4199      else if (bra == OP_BRAMINZERO)      else
4200        {        {
4201        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4202        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
4203          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4204          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4205        }        }
4206      }      }
4207    
# Line 3788  else Line 4238  else
4238      {      {
4239      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4240      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
     if (framesize > 0)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
4241      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4242      if (bra != OP_BRA)      if (bra != OP_BRA)
4243        {        {
# Line 3799  else Line 4247  else
4247      else      else
4248        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4249      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
     if (framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
4250      }      }
4251    
4252    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3824  common->accept = save_accept; Line 4270  common->accept = save_accept;
4270  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4271  }  }
4272    
4273    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4274    {
4275    int condition = FALSE;
4276    pcre_uchar *slotA = name_table;
4277    pcre_uchar *slotB;
4278    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4279    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4280    sljit_w no_capture;
4281    int i;
4282    
4283    locals += OVECTOR_START / sizeof(sljit_w);
4284    no_capture = locals[1];
4285    
4286    for (i = 0; i < name_count; i++)
4287      {
4288      if (GET2(slotA, 0) == refno) break;
4289      slotA += name_entry_size;
4290      }
4291    
4292    if (i < name_count)
4293      {
4294      /* Found a name for the number - there can be only one; duplicate names
4295      for different numbers are allowed, but not vice versa. First scan down
4296      for duplicates. */
4297    
4298      slotB = slotA;
4299      while (slotB > name_table)
4300        {
4301        slotB -= name_entry_size;
4302        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4303          {
4304          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4305          if (condition) break;
4306          }
4307        else break;
4308        }
4309    
4310      /* Scan up for duplicates */
4311      if (!condition)
4312        {
4313        slotB = slotA;
4314        for (i++; i < name_count; i++)
4315          {
4316          slotB += name_entry_size;
4317          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4318            {
4319            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4320            if (condition) break;
4321            }
4322          else break;
4323          }
4324        }
4325      }
4326    return condition;
4327    }
4328    
4329    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4330    {
4331    int condition = FALSE;
4332    pcre_uchar *slotA = name_table;
4333    pcre_uchar *slotB;
4334    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4335    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4336    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4337    int i;
4338    
4339    for (i = 0; i < name_count; i++)
4340      {
4341      if (GET2(slotA, 0) == recno) break;
4342      slotA += name_entry_size;
4343      }
4344    
4345    if (i < name_count)
4346      {
4347      /* Found a name for the number - there can be only one; duplicate
4348      names for different numbers are allowed, but not vice versa. First
4349      scan down for duplicates. */
4350    
4351      slotB = slotA;
4352      while (slotB > name_table)
4353        {
4354        slotB -= name_entry_size;
4355        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4356          {
4357          condition = GET2(slotB, 0) == group_num;
4358          if (condition) break;
4359          }
4360        else break;
4361        }
4362    
4363      /* Scan up for duplicates */
4364      if (!condition)
4365        {
4366        slotB = slotA;
4367        for (i++; i < name_count; i++)
4368          {
4369          slotB += name_entry_size;
4370          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4371            {
4372            condition = GET2(slotB, 0) == group_num;
4373            if (condition) break;
4374            }
4375          else break;
4376          }
4377        }
4378      }
4379    return condition;
4380    }
4381    
4382  /*  /*
4383    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4384    
# Line 3871  return cc + 1 + LINK_SIZE; Line 4426  return cc + 1 + LINK_SIZE;
4426      M - Any values pushed by the current alternative. Can be empty, or anything.      M - Any values pushed by the current alternative. Can be empty, or anything.
4427    
4428    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4429    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4430    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4431    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4432                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4433                                              Or nothing, if trace is unnecessary
4434  */  */
4435    
4436  static uschar *compile_bracket_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static pcre_uchar *compile_bracket_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4437  {  {
4438  DEFINE_COMPILER;  DEFINE_COMPILER;
4439  fallback_common *fallback;  fallback_common *fallback;
4440  uschar opcode;  pcre_uchar opcode;
4441  int localptr = 0;  int localptr = 0;
4442  int offset = 0;  int offset = 0;
4443  int stacksize;  int stacksize;
4444  uschar *ccbegin;  pcre_uchar *ccbegin;
4445  uschar *hotpath;  pcre_uchar *hotpath;
4446  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4447  uschar ket;  pcre_uchar ket;
4448  assert_fallback *assert;  assert_fallback *assert;
4449  BOOL has_alternatives;  BOOL has_alternatives;
4450  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3907  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4463  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4463    
4464  opcode = *cc;  opcode = *cc;
4465  ccbegin = cc;  ccbegin = cc;
4466    hotpath = ccbegin + 1 + LINK_SIZE;
4467    
4468  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
4469    {    {
4470    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3918  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4476  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4476  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4477  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
4478  cc += GET(cc, 1);  cc += GET(cc, 1);
4479  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4480    has_alternatives = *cc == OP_ALT;
4481    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4482      {
4483      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4484      if (*hotpath == OP_NRREF)
4485        {
4486        stacksize = GET2(hotpath, 1);
4487        if (common->currententry == NULL || stacksize == RREF_ANY)
4488          has_alternatives = FALSE;
4489        else if (common->currententry->start == 0)
4490          has_alternatives = stacksize != 0;
4491        else
4492          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4493        }
4494      }
4495    
4496  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4497    opcode = OP_SCOND;    opcode = OP_SCOND;
4498    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4499      opcode = OP_ONCE;
4500    
4501  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4502    {    {
# Line 3929  if (opcode == OP_CBRA || opcode == OP_SC Line 4505  if (opcode == OP_CBRA || opcode == OP_SC
4505    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4506    offset <<= 1;    offset <<= 1;
4507    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4508      hotpath += IMM2_SIZE;
4509    }    }
4510  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4511    {    {
4512    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4513    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4514    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4515    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4516    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4085  else if (has_alternatives) Line 4662  else if (has_alternatives)
4662    }    }
4663    
4664  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4665  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4666    {    {
4667    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4668      {      {
4669        SLJIT_ASSERT(has_alternatives);
4670      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4671        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR((GET2(hotpath, 1) << 1)), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));        CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(GET2(hotpath, 1) << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1)));
4672      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4673        }
4674      else if (*hotpath == OP_NCREF)
4675        {
4676        SLJIT_ASSERT(has_alternatives);
4677        stacksize = GET2(hotpath, 1);
4678        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4679    
4680        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4681        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4682        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4683        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4684        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4685        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4686        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4687        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4688        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4689    
4690        JUMPHERE(jump);
4691        hotpath += 1 + IMM2_SIZE;
4692        }
4693      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4694        {
4695        /* Never has other case. */
4696        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4697    
4698        stacksize = GET2(hotpath, 1);
4699        if (common->currententry == NULL)
4700          stacksize = 0;
4701        else if (stacksize == RREF_ANY)
4702          stacksize = 1;
4703        else if (common->currententry->start == 0)
4704          stacksize = stacksize == 0;
4705        else
4706          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4707    
4708        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4709          {
4710          SLJIT_ASSERT(!has_alternatives);
4711          if (stacksize != 0)
4712            hotpath += 1 + IMM2_SIZE;
4713          else
4714            {
4715            if (*cc == OP_ALT)
4716              {
4717              hotpath = cc + 1 + LINK_SIZE;
4718              cc += GET(cc, 1);
4719              }
4720            else
4721              hotpath = cc;
4722            }
4723          }
4724        else
4725          {
4726          SLJIT_ASSERT(has_alternatives);
4727    
4728          stacksize = GET2(hotpath, 1);
4729          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4730          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4731          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4732          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4733          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4734          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4735          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4736          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4737          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4738          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4739          hotpath += 1 + IMM2_SIZE;
4740          }
4741      }      }
4742    else    else
4743      {      {
4744      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4745      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4746      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4747      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4128  if (opcode == OP_ONCE) Line 4771  if (opcode == OP_ONCE)
4771        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
4772        }        }
4773      }      }
4774    else if (ket == OP_KETRMAX)    else
4775      {      {
4776      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4777      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
4778      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4779          {
4780          /* TMP2 which is set here used by OP_KETRMAX below. */
4781          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4782          }
4783      }      }
4784    }    }
4785    
# Line 4197  if (bra == OP_BRAZERO) Line 4844  if (bra == OP_BRAZERO)
4844  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4845    {    {
4846    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4847    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4848    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4849      {      {
4850      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4225  cc += 1 + LINK_SIZE; Line 4872  cc += 1 + LINK_SIZE;
4872  return cc;  return cc;
4873  }  }
4874    
4875  static uschar *compile_bracketpos_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static pcre_uchar *compile_bracketpos_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4876  {  {
4877  DEFINE_COMPILER;  DEFINE_COMPILER;
4878  fallback_common *fallback;  fallback_common *fallback;
4879  uschar opcode;  pcre_uchar opcode;
4880  int localptr;  int localptr;
4881  int cbraprivptr = 0;  int cbraprivptr = 0;
4882  int framesize;  int framesize;
4883  int stacksize;  int stacksize;
4884  int offset = 0;  int offset = 0;
4885  BOOL zero = FALSE;  BOOL zero = FALSE;
4886  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4887  int stack;  int stack;
4888  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4889  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4249  if (*cc == OP_BRAPOSZERO) Line 4896  if (*cc == OP_BRAPOSZERO)
4896    }    }
4897    
4898  opcode = *cc;  opcode = *cc;
4899  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4900  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4901  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4902  switch(opcode)  switch(opcode)
# Line 4264  switch(opcode) Line 4911  switch(opcode)
4911    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4912    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4913    offset <<= 1;    offset <<= 1;
4914    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4915    break;    break;
4916    
4917    default:    default:
# Line 4366  while (*cc != OP_KETRPOS) Line 5013  while (*cc != OP_KETRPOS)
5013      {      {
5014      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5015        {        {
5016          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
5017        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
5018        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5019        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5020        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
# Line 4376  while (*cc != OP_KETRPOS) Line 5022  while (*cc != OP_KETRPOS)
5022      else      else
5023        {        {
5024        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5025          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
5026        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
5027          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
5028        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
# Line 4384  while (*cc != OP_KETRPOS) Line 5031  while (*cc != OP_KETRPOS)
5031      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
5032        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
5033    
     /* TMP2 must be set above. */  
5034      if (!zero)      if (!zero)
5035        {        {
5036        if (framesize < 0)        if (framesize < 0)
5037          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
5038        else        else
5039          OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5040        }        }
5041      }      }
5042    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4412  while (*cc != OP_KETRPOS) Line 5058  while (*cc != OP_KETRPOS)
5058      {      {
5059      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5060        {        {
5061          /* Last alternative. */
5062        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
5063          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5064        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
# Line 4443  decrease_call_count(common); Line 5090  decrease_call_count(common);
5090  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5091  }  }
5092    
5093  static SLJIT_INLINE uschar *get_iterator_parameters(compiler_common *common, uschar *cc, uschar *opcode, uschar *type, int *arg1, int *arg2, uschar **end)  static SLJIT_INLINE pcre_uchar *get_iterator_parameters(compiler_common *common, pcre_uchar *cc, pcre_uchar *opcode, pcre_uchar *type, int *arg1, int *arg2, pcre_uchar **end)
5094  {  {
5095  int class_len;  int class_len;
5096    
# Line 4482  else Line 5129  else
5129    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5130    *type = *opcode;    *type = *opcode;
5131    cc++;    cc++;
5132    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5133    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5134    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5135      {      {
# Line 4493  else Line 5140  else
5140    else    else
5141      {      {
5142      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
5143      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
5144      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
5145    
5146      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4505  else Line 5152  else
5152        *opcode = OP_EXACT;        *opcode = OP_EXACT;
5153    
5154      if (end != NULL)      if (end != NULL)
5155        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
5156      }      }
5157    return cc;    return cc;
5158    }    }
# Line 4513  else Line 5160  else
5160  if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)  if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
5161    {    {
5162    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
5163    cc += 2;    cc += IMM2_SIZE;
5164    }    }
5165    
5166  if (*type == 0)  if (*type == 0)
# Line 4528  if (*type == 0) Line 5175  if (*type == 0)
5175  if (end != NULL)  if (end != NULL)
5176    {    {
5177    *end = cc + 1;    *end = cc + 1;
5178  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5179    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
5180  #endif  #endif
5181    }    }
5182  return cc;  return cc;
5183  }  }
5184    
5185  static uschar *compile_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
5186  {  {
5187  DEFINE_COMPILER;  DEFINE_COMPILER;
5188  fallback_common *fallback;  fallback_common *fallback;
5189  uschar opcode;  pcre_uchar opcode;
5190  uschar type;  pcre_uchar type;
5191  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5192  uschar* end;  pcre_uchar* end;
5193  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
5194  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5195  struct sljit_label *label;  struct sljit_label *label;
# Line 4704  decrease_call_count(common); Line 5351  decrease_call_count(common);
5351  return end;  return end;
5352  }  }
5353    
5354  static SLJIT_INLINE uschar *compile_fail_accept_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
5355  {  {
5356  DEFINE_COMPILER;  DEFINE_COMPILER;
5357  fallback_common *fallback;  fallback_common *fallback;
# Line 4748  add_jump(compiler, &fallback->topfallbac Line 5395  add_jump(compiler, &fallback->topfallbac
5395  return cc + 1;  return cc + 1;
5396  }  }
5397    
5398  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)
5399  {  {
5400  DEFINE_COMPILER;  DEFINE_COMPILER;
5401  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5402    
5403  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5404  if (common->currententry != NULL)  if (common->currententry != NULL)
5405    return cc + 3;    return cc + 1 + IMM2_SIZE;
5406    
5407  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
5408  offset <<= 1;  offset <<= 1;
5409  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
5410  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5411  return cc + 3;  return cc + 1 + IMM2_SIZE;
5412  }  }
5413    
5414  static void compile_hotpath(compiler_common *common, uschar *cc, uschar *ccend, fallback_common *parent)  static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)
5415  {  {
5416  DEFINE_COMPILER;  DEFINE_COMPILER;
5417  fallback_common *fallback;  fallback_common *fallback;
# Line 4785  while (cc < ccend) Line 5432  while (cc < ccend)
5432      case OP_WORDCHAR:      case OP_WORDCHAR:
5433      case OP_ANY:      case OP_ANY:
5434      case OP_ALLANY:      case OP_ALLANY:
5435        case OP_ANYBYTE:
5436      case OP_NOTPROP:      case OP_NOTPROP:
5437      case OP_PROP:      case OP_PROP:
5438      case OP_ANYNL:      case OP_ANYNL:
# Line 4816  while (cc < ccend) Line 5464  while (cc < ccend)
5464    
5465      case OP_CHAR:      case OP_CHAR:
5466      case OP_CHARI:      case OP_CHARI:
5467      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5468          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5469        else
5470          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5471      break;      break;
5472    
5473      case OP_STAR:      case OP_STAR:
# Line 4889  while (cc < ccend) Line 5540  while (cc < ccend)
5540    
5541      case OP_CLASS:      case OP_CLASS:
5542      case OP_NCLASS:      case OP_NCLASS:
5543      if (cc[33] >= OP_CRSTAR && cc[33] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
5544        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5545      else      else
5546        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5547      break;      break;
5548    
5549  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5550      case OP_XCLASS:      case OP_XCLASS:
5551      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
5552        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 4906  while (cc < ccend) Line 5557  while (cc < ccend)
5557    
5558      case OP_REF:      case OP_REF:
5559      case OP_REFI:      case OP_REFI:
5560      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5561        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5562      else      else
5563        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->next