/[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 918 by zherczeg, Thu Feb 16 06:39:20 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, BOOL force)
1456    {
1457    /* Checks whether a partial matching is occured. Does not modify registers. */
1458    DEFINE_COMPILER;
1459    struct sljit_jump *jump = NULL;
1460    
1461    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1462    
1463    if (common->mode == JIT_COMPILE)
1464      return;
1465    
1466    if (!force || common->mode == JIT_PARTIAL_SOFT_COMPILE)
1467      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1468    
1469    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1470      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1471    else
1472      {
1473      if (common->partialmatchlabel != NULL)
1474        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1475      else
1476        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1477      }
1478    
1479    if (jump != NULL)
1480      JUMPHERE(jump);
1481    }
1482    
1483    static struct sljit_jump *check_str_end(compiler_common *common)
1484    {
1485    /* Does not affect registers. Usually used in a tight spot. */
1486    DEFINE_COMPILER;
1487    struct sljit_jump *jump;
1488    struct sljit_jump *nohit;
1489    struct sljit_jump *return_value;
1490    
1491    if (common->mode == JIT_COMPILE)
1492      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1493    
1494    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1495    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1496      {
1497      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1498      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1499      JUMPHERE(nohit);
1500      return_value = JUMP(SLJIT_JUMP);
1501      }
1502    else
1503      {
1504      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
1505      if (common->partialmatchlabel != NULL)
1506        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1507      else
1508        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1509      }
1510    JUMPHERE(jump);
1511    return return_value;
1512  }  }
1513    
1514  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)
1515  {  {
1516  DEFINE_COMPILER;  DEFINE_COMPILER;
1517  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1518    
1519    if (common->mode == JIT_COMPILE)
1520      {
1521      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1522      return;
1523      }
1524    
1525    /* Partial matching mode. */
1526    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1527    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0));
1528    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1529      {
1530      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
1531      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1532      }
1533    else
1534      {
1535      if (common->partialmatchlabel != NULL)
1536        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1537      else
1538        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1539      }
1540    JUMPHERE(jump);
1541  }  }
1542    
1543  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1344  static void read_char(compiler_common *c Line 1545  static void read_char(compiler_common *c
1545  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1546  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1547  DEFINE_COMPILER;  DEFINE_COMPILER;
1548  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1549  struct sljit_jump *jump;  struct sljit_jump *jump;
1550  #endif  #endif
1551    
1552  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1553  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1554  if (common->utf8)  if (common->utf)
1555    {    {
1556    #ifdef COMPILE_PCRE8
1557    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1558    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1559    #ifdef COMPILE_PCRE16
1560      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1561    #endif
1562    #endif /* COMPILE_PCRE8 */
1563      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1564    JUMPHERE(jump);    JUMPHERE(jump);
1565    }    }
1566  #endif  #endif
1567  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));
1568  }  }
1569    
1570  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1365  static void peek_char(compiler_common *c Line 1572  static void peek_char(compiler_common *c
1572  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1573  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1574  DEFINE_COMPILER;  DEFINE_COMPILER;
1575  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1576  struct sljit_jump *jump;  struct sljit_jump *jump;
1577  #endif  #endif
1578    
1579  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1580  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1581  if (common->utf8)  if (common->utf)
1582    {    {
1583    #ifdef COMPILE_PCRE8
1584    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1585    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1586    #ifdef COMPILE_PCRE16
1587      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1588    #endif
1589    #endif /* COMPILE_PCRE8 */
1590      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1591    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1592    JUMPHERE(jump);    JUMPHERE(jump);
1593    }    }
# Line 1385  static void read_char8_type(compiler_com Line 1598  static void read_char8_type(compiler_com
1598  {  {
1599  /* 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. */
1600  DEFINE_COMPILER;  DEFINE_COMPILER;
1601  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1602  struct sljit_jump *jump;  struct sljit_jump *jump;
1603  #endif  #endif
1604    
1605  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1606  if (common->utf8)  if (common->utf)
1607    {    {
1608    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1609    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));
1610    #ifdef COMPILE_PCRE8
1611    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1612    it is a clever early read in most cases. */    it is needed in most cases. */
1613    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1614    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1615    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1616      JUMPHERE(jump);
1617    #else
1618    #ifdef COMPILE_PCRE16
1619      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1620      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1621      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1622    JUMPHERE(jump);    JUMPHERE(jump);
1623      /* Skip low surrogate if necessary. */
1624      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1625      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1626      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1627      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1628      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1629    #endif
1630    #endif /* COMPILE_PCRE8 */
1631    return;    return;
1632    }    }
1633  #endif  #endif
1634  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1635  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));
1636  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1637    /* The ctypes array contains only 256 values. */
1638    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1639    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1640    #endif
1641    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1642    #ifdef COMPILE_PCRE16
1643    JUMPHERE(jump);
1644    #endif
1645  }  }
1646    
1647  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1648  {  {
1649  /* 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. */
1650  DEFINE_COMPILER;  DEFINE_COMPILER;
1651  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1652  struct sljit_label *label;  struct sljit_label *label;
1653    
1654  if (common->utf8)  if (common->utf)
1655    {    {
1656    label = LABEL();    label = LABEL();
1657    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1658    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));
1659    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1660    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1661    return;    return;
1662    }    }
1663  #endif  #endif
1664  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1665    if (common->utf)
1666      {
1667      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1668      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1669      /* Skip low surrogate if necessary. */
1670      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1671      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1672      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1673      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1674      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1675      return;
1676      }
1677    #endif
1678    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1679  }  }
1680    
1681  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 1698  else if (nltype == NLTYPE_ANYCRLF)
1698    }    }
1699  else  else
1700    {    {
1701    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1702    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));
1703    }    }
1704  }  }
1705    
1706  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1707  static void do_utf8readchar(compiler_common *common)  
1708    #ifdef COMPILE_PCRE8
1709    static void do_utfreadchar(compiler_common *common)
1710  {  {
1711  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1712  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. */
1713  DEFINE_COMPILER;  DEFINE_COMPILER;
1714  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 1465  sljit_emit_fast_enter(compiler, RETURN_A Line 1717  sljit_emit_fast_enter(compiler, RETURN_A
1717  /* Searching for the first zero. */  /* Searching for the first zero. */
1718  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);
1719  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1720  /* 2 byte sequence */  /* Two byte sequence. */
1721  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1722  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));
1723  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1724  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1725  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1726  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1727  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1728  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1729  JUMPHERE(jump);  JUMPHERE(jump);
1730    
1731  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);
1732  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1733  /* 3 byte sequence */  /* Three byte sequence. */
1734  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1735  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1736  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1737  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1738  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1739  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1740  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1741  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));
1742  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1743  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1744  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1745  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1746  JUMPHERE(jump);  JUMPHERE(jump);
1747    
1748  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1749  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);  
1750  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1751  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1752  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1753  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1754  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1755  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
1756  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1757  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1758  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1759  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1760  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1761  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1762  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1763  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1764  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1765  }  }
1766    
1767  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1768  {  {
1769  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1770  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1771  DEFINE_COMPILER;  DEFINE_COMPILER;
1772  struct sljit_jump *jump;  struct sljit_jump *jump;
1773  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1549  sljit_emit_fast_enter(compiler, RETURN_A Line 1776  sljit_emit_fast_enter(compiler, RETURN_A
1776    
1777  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);
1778  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1779  /* 2 byte sequence */  /* Two byte sequence. */
1780  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1781  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));
1782  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1783  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1784  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 1793  sljit_emit_fast_return(compiler, RETURN_
1793  JUMPHERE(jump);  JUMPHERE(jump);
1794    
1795  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1796  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);
1797  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1798  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1799  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1800  }  }
1801    
1802  #endif  #else /* COMPILE_PCRE8 */
1803    
1804    #ifdef COMPILE_PCRE16
1805    static void do_utfreadchar(compiler_common *common)
1806    {
1807    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1808    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1809    DEFINE_COMPILER;
1810    struct sljit_jump *jump;
1811    
1812    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1813    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1814    /* Do nothing, only return. */
1815    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1816    
1817    JUMPHERE(jump);
1818    /* Combine two 16 bit characters. */
1819    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1820    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1821    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1822    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1823    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1824    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1825    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1826    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1827    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1828    }
1829    #endif /* COMPILE_PCRE16 */
1830    
1831    #endif /* COMPILE_PCRE8 */
1832    
1833    #endif /* SUPPORT_UTF */
1834    
1835  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1836    
# Line 1590  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1848  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1848    
1849  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);
1850  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1851  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));
1852  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1853  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1854  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1855  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1856  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1857  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));
1858  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1859  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1860  }  }
# Line 1610  struct sljit_label *newlinelabel = NULL; Line 1868  struct sljit_label *newlinelabel = NULL;
1868  struct sljit_jump *start;  struct sljit_jump *start;
1869  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1870  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1871  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1872  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
1873  #endif  #endif
1874  jump_list *newline = NULL;  jump_list *newline = NULL;
1875  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1876  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1877    
1878  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1879      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1630  if (firstline) Line 1888  if (firstline)
1888    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1889      {      {
1890      mainloop = LABEL();      mainloop = LABEL();
1891      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));
1892      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1893      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1894      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1895      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);
1896      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);
1897      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));
1898      }      }
1899    else    else
1900      {      {
# Line 1660  start = JUMP(SLJIT_JUMP); Line 1918  start = JUMP(SLJIT_JUMP);
1918  if (newlinecheck)  if (newlinecheck)
1919    {    {
1920    newlinelabel = LABEL();    newlinelabel = LABEL();
1921    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));
1922    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1923    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1924    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);
1925    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1926    #ifdef COMPILE_PCRE16
1927      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1928    #endif
1929    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1930    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1931    }    }
# Line 1672  if (newlinecheck) Line 1933  if (newlinecheck)
1933  mainloop = LABEL();  mainloop = LABEL();
1934    
1935  /* 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. */
1936  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1937  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1938  #endif  #endif
1939  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1940    
1941  if (readbyte)  if (readuchar)
1942    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1943    
1944  if (newlinecheck)  if (newlinecheck)
1945    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);
1946    
1947  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));
1948  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1949  if (common->utf8)  if (common->utf)
1950      {
1951      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1952      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1953      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1954      JUMPHERE(singlechar);
1955      }
1956    #endif
1957    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1958    if (common->utf)
1959    {    {
1960    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1961    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);
1962      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1963      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1964      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1965    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1966    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
1967    }    }
1968  #endif  #endif
1969  JUMPHERE(start);  JUMPHERE(start);
# Line 1704  if (newlinecheck) Line 1977  if (newlinecheck)
1977  return mainloop;  return mainloop;
1978  }  }
1979    
1980  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)
1981  {  {
1982  DEFINE_COMPILER;  DEFINE_COMPILER;
1983  struct sljit_label *start;  struct sljit_label *start;
1984  struct sljit_jump *leave;  struct sljit_jump *leave;
1985  struct sljit_jump *found;  struct sljit_jump *found;
1986  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1987    
1988  if (firstline)  if (firstline)
1989    {    {
# Line 1720  if (firstline) Line 1993  if (firstline)
1993    
1994  start = LABEL();  start = LABEL();
1995  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1996  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1997    
1998  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1999    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2000      {
2001      oc = TABLE_GET(first_char, common->fcc, first_char);
2002    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2003      if (first_char > 127 && common->utf)
2004        oc = UCD_OTHERCASE(first_char);
2005    #endif
2006      }
2007    if (first_char == oc)
2008      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2009  else  else
2010    {    {
2011    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2012    if (ispowerof2(bit))    if (ispowerof2(bit))
2013      {      {
2014      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2015      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2016      }      }
2017    else    else
2018      {      {
2019      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);
2020      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2021      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);
2022      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 2024  else
2024      }      }
2025    }    }
2026    
2027  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));
2028  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2029  if (common->utf8)  if (common->utf)
2030    {    {
2031    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2032    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);
2033      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2034      }
2035    #endif
2036    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2037    if (common->utf)
2038      {
2039      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2040      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2041      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2042      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2043      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2044    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2045    }    }
2046  #endif  #endif
# Line 1786  if (common->nltype == NLTYPE_FIXED && co Line 2077  if (common->nltype == NLTYPE_FIXED && co
2077    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));
2078    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2079    
2080    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2081    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);
2082    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2083    #ifdef COMPILE_PCRE16
2084      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2085    #endif
2086    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2087    
2088    loop = LABEL();    loop = LABEL();
2089    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));
2090    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2091    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2092    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2093    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);
2094    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);
2095    
# Line 1826  if (common->nltype == NLTYPE_ANY || comm Line 2120  if (common->nltype == NLTYPE_ANY || comm
2120    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2121    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2122    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2123    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2124    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);
2125    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2126    #ifdef COMPILE_PCRE16
2127      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2128    #endif
2129    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2130    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2131    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1846  DEFINE_COMPILER; Line 2143  DEFINE_COMPILER;
2143  struct sljit_label *start;  struct sljit_label *start;
2144  struct sljit_jump *leave;  struct sljit_jump *leave;
2145  struct sljit_jump *found;  struct sljit_jump *found;
2146    #ifndef COMPILE_PCRE8
2147    struct sljit_jump *jump;
2148    #endif
2149    
2150  if (firstline)  if (firstline)
2151    {    {
# Line 1855  if (firstline) Line 2155  if (firstline)
2155    
2156  start = LABEL();  start = LABEL();
2157  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2158  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2159  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2160  if (common->utf8)  if (common->utf)
2161    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2162  #endif  #endif
2163    #ifndef COMPILE_PCRE8
2164    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2165    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2166    JUMPHERE(jump);
2167    #endif
2168  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2169  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2170  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 2172  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2172  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);
2173  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2174    
2175  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2176  if (common->utf8)  if (common->utf)
2177    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2178  #endif  #endif
2179  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));
2180  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2181  if (common->utf8)  if (common->utf)
2182    {    {
2183    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2184    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);
2185      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2186      }
2187    #endif
2188    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2189    if (common->utf)
2190      {
2191      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2192      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2193      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2194      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2195      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2196    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2197    }    }
2198  #endif  #endif
# Line 1888  if (firstline) Line 2204  if (firstline)
2204    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2205  }  }
2206    
2207  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)
2208  {  {
2209  DEFINE_COMPILER;  DEFINE_COMPILER;
2210  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1897  struct sljit_jump *alreadyfound; Line 2213  struct sljit_jump *alreadyfound;
2213  struct sljit_jump *found;  struct sljit_jump *found;
2214  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2215  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2216  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2217    
2218  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);
2219  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);
2220  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2221  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2222    
2223  if (has_firstbyte)  if (has_firstchar)
2224    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2225  else  else
2226    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2227    
2228  loop = LABEL();  loop = LABEL();
2229  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2230    
2231  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2232  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2233    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2234      {
2235      oc = TABLE_GET(req_char, common->fcc, req_char);
2236    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2237      if (req_char > 127 && common->utf)
2238        oc = UCD_OTHERCASE(req_char);
2239    #endif
2240      }
2241    if (req_char == oc)
2242      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2243  else  else
2244    {    {
2245    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2246    if (ispowerof2(bit))    if (ispowerof2(bit))
2247      {      {
2248      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2249      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2250      }      }
2251    else    else
2252      {      {
2253      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2254      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2255      }      }
2256    }    }
2257  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2258  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2259    
2260  JUMPHERE(found);  JUMPHERE(found);
2261  if (foundoc)  if (foundoc)
2262    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2263  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);
2264  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2265  JUMPHERE(toolong);  JUMPHERE(toolong);
2266  return notfound;  return notfound;
# Line 1984  JUMPTO(SLJIT_JUMP, mainloop); Line 2307  JUMPTO(SLJIT_JUMP, mainloop);
2307  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2308  {  {
2309  DEFINE_COMPILER;  DEFINE_COMPILER;
2310  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2311  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2312  struct sljit_jump *jump;  struct sljit_jump *jump;
2313  #endif  #endif
2314    
# Line 1996  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2319  sljit_emit_fast_enter(compiler, SLJIT_ME
2319  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2320  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));
2321  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2322  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2323  skip_char_back(common);  skip_char_back(common);
2324    check_start_used_ptr(common);
2325  read_char(common);  read_char(common);
2326    
2327  /* Testing char type. */  /* Testing char type. */
2328  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2329  if (common->useucp)  if (common->use_ucp)
2330    {    {
2331    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2332    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 2343  if (common->useucp)
2343  else  else
2344  #endif  #endif
2345    {    {
2346  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2347      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2348    #elif defined SUPPORT_UTF
2349    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2350    jump = NULL;    jump = NULL;
2351    if (common->utf8)    if (common->utf)
2352      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2353  #endif  #endif /* COMPILE_PCRE8 */
2354    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2355    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2356    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2357    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2358  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2359      JUMPHERE(jump);
2360    #elif defined SUPPORT_UTF
2361    if (jump != NULL)    if (jump != NULL)
2362      JUMPHERE(jump);      JUMPHERE(jump);
2363  #endif  #endif /* COMPILE_PCRE8 */
2364    }    }
2365  JUMPHERE(beginend);  JUMPHERE(skipread);
2366    
2367  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2368  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2369  peek_char(common);  peek_char(common);
2370    
2371  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2372  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2373  if (common->useucp)  if (common->use_ucp)
2374    {    {
2375    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2376    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 2386  if (common->useucp)
2386  else  else
2387  #endif  #endif
2388    {    {
2389  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2390      /* TMP2 may be destroyed by peek_char. */
2391      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2392      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2393    #elif defined SUPPORT_UTF
2394    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2395    jump = NULL;    jump = NULL;
2396    if (common->utf8)    if (common->utf)
2397      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2398  #endif  #endif
2399    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2400    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2401    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2402  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2403      JUMPHERE(jump);
2404    #elif defined SUPPORT_UTF
2405    if (jump != NULL)    if (jump != NULL)
2406      JUMPHERE(jump);      JUMPHERE(jump);
2407  #endif  #endif /* COMPILE_PCRE8 */
2408    }    }
2409  JUMPHERE(beginend);  JUMPHERE(skipread);
2410    
2411  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);
2412  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 2423  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2423  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);
2424  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2425  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);
2426  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2427  if (common->utf8)  #ifdef COMPILE_PCRE8
2428    if (common->utf)
2429    {    {
2430    #endif
2431    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2432    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2433    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);
2434    #ifdef COMPILE_PCRE8
2435    }    }
2436  #endif  #endif
2437    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2438  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2439  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2440  }  }
# Line 2113  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2451  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2451  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);
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, 0xa0);  OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xa0);
2454  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2455  if (common->utf8)  #ifdef COMPILE_PCRE8
2456    if (common->utf)
2457    {    {
2458    #endif
2459    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2460    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);
2461    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2129  if (common->utf8) Line 2469  if (common->utf8)
2469    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);
2470    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2471    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);
2472    #ifdef COMPILE_PCRE8
2473    }    }
2474  #endif  #endif
2475    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2476  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2477    
2478  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 2489  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2489  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);
2490  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2491  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);
2492  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2493  if (common->utf8)  #ifdef COMPILE_PCRE8
2494    if (common->utf)
2495    {    {
2496    #endif
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    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2499    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);
2500    #ifdef COMPILE_PCRE8
2501    }    }
2502  #endif  #endif
2503    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2504  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2505    
2506  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 2519  sljit_emit_fast_enter(compiler, RETURN_A
2519  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2520  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2521  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2522  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2523  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));
2524    
2525  label = LABEL();  label = LABEL();
2526  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2527  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2528  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2529  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));
2530  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2531    
2532  JUMPHERE(jump);  JUMPHERE(jump);
2533  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));
2534  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2535  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2536  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 2551  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2551  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2552  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2553  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2554  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2555  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));
2556    
2557  label = LABEL();  label = LABEL();
2558  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2559  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2560    #ifndef COMPILE_PCRE8
2561    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2562    #endif
2563  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2564    #ifndef COMPILE_PCRE8
2565    JUMPHERE(jump);
2566    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2567    #endif
2568  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2569    #ifndef COMPILE_PCRE8
2570    JUMPHERE(jump);
2571    #endif
2572  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2573  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));
2574  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2575    
2576  JUMPHERE(jump);  JUMPHERE(jump);
2577  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));
2578  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2579  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2580  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 2585  sljit_emit_fast_return(compiler, RETURN_
2585  #undef CHAR1  #undef CHAR1
2586  #undef CHAR2  #undef CHAR2
2587    
2588  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2589    
2590  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)
2591  {  {
2592  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2593  int c1, c2;  int c1, c2;
2594  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2595  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2596    
2597  while (src1 < end1)  while (src1 < end1)
2598    {    {
2599    if (src2 >= end2)    if (src2 >= end2)
2600      return 0;      return (pcre_uchar*)1;
2601    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2602    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2603    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2604    }    }
2605  return src2;  return src2;
2606  }  }
2607    
2608  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2609    
2610  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,
2611      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2612  {  {
2613  DEFINE_COMPILER;  DEFINE_COMPILER;
2614  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2615  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2616  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2617  int utf8length;  int utflength;
2618  #endif  #endif
2619    
2620  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2268  if (caseless && char_has_othercase(commo Line 2622  if (caseless && char_has_othercase(commo
2622    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2623    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2624    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2625    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2626      othercasechar = cc + (othercasebit >> 8);
2627    othercasebit &= 0xff;    othercasebit &= 0xff;
2628    #else
2629    #ifdef COMPILE_PCRE16
2630      othercasechar = cc + (othercasebit >> 9);
2631      if ((othercasebit & 0x100) != 0)
2632        othercasebit = (othercasebit & 0xff) << 8;
2633      else
2634        othercasebit &= 0xff;
2635    #endif
2636    #endif
2637    }    }
2638    
2639  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2640    {    {
2641    #ifdef COMPILE_PCRE8
2642  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2643    if (context->length >= 4)    if (context->length >= 4)
2644      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2645    else if (context->length >= 2)    else if (context->length >= 2)
2646      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2647    else    else
2648  #endif  #endif
2649      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2650    #else
2651    #ifdef COMPILE_PCRE16
2652    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2653      if (context->length >= 4)
2654        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2655      else
2656    #endif
2657        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2658    #endif
2659    #endif /* COMPILE_PCRE8 */
2660    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2661    }    }
2662    
2663  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2664  utf8length = 1;  utflength = 1;
2665  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2666    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2667    
2668  do  do
2669    {    {
2670  #endif  #endif
2671    
2672    context->length--;    context->length -= IN_UCHARS(1);
2673  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2674    
2675    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2676    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2677      {      {
2678      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2679      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2680      }      }
2681    else    else
2682      {      {
2683      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2684      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2685      }      }
2686    context->byteptr++;    context->ucharptr++;
2687    
2688    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2689      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2690    #else
2691      if (context->ucharptr >= 2 || context->length == 0)
2692    #endif
2693      {      {
2694      if (context->length >= 4)      if (context->length >= 4)
2695        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);
2696    #ifdef COMPILE_PCRE8
2697      else if (context->length >= 2)      else if (context->length >= 2)
2698        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);
2699      else if (context->length >= 1)      else if (context->length >= 1)
2700        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);
2701    #else
2702        else if (context->length >= 2)
2703          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2704    #endif
2705      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2706    
2707      switch(context->byteptr)      switch(context->ucharptr)
2708        {        {
2709        case 4:        case 4 / sizeof(pcre_uchar):
2710        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2711          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);
2712        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));
2713        break;        break;
2714    
2715        case 2:        case 2 / sizeof(pcre_uchar):
2716        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2717          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);
2718        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));
2719        break;        break;
2720    
2721    #ifdef COMPILE_PCRE8
2722        case 1:        case 1:
2723        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2724          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);
2725        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));
2726        break;        break;
2727    #endif
2728    
2729        default:        default:
2730        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2731        break;        break;
2732        }        }
2733      context->byteptr = 0;      context->ucharptr = 0;
2734      }      }
2735    
2736  #else  #else
2737    
2738    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2739    #ifdef COMPILE_PCRE8
2740    if (context->length > 0)    if (context->length > 0)
2741      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);
2742    #else
2743      if (context->length > 0)
2744        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2745    #endif
2746    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2747    
2748    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2749      {      {
2750      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2751      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 2756  do
2756  #endif  #endif
2757    
2758    cc++;    cc++;
2759  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2760    utf8length--;    utflength--;
2761    }    }
2762  while (utf8length > 0);  while (utflength > 0);
2763  #endif  #endif
2764    
2765  return cc;  return cc;
2766  }  }
2767    
2768  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2769    
2770  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2771    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2396  return cc; Line 2787  return cc;
2787      } \      } \
2788    charoffset = (value);    charoffset = (value);
2789    
2790  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)
2791  {  {
2792  DEFINE_COMPILER;  DEFINE_COMPILER;
2793  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2404  jump_list **list = (*cc & XCL_NOT) == 0 Line 2795  jump_list **list = (*cc & XCL_NOT) == 0
2795  unsigned int c;  unsigned int c;
2796  int compares;  int compares;
2797  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2798  uschar *ccbegin;  pcre_uchar *ccbegin;
2799  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2800  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2801  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2414  unsigned int typeoffset; Line 2805  unsigned int typeoffset;
2805  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2806  unsigned int charoffset;  unsigned int charoffset;
2807    
2808  /* 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. */
2809  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2810  read_char(common);  read_char(common);
2811    
2812  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2813    {    {
2814    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2815    if (common->utf8)  #ifndef COMPILE_PCRE8
2816      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2817    #elif defined SUPPORT_UTF
2818      if (common->utf)
2819      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2820    #endif
2821    
2822    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2823    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 2826  if ((*cc++ & XCL_MAP) != 0)
2826    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);
2827    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2828    
2829    if (common->utf8)  #ifndef COMPILE_PCRE8
2830      JUMPHERE(jump);
2831    #elif defined SUPPORT_UTF
2832      if (common->utf)
2833      JUMPHERE(jump);      JUMPHERE(jump);
2834    #endif
2835    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2836  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2837    charsaved = TRUE;    charsaved = TRUE;
2838  #endif  #endif
2839    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2840    }    }
2841    
2842  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2449  while (*cc != XCL_END) Line 2848  while (*cc != XCL_END)
2848    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2849      {      {
2850      cc += 2;      cc += 2;
2851  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2852      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]);
2853  #endif  #endif
2854  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2855      needschar = TRUE;      needschar = TRUE;
# Line 2459  while (*cc != XCL_END) Line 2858  while (*cc != XCL_END)
2858    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2859      {      {
2860      cc += 2;      cc += 2;
2861  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2862      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]);
2863  #endif  #endif
2864      cc++;      cc++;
2865  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2866      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]);
2867  #endif  #endif
2868  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2869      needschar = TRUE;      needschar = TRUE;
# Line 2534  if (needstype || needsscript) Line 2933  if (needstype || needsscript)
2933      {      {
2934      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2935        {        {
2936        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));
2937        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2938        }        }
2939      else      else
2940        {        {
2941        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2942        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));
2943        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2944        }        }
2945      }      }
# Line 2564  while (*cc != XCL_END) Line 2963  while (*cc != XCL_END)
2963    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2964      {      {
2965      cc ++;      cc ++;
2966  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2967      if (common->utf8)      if (common->utf)
2968        {        {
2969        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2970        }        }
# Line 2595  while (*cc != XCL_END) Line 2994  while (*cc != XCL_END)
2994    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2995      {      {
2996      cc ++;      cc ++;
2997  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2998      if (common->utf8)      if (common->utf)
2999        {        {
3000        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3001        }        }
# Line 2604  while (*cc != XCL_END) Line 3003  while (*cc != XCL_END)
3003  #endif  #endif
3004        c = *cc++;        c = *cc++;
3005      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3006  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3007      if (common->utf8)      if (common->utf)
3008        {        {
3009        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3010        }        }
# Line 2661  while (*cc != XCL_END) Line 3060  while (*cc != XCL_END)
3060        break;        break;
3061    
3062        case PT_GC:        case PT_GC:
3063        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3064        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3065        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);
3066        break;        break;
3067    
3068        case PT_PC:        case PT_PC:
# Line 2725  if (found != NULL) Line 3124  if (found != NULL)
3124    
3125  #endif  #endif
3126    
3127  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)
3128  {  {
3129  DEFINE_COMPILER;  DEFINE_COMPILER;
3130  int length;  int length;
3131  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3132  compare_context context;  compare_context context;
3133  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3134  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3135  struct sljit_label *label;  struct sljit_label *label;
3136  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3137  uschar propdata[5];  pcre_uchar propdata[5];
3138  #endif  #endif
3139  #endif  #endif
3140    
# Line 2761  switch(type) Line 3160  switch(type)
3160    
3161    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3162    case OP_DIGIT:    case OP_DIGIT:
3163    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3164    read_char8_type(common);    read_char8_type(common);
3165    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);
3166    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 3168  switch(type)
3168    
3169    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3170    case OP_WHITESPACE:    case OP_WHITESPACE:
3171    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3172    read_char8_type(common);    read_char8_type(common);
3173    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);
3174    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 3176  switch(type)
3176    
3177    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3178    case OP_WORDCHAR:    case OP_WORDCHAR:
3179    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3180    read_char8_type(common);    read_char8_type(common);
3181    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);
3182    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));
3183    return cc;    return cc;
3184    
3185    case OP_ANY:    case OP_ANY:
3186    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3187    read_char(common);    read_char(common);
3188    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3189      {      {
3190      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);
3191      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode == JIT_COMPILE)
3192      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3193        else
3194          {
3195          jump[1] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3196          /* Since we successfully read a char above, partial matching must occure. */
3197          check_partial(common, TRUE);
3198          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3199          JUMPHERE(jump[1]);
3200          jump[1] = NULL;
3201          }
3202    
3203        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3204      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));
3205      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3206          JUMPHERE(jump[1]);
3207      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3208      }      }
3209    else    else
# Line 2800  switch(type) Line 3211  switch(type)
3211    return cc;    return cc;
3212    
3213    case OP_ALLANY:    case OP_ALLANY:
3214    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3215  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3216    if (common->utf8)    if (common->utf)
3217      {      {
3218      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
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    #ifdef COMPILE_PCRE8
3221      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3222      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);
3223        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3224    #else /* COMPILE_PCRE8 */
3225    #ifdef COMPILE_PCRE16
3226        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3227        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3228        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3229        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3230        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3231      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3232    #endif /* COMPILE_PCRE16 */
3233    #endif /* COMPILE_PCRE8 */
3234      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3235      return cc;      return cc;
3236      }      }
3237  #endif  #endif
3238    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));
3239    return cc;    return cc;
3240    
3241    case OP_ANYBYTE:    case OP_ANYBYTE:
3242    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3243    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));
3244    return cc;    return cc;
3245    
3246  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3247  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3248    case OP_NOTPROP:    case OP_NOTPROP:
3249    case OP_PROP:    case OP_PROP:
# Line 2836  switch(type) Line 3258  switch(type)
3258  #endif  #endif
3259    
3260    case OP_ANYNL:    case OP_ANYNL:
3261    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3262    read_char(common);    read_char(common);
3263    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);
3264    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3265    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3266        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3267      else
3268        jump[1] = check_str_end(common);
3269      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3270    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);
3271    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));
3272    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3273    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3274    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2853  switch(type) Line 3279  switch(type)
3279    
3280    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3281    case OP_HSPACE:    case OP_HSPACE:
3282    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3283    read_char(common);    read_char(common);
3284    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3285    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 3287  switch(type)
3287    
3288    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3289    case OP_VSPACE:    case OP_VSPACE:
3290    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3291    read_char(common);    read_char(common);
3292    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3293    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 3295  switch(type)
3295    
3296  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3297    case OP_EXTUNI:    case OP_EXTUNI:
3298    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3299    read_char(common);    read_char(common);
3300    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3301    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 3311  switch(type)
3311    
3312    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3313    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3314      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3315        {
3316        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3317        /* Since we successfully read a char above, partial matching must occure. */
3318        check_partial(common, TRUE);
3319        JUMPHERE(jump[0]);
3320        }
3321    return cc;    return cc;
3322  #endif  #endif
3323    
3324    case OP_EODN:    case OP_EODN:
3325      /* Requires rather complex checks. */
3326    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);
3327    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3328      {      {
3329      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3330      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3331      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3332      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3333        else
3334          {
3335          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3336          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3337          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3338          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3339          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3340          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3341          check_partial(common, TRUE);
3342          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3343          JUMPHERE(jump[1]);
3344          }
3345        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3346      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));
3347      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));
3348      }      }
3349    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3350      {      {
3351      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3352      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3353      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));
3354      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));
3355      }      }
3356    else    else
3357      {      {
3358      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3359      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);
3360      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3361      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);
3362      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3363      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3364      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3365        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3366      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3367      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3368    
3369      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3370      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3371        {        {
3372        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3373        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));
3374        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));
3375        }        }
# Line 2938  switch(type) Line 3386  switch(type)
3386      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3387      }      }
3388    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3389      check_partial(common, FALSE);
3390    return cc;    return cc;
3391    
3392    case OP_EOD:    case OP_EOD:
3393    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3394      check_partial(common, FALSE);
3395    return cc;    return cc;
3396    
3397    case OP_CIRC:    case OP_CIRC:
# Line 2961  switch(type) Line 3411  switch(type)
3411    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3412    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3413    
3414    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));  
   
3415    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3416      {      {
3417      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3418      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3419      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3420      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3421      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));
3422      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));
3423      }      }
# Line 2990  switch(type) Line 3438  switch(type)
3438    if (!common->endonly)    if (!common->endonly)
3439      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3440    else    else
3441        {
3442      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));
3443        check_partial(common, FALSE);
3444        }
3445    return cc;    return cc;
3446    
3447    case OP_DOLLM:    case OP_DOLLM:
# Line 2998  switch(type) Line 3449  switch(type)
3449    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3450    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));
3451    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));
3452      check_partial(common, FALSE);
3453    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3454    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3455    
3456    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3457      {      {
3458      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3459      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3460      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3461      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3462        else
3463          {
3464          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3465          /* STR_PTR = STR_END - IN_UCHARS(1) */
3466          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3467          check_partial(common, TRUE);
3468          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3469          JUMPHERE(jump[1]);
3470          }
3471    
3472        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3473      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));
3474      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));
3475      }      }
# Line 3021  switch(type) Line 3484  switch(type)
3484    case OP_CHAR:    case OP_CHAR:
3485    case OP_CHARI:    case OP_CHARI:
3486    length = 1;    length = 1;
3487  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3488    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3489  #endif  #endif
3490    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))
3491      {      {
3492      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));
3493      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));
3494    
3495      context.length = length;      context.length = IN_UCHARS(length);
3496      context.sourcereg = -1;      context.sourcereg = -1;
3497  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3498      context.byteptr = 0;      context.ucharptr = 0;
3499  #endif  #endif
3500      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3501      }      }
3502    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3503    read_char(common);    read_char(common);
3504  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3505    if (common->utf8)    if (common->utf)
3506      {      {
3507      GETCHAR(c, cc);      GETCHAR(c, cc);
3508      }      }
3509    else    else
3510  #endif  #endif
3511      c = *cc;      c = *cc;
3512      if (type == OP_CHAR || !char_has_othercase(common, cc))
3513        {
3514        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3515        return cc + length;
3516        }
3517      oc = char_othercase(common, c);
3518      bit = c ^ oc;
3519      if (ispowerof2(bit))
3520        {
3521        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3522        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3523        return cc + length;
3524        }
3525    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);
3526    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3527    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 3531  switch(type)
3531    
3532    case OP_NOT:    case OP_NOT:
3533    case OP_NOTI:    case OP_NOTI:
3534      fallback_at_str_end(common, fallbacks);
3535    length = 1;    length = 1;
3536  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3537    if (common->utf8)    if (common->utf)
3538      {      {
3539      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3540        c = *cc;
3541      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3542        {        {
3543        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3544        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
# Line 3076  switch(type) Line 3550  switch(type)
3550          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));
3551          }          }
3552        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3553        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));
3554        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3555        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);
3556        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3557        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
3558        return cc + length;        return cc + 1;
3559        }        }
3560      else      else
3561    #endif /* COMPILE_PCRE8 */
3562          {
3563          GETCHARLEN(c, cc, length);
3564        read_char(common);        read_char(common);
3565          }
3566      }      }
3567    else    else
3568  #endif  #endif /* SUPPORT_UTF */
3569      {      {
3570      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);  
3571      c = *cc;      c = *cc;
3572      }      }
3573    
# Line 3112  switch(type) Line 3588  switch(type)
3588        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));
3589        }        }
3590      }      }
3591    return cc + length;    return cc + 1;
3592    
3593    case OP_CLASS:    case OP_CLASS:
3594    case OP_NCLASS:    case OP_NCLASS:
3595    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3596    read_char(common);    read_char(common);
3597  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3598    jump[0] = NULL;    jump[0] = NULL;
3599    if (common->utf8)  #ifdef COMPILE_PCRE8
3600      /* This check only affects 8 bit mode. In other modes, we
3601      always need to compare the value with 255. */
3602      if (common->utf)
3603    #endif /* COMPILE_PCRE8 */
3604      {      {
3605      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3606      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3129  switch(type) Line 3609  switch(type)
3609        jump[0] = NULL;        jump[0] = NULL;
3610        }        }
3611      }      }
3612  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3613    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3614    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3615    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3616    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3617    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);
3618    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3619  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3620    if (jump[0] != NULL)    if (jump[0] != NULL)
3621      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3622  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3623    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3624    
3625  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3626    case OP_XCLASS:    case OP_XCLASS:
3627    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3628    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3152  switch(type) Line 3632  switch(type)
3632    length = GET(cc, 0);    length = GET(cc, 0);
3633    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3634    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3635    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3636  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3637      {      {
3638        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3639      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3640      label = LABEL();      label = LABEL();
3641      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));
3642      skip_char_back(common);      skip_char_back(common);
3643      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);
3644      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3645      }      }
3646      else
3647  #endif  #endif
3648    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3649    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));
3650        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3651        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3652        }
3653      check_start_used_ptr(common);
3654    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3655    }    }
3656  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3657  return cc;  return cc;
3658  }  }
3659    
3660  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)
3661  {  {
3662  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3663  /* 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. */
3664  DEFINE_COMPILER;  DEFINE_COMPILER;
3665  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3666  compare_context context;  compare_context context;
3667  int size;  int size;
3668    
# Line 3191  do Line 3675  do
3675    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3676      {      {
3677      size = 1;      size = 1;
3678  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3679      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3680        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3681  #endif  #endif
3682      }      }
3683    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3684      {      {
3685      size = 1;      size = 1;
3686  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3687      if (common->utf8)      if (common->utf)
3688        {        {
3689        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)
3690          size = 0;          size = 0;
3691        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3692          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3693        }        }
3694      else      else
3695  #endif  #endif
# Line 3216  do Line 3700  do
3700      size = 0;      size = 0;
3701    
3702    cc += 1 + size;    cc += 1 + size;
3703    context.length += size;    context.length += IN_UCHARS(size);
3704    }    }
3705  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3706    
# Line 3229  if (context.length > 0) Line 3713  if (context.length > 0)
3713    
3714    context.sourcereg = -1;    context.sourcereg = -1;
3715  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3716    context.byteptr = 0;    context.ucharptr = 0;
3717  #endif  #endif
3718    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);
3719    return cc;    return cc;
# Line 3239  if (context.length > 0) Line 3723  if (context.length > 0)
3723  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3724  }  }
3725    
3726  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)
3727  {  {
3728  DEFINE_COMPILER;  DEFINE_COMPILER;
3729  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3249  if (!common->jscript_compat) Line 3733  if (!common->jscript_compat)
3733    {    {
3734    if (fallbacks == NULL)    if (fallbacks == NULL)
3735      {      {
3736        /* OVECTOR(1) contains the "string begin - 1" constant. */
3737      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));
3738      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3739      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 3746  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3746  }  }
3747    
3748  /* Forward definitions. */  /* Forward definitions. */
3749  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3750  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3751    
3752  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3290  static void compile_fallbackpath(compile Line 3775  static void compile_fallbackpath(compile
3775      } \      } \
3776    while (0)    while (0)
3777    
3778  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3779    
3780  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)
3781  {  {
3782  DEFINE_COMPILER;  DEFINE_COMPILER;
3783  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3784  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3785    struct sljit_jump *partial;
3786    struct sljit_jump *nopartial;
3787    
3788  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3789    /* OVECTOR(1) contains the "string begin - 1" constant. */
3790  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3791    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)));
3792    
3793  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3794  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3795    {    {
3796    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);
3797    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 3802  if (common->utf8 && *cc == OP_REFI)
3802    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3803    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3804    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);
3805    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));
3806    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3807    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3808        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3809      else
3810        {
3811        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3812        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3813        check_partial(common, FALSE);
3814        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3815        JUMPHERE(nopartial);
3816        }
3817    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3818    }    }
3819  else  else
3820  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3821    {    {
3822    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);
3823    if (withchecks)    if (withchecks)
3824      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3825    
3826    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3827      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3828      if (common->mode == JIT_COMPILE)
3829        add_jump(compiler, fallbacks, partial);
3830    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3831    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));
3832    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));
3833    
3834      if (common->mode != JIT_COMPILE)
3835        {
3836        nopartial = JUMP(SLJIT_JUMP);
3837        JUMPHERE(partial);
3838        /* TMP2 -= STR_END - STR_PTR */
3839        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3840        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3841        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3842        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3843        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3844        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3845        JUMPHERE(partial);
3846        check_partial(common, FALSE);
3847        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3848        JUMPHERE(nopartial);
3849        }
3850    }    }
3851    
3852  if (jump != NULL)  if (jump != NULL)
# Line 3341  if (jump != NULL) Line 3856  if (jump != NULL)
3856    else    else
3857      JUMPHERE(jump);      JUMPHERE(jump);
3858    }    }
3859  return cc + 3;  return cc + 1 + IMM2_SIZE;
3860  }  }
3861    
3862  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)
3863  {  {
3864  DEFINE_COMPILER;  DEFINE_COMPILER;
3865  fallback_common *fallback;  fallback_common *fallback;
3866  uschar type;  pcre_uchar type;
3867  struct sljit_label *label;  struct sljit_label *label;
3868  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3869  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3870  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3871  int min = 0, max = 0;  int min = 0, max = 0;
3872  BOOL minimize;  BOOL minimize;
3873    
3874  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3875    
3876  type = cc[3];  type = cc[1 + IMM2_SIZE];
3877  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3878  switch(type)  switch(type)
3879    {    {
# Line 3366  switch(type) Line 3881  switch(type)
3881    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3882    min = 0;    min = 0;
3883    max = 0;    max = 0;
3884    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3885    break;    break;
3886    case OP_CRPLUS:    case OP_CRPLUS:
3887    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3888    min = 1;    min = 1;
3889    max = 0;    max = 0;
3890    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3891    break;    break;
3892    case OP_CRQUERY:    case OP_CRQUERY:
3893    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3894    min = 0;    min = 0;
3895    max = 1;    max = 1;
3896    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3897    break;    break;
3898    case OP_CRRANGE:    case OP_CRRANGE:
3899    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3900    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3901    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3902    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3903    break;    break;
3904    default:    default:
3905    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3488  decrease_call_count(common); Line 4003  decrease_call_count(common);
4003  return cc;  return cc;
4004  }  }
4005    
4006  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)
4007  {  {
4008  DEFINE_COMPILER;  DEFINE_COMPILER;
4009  fallback_common *fallback;  fallback_common *fallback;
# Line 3534  add_jump(compiler, &fallback->topfallbac Line 4049  add_jump(compiler, &fallback->topfallbac
4049  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4050  }  }
4051    
4052  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)
4053  {  {
4054  DEFINE_COMPILER;  DEFINE_COMPILER;
4055  int framesize;  int framesize;
4056  int localptr;  int localptr;
4057  fallback_common altfallback;  fallback_common altfallback;
4058  uschar *ccbegin;  pcre_uchar *ccbegin;
4059  uschar opcode;  pcre_uchar opcode;
4060  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4061  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4062  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4063  jump_list **found;  jump_list **found;
# Line 3558  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4073  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4073    bra = *cc;    bra = *cc;
4074    cc++;    cc++;
4075    }    }
4076  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4077  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4078  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4079  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3804  common->accept = save_accept; Line 4319  common->accept = save_accept;
4319  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4320  }  }
4321    
4322  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)
4323  {  {
4324  int condition = FALSE;  int condition = FALSE;
4325  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4326  uschar *slotB;  pcre_uchar *slotB;
4327  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4328  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4329  sljit_w no_capture;  sljit_w no_capture;
# Line 3833  if (i < name_count) Line 4348  if (i < name_count)
4348    while (slotB > name_table)    while (slotB > name_table)
4349      {      {
4350      slotB -= name_entry_size;      slotB -= name_entry_size;
4351      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4352        {        {
4353        condition = locals[GET2(slotB, 0) << 1] != no_capture;        condition = locals[GET2(slotB, 0) << 1] != no_capture;
4354        if (condition) break;        if (condition) break;
# Line 3848  if (i < name_count) Line 4363  if (i < name_count)
4363      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4364        {        {
4365        slotB += name_entry_size;        slotB += name_entry_size;
4366        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4367          {          {
4368          condition = locals[GET2(slotB, 0) << 1] != no_capture;          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4369          if (condition) break;          if (condition) break;
# Line 3860  if (i < name_count) Line 4375  if (i < name_count)
4375  return condition;  return condition;
4376  }  }
4377    
4378  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)
4379  {  {
4380  int condition = FALSE;  int condition = FALSE;
4381  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4382  uschar *slotB;  pcre_uchar *slotB;
4383  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4384  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4385  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 4401  if (i < name_count)
4401    while (slotB > name_table)    while (slotB > name_table)
4402      {      {
4403      slotB -= name_entry_size;      slotB -= name_entry_size;
4404      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4405        {        {
4406        condition = GET2(slotB, 0) == group_num;        condition = GET2(slotB, 0) == group_num;
4407        if (condition) break;        if (condition) break;
# Line 3901  if (i < name_count) Line 4416  if (i < name_count)
4416      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4417        {        {
4418        slotB += name_entry_size;        slotB += name_entry_size;
4419        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4420          {          {
4421          condition = GET2(slotB, 0) == group_num;          condition = GET2(slotB, 0) == group_num;
4422          if (condition) break;          if (condition) break;
# Line 3967  return condition; Line 4482  return condition;
4482                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
4483  */  */
4484    
4485  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)
4486  {  {
4487  DEFINE_COMPILER;  DEFINE_COMPILER;
4488  fallback_common *fallback;  fallback_common *fallback;
4489  uschar opcode;  pcre_uchar opcode;
4490  int localptr = 0;  int localptr = 0;
4491  int offset = 0;  int offset = 0;
4492  int stacksize;  int stacksize;
4493  uschar *ccbegin;  pcre_uchar *ccbegin;
4494  uschar *hotpath;  pcre_uchar *hotpath;
4495  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4496  uschar ket;  pcre_uchar ket;
4497  assert_fallback *assert;  assert_fallback *assert;
4498  BOOL has_alternatives;  BOOL has_alternatives;
4499  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 4039  if (opcode == OP_CBRA || opcode == OP_SC Line 4554  if (opcode == OP_CBRA || opcode == OP_SC
4554    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4555    offset <<= 1;    offset <<= 1;
4556    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4557    hotpath += 2;    hotpath += IMM2_SIZE;
4558    }    }
4559  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4560    {    {
4561    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4562    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4563    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4564    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4565    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4203  if (opcode == OP_COND || opcode == OP_SC Line 4718  if (opcode == OP_COND || opcode == OP_SC
4718      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
4719      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4720        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)));
4721      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4722      }      }
4723    else if (*hotpath == OP_NCREF)    else if (*hotpath == OP_NCREF)
4724      {      {
# Line 4222  if (opcode == OP_COND || opcode == OP_SC Line 4737  if (opcode == OP_COND || opcode == OP_SC
4737      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));
4738    
4739      JUMPHERE(jump);      JUMPHERE(jump);
4740      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4741      }      }
4742    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4743      {      {
# Line 4243  if (opcode == OP_COND || opcode == OP_SC Line 4758  if (opcode == OP_COND || opcode == OP_SC
4758        {        {
4759        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
4760        if (stacksize != 0)        if (stacksize != 0)
4761          hotpath += 3;          hotpath += 1 + IMM2_SIZE;
4762        else        else
4763          {          {
4764          if (*cc == OP_ALT)          if (*cc == OP_ALT)
# Line 4270  if (opcode == OP_COND || opcode == OP_SC Line 4785  if (opcode == OP_COND || opcode == OP_SC
4785        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));
4786        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4787        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));
4788        hotpath += 3;        hotpath += 1 + IMM2_SIZE;
4789        }        }
4790      }      }
4791    else    else
# Line 4378  if (bra == OP_BRAZERO) Line 4893  if (bra == OP_BRAZERO)
4893  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4894    {    {
4895    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4896    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4897    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4898      {      {
4899      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4406  cc += 1 + LINK_SIZE; Line 4921  cc += 1 + LINK_SIZE;
4921  return cc;  return cc;
4922  }  }
4923    
4924  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)
4925  {  {
4926  DEFINE_COMPILER;  DEFINE_COMPILER;
4927  fallback_common *fallback;  fallback_common *fallback;
4928  uschar opcode;  pcre_uchar opcode;
4929  int localptr;  int localptr;
4930  int cbraprivptr = 0;  int cbraprivptr = 0;
4931  int framesize;  int framesize;
4932  int stacksize;  int stacksize;
4933  int offset = 0;  int offset = 0;
4934  BOOL zero = FALSE;  BOOL zero = FALSE;
4935  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4936  int stack;  int stack;
4937  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4938  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4430  if (*cc == OP_BRAPOSZERO) Line 4945  if (*cc == OP_BRAPOSZERO)
4945    }    }
4946    
4947  opcode = *cc;  opcode = *cc;
4948  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4949  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4950  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4951  switch(opcode)  switch(opcode)
# Line 4445  switch(opcode) Line 4960  switch(opcode)
4960    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4961    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4962    offset <<= 1;    offset <<= 1;
4963    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4964    break;    break;
4965    
4966    default:    default:
# Line 4624  decrease_call_count(common); Line 5139  decrease_call_count(common);
5139  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5140  }  }
5141    
5142  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)
5143  {  {
5144  int class_len;  int class_len;
5145    
# Line 4663  else Line 5178  else
5178    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5179    *type = *opcode;    *type = *opcode;
5180    cc++;    cc++;
5181    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5182    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5183    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5184      {      {
# Line 4674  else Line 5189  else
5189    else    else
5190      {      {
5191      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
5192      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
5193      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
5194    
5195      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4686  else Line 5201  else
5201        *opcode = OP_EXACT;        *opcode = OP_EXACT;
5202    
5203      if (end != NULL)      if (end != NULL)
5204        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
5205      }      }
5206    return cc;    return cc;
5207    }    }
# Line 4694  else Line 5209  else
5209  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)
5210    {    {
5211    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
5212    cc += 2;    cc += IMM2_SIZE;
5213    }    }
5214    
5215  if (*type == 0)  if (*type == 0)
# Line 4709  if (*type == 0) Line 5224  if (*type == 0)
5224  if (end != NULL)  if (end != NULL)
5225    {    {
5226    *end = cc + 1;    *end = cc + 1;
5227  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5228    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
5229  #endif  #endif
5230    }    }
5231  return cc;  return cc;
5232  }  }
5233    
5234  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)
5235  {  {
5236  DEFINE_COMPILER;  DEFINE_COMPILER;
5237  fallback_common *fallback;  fallback_common *fallback;
5238  uschar opcode;  pcre_uchar opcode;
5239  uschar type;  pcre_uchar type;
5240  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5241  uschar* end;  pcre_uchar* end;
5242  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
5243  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5244  struct sljit_label *label;  struct sljit_label *label;
# Line 4885  decrease_call_count(common); Line 5400  decrease_call_count(common);
5400  return end;  return end;
5401  }  }
5402    
5403  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)
5404  {  {
5405  DEFINE_COMPILER;  DEFINE_COMPILER;
5406  fallback_common *fallback;  fallback_common *fallback;
# Line 4929  add_jump(compiler, &fallback->topfallbac Line 5444  add_jump(compiler, &fallback->topfallbac
5444  return cc + 1;  return cc + 1;
5445  }  }
5446    
5447  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)
5448  {  {
5449  DEFINE_COMPILER;  DEFINE_COMPILER;
5450  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5451    
5452  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5453  if (common->currententry != NULL)  if (common->currententry != NULL)
5454    return cc + 3;    return cc + 1 + IMM2_SIZE;
5455    
5456  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));
5457  offset <<= 1;  offset <<= 1;
5458  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);
5459  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5460  return cc + 3;  return cc + 1 + IMM2_SIZE;
5461  }  }
5462    
5463  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)
5464  {  {
5465  DEFINE_COMPILER;  DEFINE_COMPILER;
5466  fallback_common *fallback;  fallback_common *fallback;
# Line 4998  while (cc < ccend) Line 5513  while (cc < ccend)
5513    
5514      case OP_CHAR:      case OP_CHAR:
5515      case OP_CHARI:      case OP_CHARI:
5516      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5517          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5518        else
5519          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5520      break;      break;
5521    
5522      case OP_STAR:      case OP_STAR:
# Line 5071  while (cc < ccend) Line 5589  while (cc < ccend)
5589    
5590      case OP_CLASS:      case OP_CLASS:
5591      case OP_NCLASS:      case OP_NCLASS:
5592      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)
5593        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5594      else      else
5595        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);
5596      break;      break;
5597    
5598  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5599      case OP_XCLASS:      case OP_XCLASS:
5600      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)
5601        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 5088  while (cc < ccend) Line 5606  while (cc < ccend)
5606    
5607      case OP_REF:      case OP_REF:
5608      case OP_REFI:      case OP_REFI:
5609      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5610        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5611      else      else
5612        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 5709  SLJIT_ASSERT(cc == ccend);
5709      } \      } \
5710    while (0)    while (0)
5711    
5712  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5713    
5714  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5715  {  {
5716  DEFINE_COMPILER;  DEFINE_COMPILER;
5717  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5718  uschar opcode;  pcre_uchar opcode;
5719  uschar type;  pcre_uchar type;
5720  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5721  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5722  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5323  switch(opcode) Line 5841  switch(opcode)
5841  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)
5842  {  {
5843  DEFINE_COMPILER;  DEFINE_COMPILER;
5844  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5845  uschar type;  pcre_uchar type;
5846    
5847  type = cc[3];  type = cc[1 + IMM2_SIZE];
5848  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5849    {    {
5850    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5355  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5873  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5873  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5874  {  {
5875  DEFINE_COMPILER;  DEFINE_COMPILER;
5876  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5877  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5878  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5879    
5880  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5427  int offset = 0; Line 5945  int offset = 0;
5945  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5946  int stacksize;  int stacksize;
5947  int count;  int count;
5948  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5949  uschar *ccbegin;  pcre_uchar *ccbegin;
5950  uschar *ccprev;  pcre_uchar *ccprev;
5951  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5952  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5953  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5954  uschar ket;  pcre_uchar ket;
5955  assert_fallback *assert;  assert_fallback *assert;
5956  BOOL has_alternatives;  BOOL has_alternatives;
5957  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
# Line 5933  while (current) Line 6451  while (current)
6451      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6452      case OP_CLASS:      case OP_CLASS:
6453      case OP_NCLASS:      case OP_NCLASS:
6454    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6455      case OP_XCLASS:      case OP_XCLASS:
6456    #endif
6457      compile_iterator_fallbackpath(common, current);      compile_iterator_fallbackpath(common, current);
6458      break;      break;
6459    
# Line 6000  while (current) Line 6520  while (current)
6520  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
6521  {  {
6522  DEFINE_COMPILER;  DEFINE_COMPILER;
6523  uschar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
6524  uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6525  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
6526  int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
6527  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6528  int alternativesize;  int alternativesize;
# Line 6090  sljit_emit_fast_return(compiler, SLJIT_M Line 6610  sljit_emit_fast_return(compiler, SLJIT_M
6610  #undef CURRENT_AS  #undef CURRENT_AS
6611    
6612  void  void
6613  _pcre_jit_compile(const real_pcre *re, pcre_extra *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6614  {  {
6615  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6616  fallback_common rootfallback;  fallback_common rootfallback;
6617  compiler_common common_data;  compiler_common common_data;
6618  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6619  const uschar *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6620  pcre_study_data *study;  pcre_study_data *study;
6621  uschar *ccend;  pcre_uchar *ccend;
6622  executable_function *function;  executable_functions *functions;
6623  void *executable_func;  void *executable_func;
6624  sljit_uw executable_size;  sljit_uw executable_size;
6625  struct sljit_label *leave;  struct sljit_label *leave;
6626  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6627  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6628  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6629  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6630  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6631  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6632    
# Line 6114  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_ Line 6634  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_
6634  study = extra->study_data;  study = extra->study_data;
6635    
6636  if (!tables)  if (!tables)
6637    tables = _pcre_default_tables;    tables = PRIV(default_tables);
6638    
6639  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6640  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;
6641    
6642  common->compiler = NULL;  common->compiler = NULL;
6643  common->start = rootfallback.cc;  common->start = rootfallback.cc;
6644  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6645  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6646  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6647    common->mode = mode;
6648  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6649  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6650    {    {
# Line 6158  else Line 6679  else
6679    }    }
6680  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6681  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6682  common->name_table = (sljit_w)re + re->name_table_offset;  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6683  common->name_count = re->name_count;  common->name_count = re->name_count;
6684  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
6685    common->partialmatchlabel = NULL;
6686  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6687  common->stubs = NULL;  common->stubs = NULL;
6688  common->entries = NULL;  common->entries = NULL;
6689  common->currententry = NULL;  common->currententry = NULL;
6690    common->partialmatch = NULL;
6691  common->accept = NULL;  common->accept = NULL;
6692  common->calllimit = NULL;  common->calllimit = NULL;
6693  common->stackalloc = NULL;  common->stackalloc = NULL;
# Line 6176  common->vspace = NULL; Line 6699  common->vspace = NULL;
6699  common->casefulcmp = NULL;  common->casefulcmp = NULL;
6700  common->caselesscmp = NULL;  common->caselesscmp = NULL;
6701  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6702  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6703  common->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6704    common->utf = (re->options & PCRE_UTF8) != 0;
6705  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6706  common->useucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6707  #endif  #endif
6708  common->utf8readchar = NULL;  common->utfreadchar = NULL;
6709  common->utf8readtype8 = NULL;  #ifdef COMPILE_PCRE8
6710    common->utfreadtype8 = NULL;
6711  #endif  #endif
6712    #endif /* SUPPORT_UTF */
6713  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6714  common->getucd = NULL;  common->getucd = NULL;
6715  #endif  #endif
# Line 6195  if (common->localsize < 0) Line 6721  if (common->localsize < 0)
6721  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6722  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6723    return;    return;
6724  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6725  if (!common->localptrs)  if (!common->localptrs)
6726    return;    return;
6727  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 6740  sljit_emit_enter(compiler, 1, 5, 5, comm
6740    
6741  /* Register init. */  /* Register init. */
6742  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6743  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6744    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);
6745    
6746  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6747  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6748  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));
6749  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));
6750  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 6753  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6753  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));
6754  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6755    
6756    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6757      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);
6758    
6759  /* Main part of the matching */  /* Main part of the matching */
6760  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6761    {    {
6762    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);
6763    /* Forward search if possible. */    /* Forward search if possible. */
6764    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6765      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);
6766    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6767      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6768    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)
6769      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);
6770    }    }
6771  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6772    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);
6773    
6774  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6775  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);
6776  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6777  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);
6778    /* Copy the beginning of the string. */
6779    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6780      {
6781      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0);
6782      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
6783      JUMPHERE(jump);
6784      }
6785    else if (mode == JIT_PARTIAL_HARD_COMPILE)
6786      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, STR_PTR, 0);
6787    
6788  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6789  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6265  if (common->accept != NULL) Line 6803  if (common->accept != NULL)
6803  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6804  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
6805  leave = LABEL();  leave = LABEL();
6806  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6807    
6808    if (mode != JIT_COMPILE)
6809      {
6810      common->partialmatchlabel = LABEL();
6811      set_jumps(common->partialmatch, common->partialmatchlabel);
6812      return_with_partial_match(common, leave);
6813      }
6814    
6815  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
6816  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
# Line 6278  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6823  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6823    
6824  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
6825    
6826    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6827      {
6828      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, -1);
6829      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR);
6830      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), START_USED_PTR, SLJIT_IMM, -1);
6831      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, TMP1, 0);
6832      JUMPHERE(jump);
6833      }
6834    
6835  /* Check we have remaining characters. */  /* Check we have remaining characters. */
6836  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));
6837    
# Line 6285  if ((re->options & PCRE_ANCHORED) == 0) Line 6839  if ((re->options & PCRE_ANCHORED) == 0)
6839    {    {
6840    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
6841      {      {
6842      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6843        {        {
6844        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));
6845        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
6846        }        }
6847      else      else
# Line 6295  if ((re->options & PCRE_ANCHORED) == 0) Line 6849  if ((re->options & PCRE_ANCHORED) == 0)
6849      }      }
6850    else    else
6851      {      {
6852      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6853        {        {
6854        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));
6855        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);
6856        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
6857        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 6863  if ((re->options & PCRE_ANCHORED) == 0)
6863      }      }
6864    }    }
6865    
6866    /* No more remaining characters. */
6867  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
6868    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6869  /* Copy OVECTOR(1) to OVECTOR(0) */  
6870  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6871      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), HIT_START, SLJIT_IMM, 0, common->partialmatchlabel);
6872    
6873  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);  OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_NOMATCH);
6874  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
6875    
# Line 6355  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O Line 6912  OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_O
6912  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);
6913    
6914  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));
6915  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);
6916  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
6917  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));
6918  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 6921  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT
6921  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
6922    
6923  /* Allocation failed. */  /* Allocation failed. */
6924  JUMPHERE(alloc_error);  JUMPHERE(jump);
6925  /* 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. */
6926  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);
6927  JUMPTO(SLJIT_JUMP, leave);  JUMPTO(SLJIT_JUMP, leave);
# Line 6409  if (common->caselesscmp != NULL) Line 6966  if (common->caselesscmp != NULL)
6966    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
6967    do_caselesscmp(common);    do_caselesscmp(common);
6968    }    }
6969  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6970  if (common->utf8readchar != NULL)  if (common->utfreadchar != NULL)
6971    {    {
6972    set_jumps(common->utf8readchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
6973    do_utf8readchar(common);    do_utfreadchar(common);
6974    }    }
6975  if (common->utf8readtype8 != NULL)  #ifdef COMPILE_PCRE8
6976    if (common->utfreadtype8 != NULL)
6977    {    {
6978    set_jumps(common->utf8readtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
6979    do_utf8readtype8(common);    do_utfreadtype8(common);
6980    }    }
6981  #endif  #endif
6982    #endif /* COMPILE_PCRE8 */
6983  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6984  if (common->getucd != NULL)  if (common->getucd != NULL)
6985    {    {
# Line 6436  sljit_free_compiler(compiler); Line 6995  sljit_free_compiler(compiler);
6995  if (executable_func == NULL)  if (executable_func == NULL)
6996    return;    return;
6997    
6998  function = SLJIT_MALLOC(sizeof(executable_function));  /* Reuse the function descriptor if possible. */
6999  if (function == NULL)  if ((extra->flags & PCRE_EXTRA_EXECUTABLE_JIT) != 0 && extra->executable_jit != NULL)
7000      functions = (executable_functions *)extra->executable_jit;
7001    else
7002    {    {
7003    /* This case is highly unlikely since we just recently    functions = SLJIT_MALLOC(sizeof(executable_functions));
7004    freed a lot of memory. Although not impossible. */    if (functions == NULL)
7005    sljit_free_code(executable_func);      {
7006    return;      /* This case is highly unlikely since we just recently
7007        freed a lot of memory. Although not impossible. */
7008        sljit_free_code(executable_func);
7009        return;
7010        }
7011      memset(functions, 0, sizeof(executable_functions));
7012      extra->executable_jit = functions;
7013      extra->flags |= PCRE_EXTRA_EXECUTABLE_JIT;
7014    }    }
7015    
7016  function->executable_func = executable_func;  functions->executable_funcs[mode] = executable_func;
7017  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;  
7018  }  }
7019    
7020  static int jit_machine_stack_exec(jit_arguments *arguments, executable_function *function)  static int jit_machine_stack_exec(jit_arguments *arguments, void* executable_func)
7021  {  {
7022  union {  union {
7023     void* executable_func;     void* executable_func;
7024     jit_function call_executable_func;     jit_function call_executable_func;
7025  } convert_executable_func;  } convert_executable_func;
7026  uschar local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_area[LOCAL_SPACE_SIZE];
7027  struct sljit_stack local_stack;  struct sljit_stack local_stack;
7028    
7029  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_area;
# Line 6467  local_stack.base = local_stack.top; Line 7031  local_stack.base = local_stack.top;
7031  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;  local_stack.limit = local_stack.base + LOCAL_SPACE_SIZE;
7032  local_stack.max_limit = local_stack.limit;  local_stack.max_limit = local_stack.limit;
7033  arguments->stack = &local_stack;  arguments->stack = &local_stack;
7034  convert_executable_func.executable_func = function->executable_func;  convert_executable_func.executable_func = executable_func;
7035  return convert_executable_func.call_executable_func(arguments);  return convert_executable_func.call_executable_func(arguments);
7036  }  }
7037    
7038  int  int
7039  _pcre_jit_exec(const real_pcre *re, void *executable_func,  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_funcs,
7040    PCRE_SPTR subject, int length, int start_offset, int options,    const pcre_uchar *subject, int length, int start_offset, int options,
7041    int match_limit, int *offsets, int offsetcount)    int match_limit, int *offsets, int offsetcount)
7042  {  {
7043  executable_function *function = (executable_function*)executable_func;  executable_functions *functions = (executable_functions *)executable_funcs;
7044  union {  union {
7045     void* executable_func;     void* executable_func;
7046     jit_function call_executable_func;     jit_function call_executable_func;
# Line 6484  union { Line 7048  union {
7048  jit_arguments arguments;  jit_arguments arguments;
7049  int maxoffsetcount;  int maxoffsetcount;
7050  int retval;  int retval;
7051    int mode = JIT_COMPILE;
7052    
7053    if ((options & PCRE_PARTIAL_HARD) != 0)
7054      mode = JIT_PARTIAL_HARD_COMPILE;
7055    else if ((options & PCRE_PARTIAL_SOFT) != 0)
7056      mode = JIT_PARTIAL_SOFT_COMPILE;
7057    
7058    if (functions->executable_funcs[mode] == NULL)
7059      return PCRE_ERROR_NULL;
7060    
7061  /* Sanity checks should be handled by pcre_exec. */  /* Sanity checks should be handled by pcre_exec. */
7062  arguments.stack = NULL;  arguments.stack = NULL;
# Line 6503  workspace. We don't need the workspace h Line 7076  workspace. We don't need the workspace h
7076  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
7077  gets the same result with and without JIT. */  gets the same result with and without JIT. */
7078    
7079  offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3;  if (offsetcount != 2)
7080      offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
7081  maxoffsetcount = (re->top_bracket + 1) * 2;  maxoffsetcount = (re->top_bracket + 1) * 2;
7082  if (offsetcount > maxoffsetcount)  if (offsetcount > maxoffsetcount)
7083    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
7084  arguments.offsetcount = offsetcount;  arguments.offsetcount = offsetcount;
7085    
7086  if (function->callback)  if (functions->callback)
7087    arguments.stack = (struct sljit_stack*)function->callback(function->userdata);    arguments.stack = (struct sljit_stack *)functions->callback(functions->userdata);
7088  else  else
7089    arguments.stack = (struct sljit_stack*)function->userdata;    arguments.stack = (struct sljit_stack *)functions->userdata;
7090    
7091  if (arguments.stack == NULL)  if (arguments.stack == NULL)
7092    retval = jit_machine_stack_exec(&arguments, function);    retval = jit_machine_stack_exec(&arguments, functions->executable_funcs[mode]);
7093  else  else
7094    {    {
7095    convert_executable_func.executable_func = function->executable_func;    convert_executable_func.executable_func = functions->executable_funcs[mode];
7096    retval = convert_executable_func.call_executable_func(&arguments);    retval = convert_executable_func.call_executable_func(&arguments);
7097    }    }
7098    
# Line 6528  return retval; Line 7102  return retval;
7102  }  }
7103    
7104  void  void
7105  _pcre_jit_free(void *executable_func)  PRIV(jit_free)(void *executable_funcs)
7106  {  {
7107  executable_function *function = (executable_function*)executable_func;  int i;
7108  sljit_free_code(function->executable_func);  executable_functions *functions = (executable_functions *)executable_funcs;
7109  SLJIT_FREE(function);  for (i = 0; i < JIT_NUMBER_OF_COMPILE_MODES; i++)
7110      {
7111      if (functions->executable_funcs[i] != NULL)
7112        sljit_free_code(functions->executable_funcs[i]);
7113      }
7114    SLJIT_FREE(functions);
7115  }  }
7116    
7117  int  int
7118  _pcre_jit_get_size(void *executable_func)  PRIV(jit_get_size)(void *executable_funcs)
7119  {  {
7120  return ((executable_function*)executable_func)->executable_size;  return ((executable_functions *)executable_funcs)->executable_sizes[PCRE_STUDY_JIT_COMPILE];