/[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 792 by ph10, Wed Dec 7 16:44:48 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) (pcre_malloc)(size)  #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56  #define SLJIT_FREE(ptr) (pcre_free)(ptr)  #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 62  system files. */ Line 62  system files. */
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 148  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    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170  } executable_function;  } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 198  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 269  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;
# Line 283  typedef struct compiler_common { Line 284  typedef struct compiler_common {
284    sljit_uw name_table;    sljit_uw name_table;
285    sljit_w name_count;    sljit_w name_count;
286    sljit_w name_entry_size;    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 298  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 317  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 338  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 363  enum { Line 383  enum {
383  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
384  /* Max limit of recursions. */  /* Max limit of recursions. */
385  #define CALL_LIMIT       (5 * 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     (6 * 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    (7 * 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
397  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
398  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
399  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
400  #define OVECTOR_START    (8 * 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 398  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 419  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 475  switch(*cc) Line 513  switch(*cc)
513    return cc + 1;    return cc + 1;
514    
515    case OP_ANYBYTE:    case OP_ANYBYTE:
516  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
517    if (common->utf8) return NULL;    if (common->utf) return NULL;
518  #endif  #endif
519    return cc + 1;    return cc + 1;
520    
# Line 484  switch(*cc) Line 522  switch(*cc)
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 522  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 543  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 562  switch(*cc) Line 601  switch(*cc)
601    case OP_RREF:    case OP_RREF:
602    case OP_NRREF:    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 603  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 636  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 657  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 684  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 707  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);
752  int length = 0;  int length = 0;
753  BOOL possessive = FALSE;  BOOL possessive = FALSE;
754  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
# Line 740  while (cc < ccend) Line 779  while (cc < ccend)
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 758  if (length > 0) Line 797  if (length > 0)
797  return -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  {  {
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  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
808    SLJIT_UNUSED_ARG(stacktop);
809  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
810    
811  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 803  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 816  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 856  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
856  SLJIT_ASSERT(stackpos == STACK(stacktop));  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 842  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 869  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 878  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 939  while (status != end) Line 979  while (status != end)
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 948  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 966  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 1174  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 1198  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 1223  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 * (sljit_w)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 1251  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 1271  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 1300  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 1318  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 1329  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 void check_partial(compiler_common *common)
1456    {
1457    DEFINE_COMPILER;
1458    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 SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1508  {  {
1509  DEFINE_COMPILER;  DEFINE_COMPILER;
1510  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  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 1344  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    #ifdef COMPILE_PCRE8
1550    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    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 1365  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    #ifdef COMPILE_PCRE8
1577    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    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 1385  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    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1608    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1609      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);    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 1448  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 (>= 0xc0). 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;
# Line 1465  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));
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), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1753  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
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, 3);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  
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 (>= 0xc0) 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 1549  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 1566  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 - 0xc0);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
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 1590  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 1610  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_UTF8  #ifdef SUPPORT_UTF
1865  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
1866  #endif  #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 1630  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 1660  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 1672  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  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));
1941  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1942  if (common->utf8)  if (common->utf)
1943      {
1944      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);
1947      JUMPHERE(singlechar);
1948      }
1949    #endif
1950    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1951    if (common->utf)
1952    {    {
1953    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1954    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    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);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1959    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
1960    }    }
1961  #endif  #endif
1962  JUMPHERE(start);  JUMPHERE(start);
# Line 1704  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 1720  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 1744  else Line 2017  else
2017      }      }
2018    }    }
2019    
2020  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));
2021  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2022  if (common->utf8)  if (common->utf)
2023    {    {
2024    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2025    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    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    }    }
2039  #endif  #endif
# Line 1786  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 1826  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 1846  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 1855  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, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2155  #endif  #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
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);
2163  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1867  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    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2171  #endif  #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  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2174  if (common->utf8)  if (common->utf)
2175    {    {
2176    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2177    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);    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);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2190    }    }
2191  #endif  #endif
# Line 1888  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 1897  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 1984  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    
# Line 1996  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2312  sljit_emit_fast_enter(compiler, SLJIT_ME
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 2019  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 2058  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 2089  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 2113  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 2129  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 2147  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 2173  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 2205  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 2229  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 2268  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 2365  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 2396  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 2404  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;
# Line 2414  unsigned int typeoffset; Line 2798  unsigned int typeoffset;
2798  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2799  unsigned int charoffset;  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 2431  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 2449  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 2459  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 2534  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 2564  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 2595  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 2604  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 2661  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 2725  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 2761  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 2769  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 2777  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 2800  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      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));
3201    #ifdef COMPILE_PCRE8
3202      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3203      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);      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]);      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;    return cc;
3221    
3222    case OP_ANYBYTE:    case OP_ANYBYTE:
3223    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3224    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));
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 2836  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 2853  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 2861  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 2869  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 2885  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 2892  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 2938  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 2961  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 2990  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 2998  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 3021  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 3055  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);
3495        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
# Line 3076  switch(type) Line 3501  switch(type)
3501          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 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, SLJIT_IMM, 1);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3505        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3506        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes - 0xc0);        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);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3508        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
3509        return cc + length;        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 3112  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 3129  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 3152  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 3191  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 3216  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 3229  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 3239  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 3249  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 3261  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 3290  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 3315  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 3341  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 3366  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 3488  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 3534  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 3558  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 3804  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, uschar *name_table)  static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4274  {  {
4275  int condition = FALSE;  int condition = FALSE;
4276  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4277  uschar *slotB;  pcre_uchar *slotB;
4278  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4279  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4280  sljit_w no_capture;  sljit_w no_capture;
# Line 3833  if (i < name_count) Line 4299  if (i < name_count)
4299    while (slotB > name_table)    while (slotB > name_table)
4300      {      {
4301      slotB -= name_entry_size;      slotB -= name_entry_size;
4302      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4303        {        {
4304        condition = locals[GET2(slotB, 0) << 1] != no_capture;        condition = locals[GET2(slotB, 0) << 1] != no_capture;
4305        if (condition) break;        if (condition) break;
# Line 3848  if (i < name_count) Line 4314  if (i < name_count)
4314      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4315        {        {
4316        slotB += name_entry_size;        slotB += name_entry_size;
4317        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4318          {          {
4319          condition = locals[GET2(slotB, 0) << 1] != no_capture;          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4320          if (condition) break;          if (condition) break;
# Line 3860  if (i < name_count) Line 4326  if (i < name_count)
4326  return condition;  return condition;
4327  }  }
4328    
4329  static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table)  static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4330  {  {
4331  int condition = FALSE;  int condition = FALSE;
4332  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4333  uschar *slotB;  pcre_uchar *slotB;
4334  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4335  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4336  sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];  sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
# Line 3886  if (i < name_count) Line 4352  if (i < name_count)
4352    while (slotB > name_table)    while (slotB > name_table)
4353      {      {
4354      slotB -= name_entry_size;      slotB -= name_entry_size;
4355      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4356        {        {
4357        condition = GET2(slotB, 0) == group_num;        condition = GET2(slotB, 0) == group_num;
4358        if (condition) break;        if (condition) break;
# Line 3901  if (i < name_count) Line 4367  if (i < name_count)
4367      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4368        {        {
4369        slotB += name_entry_size;        slotB += name_entry_size;
4370        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4371          {          {
4372          condition = GET2(slotB, 0) == group_num;          condition = GET2(slotB, 0) == group_num;
4373          if (condition) break;          if (condition) break;
# Line 3967  return condition; Line 4433  return condition;
4433                                            Or nothing, if trace is unnecessary                                            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 4039  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 += 2;    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 4203  if (opcode == OP_COND || opcode == OP_SC Line 4669  if (opcode == OP_COND || opcode == OP_SC
4669      SLJIT_ASSERT(has_alternatives);      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)    else if (*hotpath == OP_NCREF)
4675      {      {
# Line 4222  if (opcode == OP_COND || opcode == OP_SC Line 4688  if (opcode == OP_COND || opcode == OP_SC
4688      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4689    
4690      JUMPHERE(jump);      JUMPHERE(jump);
4691      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4692      }      }
4693    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4694      {      {
# Line 4243  if (opcode == OP_COND || opcode == OP_SC Line 4709  if (opcode == OP_COND || opcode == OP_SC
4709        {        {
4710        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
4711        if (stacksize != 0)        if (stacksize != 0)
4712          hotpath += 3;          hotpath += 1 + IMM2_SIZE;
4713        else        else
4714          {          {
4715          if (*cc == OP_ALT)          if (*cc == OP_ALT)
# Line 4270  if (opcode == OP_COND || opcode == OP_SC Line 4736  if (opcode == OP_COND || opcode == OP_SC
4736        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        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);        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));        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4739        hotpath += 3;        hotpath += 1 + IMM2_SIZE;
4740        }        }
4741      }      }
4742    else    else
# Line 4378  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 4406  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 4430  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 4445  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 4624  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 4663  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 4674  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 4686  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 4694  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 4709  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 4885  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 4929  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 4998  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 5071  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 5088  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->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);
# Line 5191  SLJIT_ASSERT(cc == ccend); Line 5660  SLJIT_ASSERT(cc == ccend);
5660      } \      } \
5661    while (0)    while (0)
5662    
5663  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5664    
5665  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5666  {  {
5667  DEFINE_COMPILER;  DEFINE_COMPILER;
5668  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5669  uschar opcode;  pcre_uchar opcode;
5670  uschar type;  pcre_uchar type;
5671  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5672  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5673  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5323  switch(opcode) Line 5792  switch(opcode)
5792  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5793  {  {
5794  DEFINE_COMPILER;  DEFINE_COMPILER;
5795  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5796  uschar type;  pcre_uchar type;
5797    
5798  type = cc[3];  type = cc[1 + IMM2_SIZE];
5799  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5800    {    {
5801    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5355  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5824  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5824  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5825  {  {
5826  DEFINE_COMPILER;  DEFINE_COMPILER;
5827  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5828  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5829  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5830    
5831  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5427  int offset = 0; Line 5896  int offset = 0;
5896  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5897  int stacksize;  int stacksize;
5898  int count;  int count;
5899  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5900  uschar *ccbegin;  pcre_uchar *ccbegin;
5901  uschar *ccprev;  pcre_uchar *ccprev;
5902  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5903  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5904  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5905  uschar ket;  pcre_uchar ket;
5906  assert_fallback *assert;  assert_fallback *assert;
5907  BOOL has_alternatives;  BOOL has_alternatives;
5908  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
# Line 5933  while (current) Line 6402  while (current)
6402      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6403      case OP_CLASS:      case OP_CLASS:
6404      case OP_NCLASS:      case OP_NCLASS:
6405    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6406      case OP_XCLASS:      case OP_XCLASS:
6407    #endif
6408      compile_iterator_fallbackpath(common, current);      compile_iterator_fallbackpath(common, current);
6409      break;      break;
6410    
# Line 6000  while (current) Line 6471  while (current)
6471  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
6472  {  {
6473  DEFINE_COMPILER;  DEFINE_COMPILER;
6474  uschar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
6475  uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6476  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
6477  int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
6478  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6479  int alternativesize;  int alternativesize;
# Line 6090  sljit_emit_fast_return(compiler, SLJIT_M Line 6561  sljit_emit_fast_return(compiler, SLJIT_M
6561  #undef CURRENT_AS  #undef CURRENT_AS
6562    
6563  void  void
6564  _pcre_jit_compile(const real_pcre *re, pcre_extra *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6565  {  {
6566  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6567  fallback_common rootfallback;  fallback_common rootfallback;
6568  compiler_common common_data;  compiler_common common_data;
6569  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6570  const uschar *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6571  pcre_study_data *study;  pcre_study_data *study;
6572  uschar *ccend;  pcre_uchar *ccend;
6573  executable_function *function;  executable_functions *functions;
6574  void *executable_func;  void *executable_func;
6575  sljit_uw executable_size;  sljit_uw executable_size;
6576  struct sljit_label *leave;  struct sljit_label *leave;
6577  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6578  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6579  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6580  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6581  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6582  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6583    
# Line 6114  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_ Line 6585  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_
6585  study = extra->study_data;  study = extra->study_data;
6586    
6587  if (!tables)  if (!tables)
6588    tables = _pcre_default_tables;    tables = PRIV(default_tables);
6589    
6590  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6591  rootfallback.cc = (uschar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6592    
6593  common->compiler = NULL;  common->compiler = NULL;
6594  common->start = rootfallback.cc;  common->start = rootfallback.cc;
6595  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6596  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6597  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6598    common->mode = mode;
6599  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6600  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6601    {    {
# Line 6158  else Line 6630  else
6630    }    }
6631  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6632  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6633  common->name_table = (sljit_w)re + re->name_table_offset;  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6634  common->name_count = re->name_count;  common->name_count = re->name_count;
6635  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
6636    common->partialmatchlabel = NULL;
6637  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6638  common->stubs = NULL;  common->stubs = NULL;
6639  common->entries = NULL;  common->entries = NULL;
6640  common->currententry = NULL;  common->currententry = NULL;
6641    common->partialmatch = NULL;
6642  common->accept = NULL;  common->accept = NULL;
6643  common->calllimit = NULL;  common->calllimit = NULL;
6644  common->stackalloc = NULL;  common->stackalloc = NULL;
# Line 6176  common->vspace = NULL; Line 6650  common->vspace = NULL;
6650  common->casefulcmp = NULL;  common->casefulcmp = NULL;
6651  common->caselesscmp = NULL;  common->caselesscmp = NULL;
6652  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6653  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6654  common->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6655    common->utf = (re->options & PCRE_UTF8) != 0;
6656  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6657  common->useucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6658  #endif  #endif
6659  common->utf8readchar = NULL;  common->utfreadchar = NULL;
6660  common->utf8readtype8 = NULL;  #ifdef COMPILE_PCRE8
6661    common->utfreadtype8 = NULL;
6662  #endif  #endif
6663    #endif /* SUPPORT_UTF */
6664  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6665  common->getucd = NULL;  common->getucd = NULL;
6666  #endif  #endif
# Line 6195  if (common->localsize < 0) Line 6672  if (common->localsize < 0)
6672  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6673  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6674    return;    return;
6675  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6676  if (!common->localptrs)  if (!common->localptrs)
6677    return;    return;
6678  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
# Line 6214  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6691  sljit_emit_enter(compiler, 1, 5, 5, comm
6691    
6692  /* Register init. */  /* Register init. */
6693  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6694  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6695    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, SLJIT_TEMPORARY_REG1, 0);
6696    
6697  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6698  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6699  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6700  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6701  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
# Line 6227  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6704  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6704  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6705  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6706    
6707    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6708      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);
6709    
6710  /* Main part of the matching */  /* Main part of the matching */
6711  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6712    {    {
6713    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6714    /* Forward search if possible. */    /* Forward search if possible. */
6715    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6716      fast_forward_first_byte(common, re->first_byte, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6717    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6718      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6719    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6720      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6721    }    }
6722  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6723    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6724    
6725  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6726  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), STR_PTR, 0);
6727  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6728  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6729    /* Copy the beginning of the string. */
6730    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6731      {
6732      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);
6733      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
6734      JUMPHERE(jump);
6735      }
6736    else if (mode == JIT_PARTIAL_HARD_COMPILE)
6737      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
6738    
6739  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6740  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6265  if (common->accept != NULL) Line 6754  if (common->accept != NULL)
6754  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6755  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
6756  leave = LABEL();  leave = LABEL();
6757  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6758    
6759    if (mode != JIT_COMPILE)
6760      {
6761      common->partialmatchlabel = LABEL();
6762      set_jumps(common->partialmatch, common->partialmatchlabel);
6763      return_with_partial_match(common, leave);
6764      }
6765    
6766  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
6767  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
# Line 6278  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6774  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6774    
6775  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
6776    
6777    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6778      {
6779      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
6780      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR);
6781      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, -1);
6782      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, TMP1, 0);
6783      JUMPHERE(jump);
6784      }
6785    
6786  /* Check we have remaining characters. */  /* Check we have remaining characters. */
6787  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6788    
# Line 6285  if ((re->options & PCRE_ANCHORED) == 0) Line 6790  if ((re->options & PCRE_ANCHORED) == 0)
6790    {    {
6791    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
6792      {      {
6793      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6794        {        {
6795        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, study->minlength);        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
6796        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
6797        }        }
6798      else      else
# Line 6295  if ((re->options & PCRE_ANCHORED) == 0) Line 6800  if ((re->options & PCRE_ANCHORED) == 0)
6800      }      }
6801    else    else
6802      {      {
6803      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6804        {        {
6805        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, study->minlength);        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
6806        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
6807        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
6808        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);
# Line 6309  if ((re->options & PCRE_ANCHORED) == 0) Line 6814  if ((re->options & PCRE_ANCHORED) == 0)
6814      }      }
6815    }    }
6816    
6817    /* No more remaining characters. */
6818  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
6819    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6820  /* Copy OVECTOR(1) to OVECTOR(0) */  
6821  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6822      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0, common->partialmatchlabel);
6823    
6824  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6825  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6826    
# Line 6355  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O Line 6863  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O
6863  OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);  OP2(SLJIT_ADD, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, limit), SLJIT_IMM, STACK_GROWTH_RATE);
6864    
6865  sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));  sljit_emit_ijump(compiler, SLJIT_CALL2, SLJIT_IMM, SLJIT_FUNC_OFFSET(sljit_stack_resize));
6866  alloc_error = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0);
6867  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6868  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
6869  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(struct sljit_stack, top));
# Line 6364  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT Line 6872  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT
6872  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
6873    
6874  /* Allocation failed. */  /* Allocation failed. */
6875  JUMPHERE(alloc_error);  JUMPHERE(jump);
6876  /* We break the return address cache here, but this is a really rare case. */  /* We break the return address cache here, but this is a really rare case. */
6877  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_JIT_STACKLIMIT);
6878  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
# Line 6409  if (common->caselesscmp != NULL) Line 6917  if (common->caselesscmp != NULL)
6917    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
6918    do_caselesscmp(common);    do_caselesscmp(common);
6919    }    }
6920  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6921  if (common->utf8readchar != NULL)  if (common->utfreadchar != NULL)
6922    {    {
6923    set_jumps(common->utf8readchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
6924    do_utf8readchar(common);    do_utfreadchar(common);
6925    }    }
6926  if (common->utf8readtype8 != NULL)  #ifdef COMPILE_PCRE8
6927    if (common->utfreadtype8 != NULL)
6928    {    {
6929    set_jumps(common->utf8readtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
6930    do_utf8readtype8(common);    do_utfreadtype8(common);
6931    }    }
6932  #endif  #endif
6933    #endif /* COMPILE_PCRE8 */
6934  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6935  if (common->getucd != NULL)  if (common->getucd != NULL)
6936    {    {
# Line 6436  sljit_free_compiler(compiler); Line 6946  sljit_free_compiler(compiler);
6946  if (executable_func == NULL)  if (executable_func == NULL)
6947    return;    return;
6948    
6949  function = SLJIT_MALLOC(sizeof(executable_function));  /* Reuse the function descriptor if possible. */
6950  if (function == NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
6951      functions = (executable_functions *)extra->executable_jit;
6952    else
6953    {    {
6954    /* This case is highly unlikely since we just recently    functions = SLJIT_MALLOC(sizeof(executable_functions));
6955    freed a lot of memory. Although not impossible. */    if (functions == NULL)
6956    sljit_free_code(executable_func);      {
6957    return;      /* This case is highly unlikely since we just recently
6958        freed a lot of memory. Although not impossible. */
6959        sljit_free_code(executable_func);
6960        return;
6961        }
6962      memset(functions, 0, sizeof(executable_functions));
6963      extra->executable_jit = functions;
6964      extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
6965    }    }
6966    
6967  function->executable_func = executable_func;  functions->executable_funcs[mode] = executable_func;
6968  function->executable_size = executable_size;  functions->executable_sizes[mode] = executable_size;
 function->callback = NULL;  
 function->userdata = NULL;  
 extra->executable_jit = function;  
 extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;  
6969  }  }
6970    
6971  static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)  static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
6972  {  {
6973  union {  union {
6974     void* executable_func;     void* executable_func;
6975     jit_function call_executable_func;     jit_function call_executable_func;
6976  } convert_executable_func;  } convert_executable_func;
6977  uschar local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_area[LOCAL_SPACE_SIZE];
6978  struct sljit_stack local_stack;  struct sljit_stack local_stack;
6979    
6980  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_area;
# Line 6467  local_stack.base = local_stack.top; Line 6982  local_stack.base = local_stack.top;
6982  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
6983  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
6984  arguments->stack = &local_stack;  arguments->stack = &local_stack;
6985  convert_executable_func.executable_func = function->executable_func;  convert_executable_func.executable_func = executable_func;
6986  return convert_executable_func.call_executable_func(arguments);  return convert_executable_func.call_executable_func(arguments);
6987  }  }
6988    
6989  int  int
6990  _pcre_jit_exec(const real_pcre *re, void *executable_func,  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,
6991    PCRE_SPTR subject, int length, int start_offset, int options,    const pcre_uchar *subject, int length, int start_offset, int options,
6992    int match_limit, int *offsets, int offsetcount)    int match_limit, int *offsets, int offsetcount)
6993  {  {
6994  executable_function *function = (executable_function*)executable_func;  executable_functions *functions = (executable_functions *)executable_funcs;
6995  union {  union {
6996     void* executable_func;     void* executable_func;
6997     jit_function call_executable_func;     jit_function call_executable_func;
# Line 6484  union { Line 6999  union {
6999  jit_arguments arguments;  jit_arguments arguments;
7000  int maxoffsetcount;  int maxoffsetcount;
7001  int retval;  int retval;
7002    int mode = JIT_COMPILE;
7003    
7004    if ((options & PCRE_PARTIAL_HARD) != 0)
7005      mode = JIT_PARTIAL_HARD_COMPILE;
7006    else if ((options & PCRE_PARTIAL_SOFT) != 0)
7007      mode = JIT_PARTIAL_SOFT_COMPILE;
7008    
7009    if (functions->executable_funcs[mode] == NULL)
7010      return PCRE_ERROR_NULL;
7011    
7012  /* Sanity checks should be handled by pcre_exec. */  /* Sanity checks should be handled by pcre_exec. */
7013  arguments.stack = NULL;  arguments.stack = NULL;
# Line 6503  workspace. We don't need the workspace h Line 7027  workspace. We don't need the workspace h
7027  number of captured strings in the same way as pcre_exec(), so that the user  number of captured strings in the same way as pcre_exec(), so that the user
7028  gets the same result with and without JIT. */  gets the same result with and without JIT. */
7029    
7030  offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3;  if (offsetcount != 2)
7031      offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
7032  maxoffsetcount = (re->top_bracket + 1) * 2;  maxoffsetcount = (re->top_bracket + 1) * 2;
7033  if (offsetcount > maxoffsetcount)  if (offsetcount > maxoffsetcount)
7034    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
7035  arguments.offsetcount = offsetcount;  arguments.offsetcount = offsetcount;
7036    
7037  if (function->callback)  if (functions->callback)
7038    arguments.stack = (struct sljit_stack*)function->callback(function->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7039  else  else
7040    arguments.stack = (struct sljit_stack*)function->userdata;    arguments.stack = (struct sljit_stack *)functions->userdata;
7041    
7042  if (arguments.stack == NULL)  if (arguments.stack == NULL)
7043    retval = jit_machine_stack_exec(&arguments, function);    retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7044  else  else
7045    {    {
7046    convert_executable_func.executable_func = function->executable_func;    convert_executable_func.executable_func = functions->executable_funcs[mode];
7047    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
7048    }    }
7049    
# Line 6528  return retval; Line 7053  return retval;
7053  }  }
7054    
7055  void  void
7056  _pcre_jit_free(void *executable_func)  PRIV(jit_free)(void *executable_funcs)
7057  {  {
7058  executable_function *function = (executable_function*)executable_func;  int i;
7059  sljit_free_code(function->executable_func);  executable_functions *functions = (executable_functions *)executable_funcs;
7060  SLJIT_FREE(function);  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7061      {
7062      if (functions->executable_funcs[i] != NULL)
7063        sljit_free_code(functions->executable_funcs[i]);
7064      }
7065    SLJIT_FREE(functions);
7066  }  }
7067    
7068  int  int
7069  _pcre_jit_get_size(void *executable_func)  PRIV(jit_get_size)(void *executable_funcs)
7070  {  {
7071  return ((executable_function*)executable_func)->executable_size;  return ((executable_functions *)executable_funcs)->executable_sizes[PCRE_STUDY_JIT_COMPILE];
7072  }  }
7073    
7074    const char*
7075    PRIV(jit_get_target)(void)
7076    {
7077    return sljit_get_platform_name();
7078    }
7079    
7080    #ifdef COMPILE_PCRE8
7081  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
7082  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
7083    #else
7084    PCRE_EXP_DECL pcre16_jit_stack *
7085    pcre16_jit_stack_alloc(int startsize, int maxsize)
7086    #endif
7087  {  {
7088  if (startsize < 1 || maxsize < 1)  if (startsize < 1 || maxsize < 1)
7089    return NULL;    return NULL;
# Line 6550  if (startsize > maxsize) Line 7091  if (startsize > maxsize)
7091    startsize = maxsize;    startsize = maxsize;
7092  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
7093  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
7094  return (pcre_jit_stack*)sljit_allocate_stack(startsize, maxsize);  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
7095  }  }
7096    
7097    #ifdef COMPILE_PCRE8
7098  PCRE_EXP_DECL void  PCRE_EXP_DECL void
7099  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
7100    #else
7101    PCRE_EXP_DECL void
7102    pcre16_jit_stack_free(pcre16_jit_stack *stack)
7103    #endif
7104  {  {
7105  sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack *)stack);
7106  }  }
7107    
7108    #ifdef COMPILE_PCRE8
7109  PCRE_EXP_DECL void  PCRE_EXP_DECL void
7110  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
7111    #else
7112    PCRE_EXP_DECL void
7113    pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
7114    #endif
7115  {  {