Diff for /embedaddon/pcre/pcre_jit_compile.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:05:51 version 1.1.1.2, 2012/02/21 23:50:25
Line 6 Line 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.
   
                        Written by Philip Hazel                         Written by Philip Hazel
           Copyright (c) 1997-2008 University of Cambridge           Copyright (c) 1997-2012 University of Cambridge
   
   The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
                      Copyright (c) 2010-2011                      Copyright (c) 2010-2012
   
 -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
 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.
 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
 system files. */  system files. */
   
#define SLJIT_MALLOC(size) (pcre_malloc)(size)#define SLJIT_MALLOC(size) (PUBL(malloc))(size)
#define SLJIT_FREE(ptr) (pcre_free)(ptr)#define SLJIT_FREE(ptr) (PUBL(free))(ptr)
 #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
 #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
 #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
Line 62  system files. */ Line 62  system files. */
 #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
   
 #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
#error "Unsupported architecture"#error Unsupported architecture
 #endif  #endif
   
 /* 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 particular point i Line 148  Thus we can restore the locals to a particular point i
 typedef struct jit_arguments {  typedef struct jit_arguments {
   /* Pointers first. */    /* Pointers first. */
   struct sljit_stack *stack;    struct sljit_stack *stack;
  PCRE_SPTR str;  const pcre_uchar *str;
  PCRE_SPTR begin;  const pcre_uchar *begin;
  PCRE_SPTR end;  const pcre_uchar *end;
   int *offsets;    int *offsets;
  uschar *ptr;  pcre_uchar *ptr;
   /* Everything else after. */    /* Everything else after. */
   int offsetcount;    int offsetcount;
   int calllimit;    int calllimit;
  uschar notbol;  pcre_uint8 notbol;
  uschar noteol;  pcre_uint8 noteol;
  uschar notempty;  pcre_uint8 notempty;
  uschar notempty_atstart;  pcre_uint8 notempty_atstart;
 } jit_arguments;  } jit_arguments;
   
 typedef struct executable_function {  typedef struct executable_function {
   void *executable_func;    void *executable_func;
  pcre_jit_callback callback;  PUBL(jit_callback) callback;
   void *userdata;    void *userdata;
   sljit_uw executable_size;    sljit_uw executable_size;
 } executable_function;  } executable_function;
Line 198  typedef struct fallback_common { Line 198  typedef struct fallback_common {
   struct fallback_common *top;    struct fallback_common *top;
   jump_list *topfallbacks;    jump_list *topfallbacks;
   /* Opcode pointer. */    /* Opcode pointer. */
  uschar *cc;  pcre_uchar *cc;
 } fallback_common;  } fallback_common;
   
 typedef struct assert_fallback {  typedef struct assert_fallback {
Line 269  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
   
 typedef struct compiler_common {  typedef struct compiler_common {
   struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
  uschar *start;  pcre_uchar *start;
   int localsize;    int localsize;
   int *localptrs;    int *localptrs;
  const uschar *fcc;  const pcre_uint8 *fcc;
   sljit_w lcc;    sljit_w lcc;
   int cbraptr;    int cbraptr;
   int nltype;    int nltype;
Line 298  typedef struct compiler_common { Line 298  typedef struct compiler_common {
   jump_list *casefulcmp;    jump_list *casefulcmp;
   jump_list *caselesscmp;    jump_list *caselesscmp;
   BOOL jscript_compat;    BOOL jscript_compat;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  BOOL utf8;  BOOL utf;
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
  BOOL useucp;  BOOL use_ucp;
 #endif  #endif
  jump_list *utf8readchar;  jump_list *utfreadchar;
  jump_list *utf8readtype8;#ifdef COMPILE_PCRE8
   jump_list *utfreadtype8;
 #endif  #endif
   #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
   jump_list *getucd;    jump_list *getucd;
 #endif  #endif
Line 317  typedef struct compare_context { Line 319  typedef struct compare_context {
   int length;    int length;
   int sourcereg;    int sourcereg;
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
  int byteptr;  int ucharptr;
   union {    union {
    int asint;    sljit_i asint;
    short asshort;    sljit_uh asushort;
 #ifdef COMPILE_PCRE8
     sljit_ub asbyte;      sljit_ub asbyte;
    sljit_ub asbytes[4];    sljit_ub asuchars[4];
 #else
 #ifdef COMPILE_PCRE16
     sljit_uh asuchars[2];
 #endif
 #endif
   } c;    } c;
   union {    union {
    int asint;    sljit_i asint;
    short asshort;    sljit_uh asushort;
 #ifdef COMPILE_PCRE8
     sljit_ub asbyte;      sljit_ub asbyte;
    sljit_ub asbytes[4];    sljit_ub asuchars[4];
 #else
 #ifdef COMPILE_PCRE16
     sljit_uh asuchars[2];
 #endif
 #endif
   } oc;    } oc;
 #endif  #endif
 } compare_context;  } compare_context;
Line 338  enum { Line 352  enum {
   frame_setstrbegin = -1    frame_setstrbegin = -1
 };  };
   
   /* Undefine sljit macros. */
   #undef CMP
   
 /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
 #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
   
 #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
 #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
 #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
#define STR_PTR       SLJIT_GENERAL_REG1#define STR_PTR       SLJIT_SAVED_REG1
#define STR_END       SLJIT_GENERAL_REG2#define STR_END       SLJIT_SAVED_REG2
 #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
#define STACK_LIMIT   SLJIT_GENERAL_REG3#define STACK_LIMIT   SLJIT_SAVED_REG3
#define ARGUMENTS     SLJIT_GENERAL_EREG1#define ARGUMENTS     SLJIT_SAVED_EREG1
#define CALL_COUNT    SLJIT_GENERAL_EREG2#define CALL_COUNT    SLJIT_SAVED_EREG2
 #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
   
 /* Locals layout. */  /* Locals layout. */
Line 364  enum { Line 381  enum {
 /* Max limit of recursions. */  /* Max limit of recursions. */
 #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
#define REQ_BYTE_PTR     (6 * sizeof(sljit_w))#define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
 /* End pointer of the first line. */  /* End pointer of the first line. */
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
 /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
Line 374  the start pointers when the end of the capturing group Line 391  the start pointers when the end of the capturing group
 #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
 #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
 #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
#define PRIV(cc)         (common->localptrs[(cc) - common->start])#define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
   
   #ifdef COMPILE_PCRE8
   #define MOV_UCHAR  SLJIT_MOV_UB
   #define MOVU_UCHAR SLJIT_MOVU_UB
   #else
   #ifdef COMPILE_PCRE16
   #define MOV_UCHAR  SLJIT_MOV_UH
   #define MOVU_UCHAR SLJIT_MOVU_UH
   #else
   #error Unsupported compiling mode
   #endif
   #endif
   
 /* Shortcuts. */  /* Shortcuts. */
 #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
   struct sljit_compiler *compiler = common->compiler    struct sljit_compiler *compiler = common->compiler
Line 398  the start pointers when the end of the capturing group Line 427  the start pointers when the end of the capturing group
 #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
   sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
   
static uschar* bracketend(uschar* cc)static pcre_uchar* bracketend(pcre_uchar* cc)
 {  {
 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));
 do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
Line 419  return cc; Line 448  return cc;
  compile_fallbackpath   compile_fallbackpath
 */  */
   
static uschar *next_opcode(compiler_common *common, uschar *cc)static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
 {  {
 SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
 switch(*cc)  switch(*cc)
Line 475  switch(*cc) Line 504  switch(*cc)
   return cc + 1;    return cc + 1;
   
   case OP_ANYBYTE:    case OP_ANYBYTE:
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  if (common->utf8) return NULL;  if (common->utf) return NULL;
 #endif  #endif
   return cc + 1;    return cc + 1;
   
Line 484  switch(*cc) Line 513  switch(*cc)
   case OP_CHARI:    case OP_CHARI:
   case OP_NOT:    case OP_NOT:
   case OP_NOTI:    case OP_NOTI:
   
   case OP_STAR:    case OP_STAR:
   case OP_MINSTAR:    case OP_MINSTAR:
   case OP_PLUS:    case OP_PLUS:
Line 522  switch(*cc) Line 550  switch(*cc)
   case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
   case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
   cc += 2;    cc += 2;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  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]);
 #endif  #endif
   return cc;    return cc;
   
Line 543  switch(*cc) Line 571  switch(*cc)
   case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
   case OP_NOTEXACTI:    case OP_NOTEXACTI:
   case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
  cc += 4;  cc += 2 + IMM2_SIZE;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  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]);
 #endif  #endif
   return cc;    return cc;
   
   case OP_NOTPROP:    case OP_NOTPROP:
   case OP_PROP:    case OP_PROP:
     return cc + 1 + 2;
   
   case OP_TYPEUPTO:    case OP_TYPEUPTO:
   case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
   case OP_TYPEEXACT:    case OP_TYPEEXACT:
Line 562  switch(*cc) Line 592  switch(*cc)
   case OP_RREF:    case OP_RREF:
   case OP_NRREF:    case OP_NRREF:
   case OP_CLOSE:    case OP_CLOSE:
  cc += 3;  cc += 1 + IMM2_SIZE;
   return cc;    return cc;
   
   case OP_CRRANGE:    case OP_CRRANGE:
   case OP_CRMINRANGE:    case OP_CRMINRANGE:
  return cc + 5;  return cc + 1 + 2 * IMM2_SIZE;
   
   case OP_CLASS:    case OP_CLASS:
   case OP_NCLASS:    case OP_NCLASS:
  return cc + 33;  return cc + 1 + 32 / sizeof(pcre_uchar);
   
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
   case OP_XCLASS:    case OP_XCLASS:
   return cc + GET(cc, 1);    return cc + GET(cc, 1);
 #endif  #endif
Line 603  switch(*cc) Line 633  switch(*cc)
   case OP_CBRAPOS:    case OP_CBRAPOS:
   case OP_SCBRA:    case OP_SCBRA:
   case OP_SCBRAPOS:    case OP_SCBRAPOS:
  return cc + 1 + LINK_SIZE + 2;  return cc + 1 + LINK_SIZE + IMM2_SIZE;
   
   default:    default:
   return NULL;    return NULL;
   }    }
 }  }
   
static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
 {  {
 int localspace = 0;  int localspace = 0;
uschar *alternative;pcre_uchar *alternative;
 /* 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. */
 while (cc < ccend)  while (cc < ccend)
   {    {
Line 636  while (cc < ccend) Line 666  while (cc < ccend)
     case OP_CBRAPOS:      case OP_CBRAPOS:
     case OP_SCBRAPOS:      case OP_SCBRAPOS:
     localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
    cc += 1 + LINK_SIZE + 2;    cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;      break;
   
     case OP_COND:      case OP_COND:
Line 657  while (cc < ccend) Line 687  while (cc < ccend)
 return localspace;  return localspace;
 }  }
   
static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
 {  {
uschar *cc = common->start;pcre_uchar *cc = common->start;
uschar *alternative;pcre_uchar *alternative;
 while (cc < ccend)  while (cc < ccend)
   {    {
   switch(*cc)    switch(*cc)
Line 684  while (cc < ccend) Line 714  while (cc < ccend)
     case OP_SCBRAPOS:      case OP_SCBRAPOS:
     common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
     localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
    cc += 1 + LINK_SIZE + 2;    cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;      break;
   
     case OP_COND:      case OP_COND:
Line 707  while (cc < ccend) Line 737  while (cc < ccend)
 }  }
   
 /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
 {  {
uschar *ccend = bracketend(cc);pcre_uchar *ccend = bracketend(cc);
 int length = 0;  int length = 0;
 BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
Line 740  while (cc < ccend) Line 770  while (cc < ccend)
     case OP_SCBRA:      case OP_SCBRA:
     case OP_SCBRAPOS:      case OP_SCBRAPOS:
     length += 3;      length += 3;
    cc += 1 + LINK_SIZE + 2;    cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;      break;
   
     default:      default:
Line 758  if (length > 0) Line 788  if (length > 0)
 return -1;  return -1;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
uschar *ccend = bracketend(cc);pcre_uchar *ccend = bracketend(cc);
 BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
 int offset;  int offset;
   
 /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
   SLJIT_UNUSED_ARG(stacktop);
 SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   
 stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
Line 803  while (cc < ccend) Line 834  while (cc < ccend)
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
     stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
   
    cc += 1 + LINK_SIZE + 2;    cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;      break;
   
     default:      default:
Line 816  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_ Line 847  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_
 SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
 }  }
   
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)
 {  {
 int localsize = 2;  int localsize = 2;
uschar *alternative;pcre_uchar *alternative;
 /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
 while (cc < ccend)  while (cc < ccend)
   {    {
Line 842  while (cc < ccend) Line 873  while (cc < ccend)
     case OP_CBRA:      case OP_CBRA:
     case OP_SCBRA:      case OP_SCBRA:
     localsize++;      localsize++;
    cc += 1 + LINK_SIZE + 2;    cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;      break;
   
     case OP_CBRAPOS:      case OP_CBRAPOS:
     case OP_SCBRAPOS:      case OP_SCBRAPOS:
     localsize += 2;      localsize += 2;
    cc += 1 + LINK_SIZE + 2;    cc += 1 + LINK_SIZE + IMM2_SIZE;
     break;      break;
   
     case OP_COND:      case OP_COND:
Line 869  SLJIT_ASSERT(cc == ccend); Line 900  SLJIT_ASSERT(cc == ccend);
 return localsize;  return localsize;
 }  }
   
static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
   BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
Line 878  int count; Line 909  int count;
 BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
 BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
 BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
uschar *alternative;pcre_uchar *alternative;
 enum {  enum {
   start,    start,
   loop,    loop,
Line 939  while (status != end) Line 970  while (status != end)
       case OP_SBRAPOS:        case OP_SBRAPOS:
       case OP_SCOND:        case OP_SCOND:
       count = 1;        count = 1;
      srcw[0] = PRIV(cc);      srcw[0] = PRIV_DATA(cc);
       SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
       cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
       break;        break;
Line 948  while (status != end) Line 979  while (status != end)
       case OP_SCBRA:        case OP_SCBRA:
       count = 1;        count = 1;
       srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
       break;        break;
   
       case OP_CBRAPOS:        case OP_CBRAPOS:
       case OP_SCBRAPOS:        case OP_SCBRAPOS:
       count = 2;        count = 2;
       srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
      srcw[0] = PRIV(cc);      srcw[0] = PRIV_DATA(cc);
       SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
       break;        break;
   
       case OP_COND:        case OP_COND:
Line 966  while (status != end) Line 997  while (status != end)
       if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
         {          {
         count = 1;          count = 1;
        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
         SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
         }          }
       cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
Line 1174  struct sljit_label *loop; Line 1205  struct sljit_label *loop;
 int i;  int i;
 /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
 /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
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));
 if (length < 8)  if (length < 8)
   {    {
   for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
Line 1198  struct sljit_label *loop; Line 1229  struct sljit_label *loop;
 struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
   
 /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
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));
 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);
   
 OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
 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));
 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));
 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));
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);
 /* Unlikely, but possible */  /* Unlikely, but possible */
 earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
 loop = LABEL();  loop = LABEL();
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);
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));
 /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);#ifdef COMPILE_PCRE16
 OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
 #endif
 OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
 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);
 JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
 JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
Line 1223  if (topbracket > 1) Line 1257  if (topbracket > 1)
   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));
   OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
   
  /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */  /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
   loop = LABEL();    loop = LABEL();
   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)));
   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);
  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);
   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
   }    }
 else  else
   OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
 }  }
   
static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
 {  {
 /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
 unsigned int c;  unsigned int c;
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   {    {
   GETCHAR(c, cc);    GETCHAR(c, cc);
   if (c > 127)    if (c > 127)
Line 1251  if (common->utf8) Line 1285  if (common->utf8)
     return FALSE;      return FALSE;
 #endif  #endif
     }      }
   #ifndef COMPILE_PCRE8
     return common->fcc[c] != c;
   #endif
   }    }
 else  else
 #endif  #endif
   c = *cc;    c = *cc;
return common->fcc[c] != c;return MAX_255(c) ? common->fcc[c] != c : FALSE;
 }  }
   
 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)
 {  {
 /* Returns with the othercase. */  /* Returns with the othercase. */
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8 && c > 127)if (common->utf && c > 127)
   {    {
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
   return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
Line 1271  if (common->utf8 && c > 127) Line 1308  if (common->utf8 && c > 127)
 #endif  #endif
   }    }
 #endif  #endif
return common->fcc[c];return TABLE_GET(c, common->fcc, c);
 }  }
   
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)
 {  {
 /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
 unsigned int c, oc, bit;  unsigned int c, oc, bit;
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined COMPILE_PCRE8
 int n;  int n;
 #endif  #endif
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   {    {
   GETCHAR(c, cc);    GETCHAR(c, cc);
   if (c <= 127)    if (c <= 127)
Line 1300  if (common->utf8) Line 1337  if (common->utf8)
 else  else
   {    {
   c = *cc;    c = *cc;
  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
   }    }
 #else  #else
 c = *cc;  c = *cc;
oc = common->fcc[c];oc = TABLE_GET(c, common->fcc, c);
 #endif  #endif
   
 SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
Line 1318  if (c <= 127 && bit == 0x20) Line 1355  if (c <= 127 && bit == 0x20)
 if (!ispowerof2(bit))  if (!ispowerof2(bit))
   return 0;    return 0;
   
#ifdef SUPPORT_UTF8#ifdef COMPILE_PCRE8
if (common->utf8 && c > 127)
 #ifdef SUPPORT_UTF
 if (common->utf && c > 127)
   {    {
  n = _pcre_utf8_table4[*cc & 0x3f];  n = GET_EXTRALEN(*cc);
   while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
     {      {
     n--;      n--;
Line 1329  if (common->utf8 && c > 127) Line 1368  if (common->utf8 && c > 127)
     }      }
   return (n << 8) | bit;    return (n << 8) | bit;
   }    }
#endif#endif /* SUPPORT_UTF */
 return (0 << 8) | bit;  return (0 << 8) | bit;
   
   #else /* COMPILE_PCRE8 */
   
   #ifdef COMPILE_PCRE16
   #ifdef SUPPORT_UTF
   if (common->utf && c > 65535)
     {
     if (bit >= (1 << 10))
       bit >>= 10;
     else
       return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
     }
   #endif /* SUPPORT_UTF */
   return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
   #endif /* COMPILE_PCRE16 */
   
   #endif /* COMPILE_PCRE8 */
 }  }
   
 static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)
Line 1344  static void read_char(compiler_common *common) Line 1400  static void read_char(compiler_common *common)
 /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
 Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
 struct sljit_jump *jump;  struct sljit_jump *jump;
 #endif  #endif
   
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   {    {
   #ifdef COMPILE_PCRE8
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
  add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));#else
 #ifdef COMPILE_PCRE16
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
 #endif
 #endif /* COMPILE_PCRE8 */
   add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
   JUMPHERE(jump);    JUMPHERE(jump);
   }    }
 #endif  #endif
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));
 }  }
   
 static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
Line 1365  static void peek_char(compiler_common *common) Line 1427  static void peek_char(compiler_common *common)
 /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
 Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
 struct sljit_jump *jump;  struct sljit_jump *jump;
 #endif  #endif
   
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   {    {
   #ifdef COMPILE_PCRE8
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
  add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));#else
 #ifdef COMPILE_PCRE16
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
 #endif
 #endif /* COMPILE_PCRE8 */
   add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
   JUMPHERE(jump);    JUMPHERE(jump);
   }    }
Line 1385  static void read_char8_type(compiler_common *common) Line 1453  static void read_char8_type(compiler_common *common)
 {  {
 /* 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. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || defined COMPILE_PCRE16
 struct sljit_jump *jump;  struct sljit_jump *jump;
 #endif  #endif
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   {    {
  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
  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));
 #ifdef COMPILE_PCRE8
   /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
  it is a clever early read in most cases. */  it is needed in most cases. */
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
   jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
  add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   JUMPHERE(jump);    JUMPHERE(jump);
   #else
   #ifdef COMPILE_PCRE16
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
     jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
     JUMPHERE(jump);
     /* Skip low surrogate if necessary. */
     OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
   #endif
   #endif /* COMPILE_PCRE8 */
   return;    return;
   }    }
 #endif  #endif
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
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));
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);#ifdef COMPILE_PCRE16
 /* The ctypes array contains only 256 values. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
 jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
 #endif
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
 #ifdef COMPILE_PCRE16
 JUMPHERE(jump);
 #endif
 }  }
   
 static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
 {  {
/* 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. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined COMPILE_PCRE8
 struct sljit_label *label;  struct sljit_label *label;
   
if (common->utf8)if (common->utf)
   {    {
   label = LABEL();    label = LABEL();
  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
  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));
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
   CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
   return;    return;
   }    }
 #endif  #endif
OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);#if defined SUPPORT_UTF && defined COMPILE_PCRE16
 if (common->utf)
   {
   OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   /* Skip low surrogate if necessary. */
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
   OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   return;
   }
 #endif
 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 }  }
   
 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 1553  else if (nltype == NLTYPE_ANYCRLF)
   }    }
 else  else
   {    {
  SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);  SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
   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));
   }    }
 }  }
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
static void do_utf8readchar(compiler_common *common)
 #ifdef COMPILE_PCRE8
 static void do_utfreadchar(compiler_common *common)
 {  {
/* Fast decoding an utf8 character. TMP1 contains the first byte/* Fast decoding a UTF-8 character. TMP1 contains the first byte
 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. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  struct sljit_jump *jump;
Line 1465  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5,  Line 1572  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 
 /* Searching for the first zero. */  /* Searching for the first zero. */
 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);
 jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
/* 2 byte sequence *//* Two byte sequence. */
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
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));
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  JUMPHERE(jump);
   
 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);
 jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
/* 3 byte sequence *//* Three byte sequence. */
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
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_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 2);OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  JUMPHERE(jump);
   
OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);/* Four byte sequence. */
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); 
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
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_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 }  }
   
static void do_utf8readtype8(compiler_common *common)static void do_utfreadtype8(compiler_common *common)
 {  {
/* Fast decoding an utf8 character type. TMP2 contains the first byte/* Fast decoding a UTF-8 character type. TMP2 contains the first byte
of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */of the character (>= 0xc0). Return value in TMP1. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  struct sljit_jump *jump;
 struct sljit_jump *compare;  struct sljit_jump *compare;
Line 1549  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5,  Line 1631  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 
   
 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);
 jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
/* 2 byte sequence *//* Two byte sequence. */
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
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));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
 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_ADDR, 0); Line 1648  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 JUMPHERE(jump);  JUMPHERE(jump);
   
 /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
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);
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 }  }
   
#endif#else /* COMPILE_PCRE8 */
   
   #ifdef COMPILE_PCRE16
   static void do_utfreadchar(compiler_common *common)
   {
   /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
   of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
   DEFINE_COMPILER;
   struct sljit_jump *jump;
   
   sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
   /* Do nothing, only return. */
   sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
   
   JUMPHERE(jump);
   /* Combine two 16 bit characters. */
   OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
   OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
   OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
   sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
   }
   #endif /* COMPILE_PCRE16 */
   
   #endif /* COMPILE_PCRE8 */
   
   #endif /* SUPPORT_UTF */
   
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
   
 /* UCD_BLOCK_SIZE must be 128 (see the assert below). */  /* UCD_BLOCK_SIZE must be 128 (see the assert below). */
Line 1590  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_recor Line 1703  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_recor
   
 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);
 OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
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));
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
 OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
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));
 OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 }  }
Line 1610  struct sljit_label *newlinelabel = NULL; Line 1723  struct sljit_label *newlinelabel = NULL;
 struct sljit_jump *start;  struct sljit_jump *start;
 struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
 struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
struct sljit_jump *singlebyte;struct sljit_jump *singlechar;
 #endif  #endif
 jump_list *newline = NULL;  jump_list *newline = NULL;
 BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
BOOL readbyte = FALSE;BOOL readuchar = FALSE;
   
 if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
     common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
Line 1630  if (firstline) Line 1743  if (firstline)
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
     {      {
     mainloop = LABEL();      mainloop = LABEL();
    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));
     end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
     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);
     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);
    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));
     }      }
   else    else
     {      {
Line 1660  start = JUMP(SLJIT_JUMP); Line 1773  start = JUMP(SLJIT_JUMP);
 if (newlinecheck)  if (newlinecheck)
   {    {
   newlinelabel = LABEL();    newlinelabel = LABEL();
  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));
   end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
   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);
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
   #ifdef COMPILE_PCRE16
     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
   #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
   }    }
Line 1672  if (newlinecheck) Line 1788  if (newlinecheck)
 mainloop = LABEL();  mainloop = LABEL();
   
 /* 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. */
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8) readbyte = TRUE;if (common->utf) readuchar = TRUE;
 #endif  #endif
if (newlinecheck) readbyte = TRUE;if (newlinecheck) readuchar = TRUE;
   
if (readbyte)if (readuchar)
  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
   
 if (newlinecheck)  if (newlinecheck)
   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);
   
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));
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (common->utf8)if (common->utf)
   {    {
  singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);  singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
  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);
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
  JUMPHERE(singlebyte);  JUMPHERE(singlechar);
   }    }
 #endif  #endif
   #if defined SUPPORT_UTF && defined COMPILE_PCRE16
   if (common->utf)
     {
     singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
     JUMPHERE(singlechar);
     }
   #endif
 JUMPHERE(start);  JUMPHERE(start);
   
 if (newlinecheck)  if (newlinecheck)
Line 1704  if (newlinecheck) Line 1832  if (newlinecheck)
 return mainloop;  return mainloop;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_label *start;  struct sljit_label *start;
 struct sljit_jump *leave;  struct sljit_jump *leave;
 struct sljit_jump *found;  struct sljit_jump *found;
pcre_uint16 oc, bit;pcre_uchar oc, bit;
   
 if (firstline)  if (firstline)
   {    {
Line 1720  if (firstline) Line 1848  if (firstline)
   
 start = LABEL();  start = LABEL();
 leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
   
if ((firstbyte & REQ_CASELESS) == 0)oc = first_char;
  found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);if (caseless)
   {
   oc = TABLE_GET(first_char, common->fcc, first_char);
 #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
   if (first_char > 127 && common->utf)
     oc = UCD_OTHERCASE(first_char);
 #endif
   }
 if (first_char == oc)
   found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
 else  else
   {    {
  firstbyte &= 0xff;  bit = first_char ^ oc;
  oc = common->fcc[firstbyte]; 
  bit = firstbyte ^ oc; 
   if (ispowerof2(bit))    if (ispowerof2(bit))
     {      {
     OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
     }      }
   else    else
     {      {
    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);
     COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
     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);
     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 1879  else
     }      }
   }    }
   
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));
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (common->utf8)if (common->utf)
   {    {
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
  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);
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   }    }
 #endif  #endif
   #if defined SUPPORT_UTF && defined COMPILE_PCRE16
   if (common->utf)
     {
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
     }
   #endif
 JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
 JUMPHERE(found);  JUMPHERE(found);
 JUMPHERE(leave);  JUMPHERE(leave);
Line 1786  if (common->nltype == NLTYPE_FIXED && common->newline  Line 1932  if (common->nltype == NLTYPE_FIXED && common->newline 
   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));
   firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
   
  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
   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);
   COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
   #ifdef COMPILE_PCRE16
     OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
   #endif
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
   
   loop = LABEL();    loop = LABEL();
  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));
   leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
   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);
   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);
   
Line 1826  if (common->nltype == NLTYPE_ANY || common->nltype ==  Line 1975  if (common->nltype == NLTYPE_ANY || common->nltype == 
   leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
   JUMPHERE(foundcr);    JUMPHERE(foundcr);
   notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
   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);
   COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
   #ifdef COMPILE_PCRE16
     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
   #endif
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
   JUMPHERE(leave);    JUMPHERE(leave);
Line 1846  DEFINE_COMPILER; Line 1998  DEFINE_COMPILER;
 struct sljit_label *start;  struct sljit_label *start;
 struct sljit_jump *leave;  struct sljit_jump *leave;
 struct sljit_jump *found;  struct sljit_jump *found;
   #ifndef COMPILE_PCRE8
   struct sljit_jump *jump;
   #endif
   
 if (firstline)  if (firstline)
   {    {
Line 1855  if (firstline) Line 2010  if (firstline)
   
 start = LABEL();  start = LABEL();
 leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
 #endif  #endif
   #ifndef COMPILE_PCRE8
   jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
   JUMPHERE(jump);
   #endif
 OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
 OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
 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, TMP2, 0); Line 2027  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
 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);
 found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8)if (common->utf)
   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
 #endif  #endif
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));
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined COMPILE_PCRE8
if (common->utf8)if (common->utf)
   {    {
   CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
  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);
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   }    }
 #endif  #endif
   #if defined SUPPORT_UTF && defined COMPILE_PCRE16
   if (common->utf)
     {
     CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
     OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
     OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
     COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
     OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
     }
   #endif
 JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
 JUMPHERE(found);  JUMPHERE(found);
 JUMPHERE(leave);  JUMPHERE(leave);
Line 1888  if (firstline) Line 2059  if (firstline)
   OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_label *loop;  struct sljit_label *loop;
Line 1897  struct sljit_jump *alreadyfound; Line 2068  struct sljit_jump *alreadyfound;
 struct sljit_jump *found;  struct sljit_jump *found;
 struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
 struct sljit_jump *notfound;  struct sljit_jump *notfound;
pcre_uint16 oc, bit;pcre_uchar oc, bit;
   
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);
 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);
 toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
 alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
   
if (has_firstbyte)if (has_firstchar)
  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
 else  else
   OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
   
 loop = LABEL();  loop = LABEL();
 notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
   
OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
if ((reqbyte & REQ_CASELESS) == 0)oc = req_char;
  found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);if (caseless)
   {
   oc = TABLE_GET(req_char, common->fcc, req_char);
 #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
   if (req_char > 127 && common->utf)
     oc = UCD_OTHERCASE(req_char);
 #endif
   }
 if (req_char == oc)
   found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
 else  else
   {    {
  reqbyte &= 0xff;  bit = req_char ^ oc;
  oc = common->fcc[reqbyte]; 
  bit = reqbyte ^ oc; 
   if (ispowerof2(bit))    if (ispowerof2(bit))
     {      {
     OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
     }      }
   else    else
     {      {
    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
     foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
     }      }
   }    }
OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
 JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
   
 JUMPHERE(found);  JUMPHERE(found);
 if (foundoc)  if (foundoc)
   JUMPHERE(foundoc);    JUMPHERE(foundoc);
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);
 JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
 JUMPHERE(toolong);  JUMPHERE(toolong);
 return notfound;  return notfound;
Line 1985  static void check_wordboundary(compiler_common *common Line 2163  static void check_wordboundary(compiler_common *common
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *beginend;  struct sljit_jump *beginend;
#ifdef SUPPORT_UTF8#if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
 struct sljit_jump *jump;  struct sljit_jump *jump;
 #endif  #endif
   
Line 2002  read_char(common); Line 2180  read_char(common);
   
 /* Testing char type. */  /* Testing char type. */
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
if (common->useucp)if (common->use_ucp)
   {    {
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
   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 2197  if (common->useucp)
 else  else
 #endif  #endif
   {    {
#ifdef SUPPORT_UTF8#ifndef COMPILE_PCRE8
   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
 #elif defined SUPPORT_UTF
   /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
   jump = NULL;    jump = NULL;
  if (common->utf8)  if (common->utf)
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
#endif#endif /* COMPILE_PCRE8 */
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
   OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
#ifdef SUPPORT_UTF8#ifndef COMPILE_PCRE8
   JUMPHERE(jump);
 #elif defined SUPPORT_UTF
   if (jump != NULL)    if (jump != NULL)
     JUMPHERE(jump);      JUMPHERE(jump);
#endif#endif /* COMPILE_PCRE8 */
   }    }
 JUMPHERE(beginend);  JUMPHERE(beginend);
   
Line 2042  peek_char(common); Line 2224  peek_char(common);
   
 /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
if (common->useucp)if (common->use_ucp)
   {    {
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
   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 2240  if (common->useucp)
 else  else
 #endif  #endif
   {    {
#ifdef SUPPORT_UTF8#ifndef COMPILE_PCRE8
   /* TMP2 may be destroyed by peek_char. */
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
   #elif defined SUPPORT_UTF
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
   jump = NULL;    jump = NULL;
  if (common->utf8)  if (common->utf)
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
 #endif  #endif
   OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
   OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
   OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
#ifdef SUPPORT_UTF8#ifndef COMPILE_PCRE8
   JUMPHERE(jump);
 #elif defined SUPPORT_UTF
   if (jump != NULL)    if (jump != NULL)
     JUMPHERE(jump);      JUMPHERE(jump);
#endif#endif /* COMPILE_PCRE8 */
   }    }
 JUMPHERE(beginend);  JUMPHERE(beginend);
   
Line 2089  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a); Line 2277  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
 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);
 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
 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);
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || defined COMPILE_PCRE16
if (common->utf8)#ifdef COMPILE_PCRE8
 if (common->utf)
   {    {
   #endif
   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
   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);
   #ifdef COMPILE_PCRE8
   }    }
 #endif  #endif
   #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 }  }
Line 2113  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL); Line 2305  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
 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);
 COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
 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);
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || defined COMPILE_PCRE16
if (common->utf8)#ifdef COMPILE_PCRE8
 if (common->utf)
   {    {
   #endif
   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
   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);
   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
Line 2129  if (common->utf8) Line 2323  if (common->utf8)
   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);
   COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
   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);
   #ifdef COMPILE_PCRE8
   }    }
 #endif  #endif
   #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
   
 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_IMM, 0x0a); Line 2343  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0a);
 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);
 COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
 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);
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || defined COMPILE_PCRE16
if (common->utf8)#ifdef COMPILE_PCRE8
 if (common->utf)
   {    {
   #endif
   COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
   OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
   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);
   #ifdef COMPILE_PCRE8
   }    }
 #endif  #endif
   #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
 COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
   
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
Line 2173  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5,  Line 2373  sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 
 OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
 OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
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));
   
 label = LABEL();  label = LABEL();
OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
 jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
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));
 JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
   
 JUMPHERE(jump);  JUMPHERE(jump);
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));
 OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
 OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
 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 2405  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
 OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
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));
   
 label = LABEL();  label = LABEL();
OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
 #ifndef COMPILE_PCRE8
 jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
 #endif
 OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
   #ifndef COMPILE_PCRE8
   JUMPHERE(jump);
   jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
   #endif
 OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
   #ifndef COMPILE_PCRE8
   JUMPHERE(jump);
   #endif
 jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
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));
 JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
   
 JUMPHERE(jump);  JUMPHERE(jump);
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));
 OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
 OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
 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_ADDR, 0); Line 2439  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
 #undef CHAR1  #undef CHAR1
 #undef CHAR2  #undef CHAR2
   
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined SUPPORT_UCP
#ifdef SUPPORT_UCP 
   
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)
 {  {
 /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
 int c1, c2;  int c1, c2;
uschar *src2 = args->ptr;const pcre_uchar *src2 = args->ptr;
uschar *end2 = (uschar*)args->end;const pcre_uchar *end2 = args->end;
   
 while (src1 < end1)  while (src1 < end1)
   {    {
Line 2250  while (src1 < end1) Line 2459  while (src1 < end1)
 return src2;  return src2;
 }  }
   
#endif#endif /* SUPPORT_UTF && SUPPORT_UCP */
#endif 
   
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,
     compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
uschar *othercasebyte = NULL;pcre_uchar *othercasechar = NULL;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
int utf8length;int utflength;
 #endif  #endif
   
 if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
Line 2268  if (caseless && char_has_othercase(common, cc)) Line 2476  if (caseless && char_has_othercase(common, cc))
   othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
   SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
   /* Extracting bit difference info. */    /* Extracting bit difference info. */
  othercasebyte = cc + (othercasebit >> 8);#ifdef COMPILE_PCRE8
   othercasechar = cc + (othercasebit >> 8);
   othercasebit &= 0xff;    othercasebit &= 0xff;
   #else
   #ifdef COMPILE_PCRE16
     othercasechar = cc + (othercasebit >> 9);
     if ((othercasebit & 0x100) != 0)
       othercasebit = (othercasebit & 0xff) << 8;
     else
       othercasebit &= 0xff;
   #endif
   #endif
   }    }
   
 if (context->sourcereg == -1)  if (context->sourcereg == -1)
   {    {
   #ifdef COMPILE_PCRE8
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
   if (context->length >= 4)    if (context->length >= 4)
     OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
   else if (context->length >= 2)    else if (context->length >= 2)
    OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);    OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
   else    else
 #endif  #endif
     OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
   #else
   #ifdef COMPILE_PCRE16
   #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
     if (context->length >= 4)
       OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
     else
   #endif
       OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
   #endif
   #endif /* COMPILE_PCRE8 */
   context->sourcereg = TMP2;    context->sourcereg = TMP2;
   }    }
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
utf8length = 1;utflength = 1;
if (common->utf8 && *cc >= 0xc0)if (common->utf && HAS_EXTRALEN(*cc))
  utf8length += _pcre_utf8_table4[*cc & 0x3f];  utflength += GET_EXTRALEN(*cc);
   
 do  do
   {    {
 #endif  #endif
   
  context->length--;  context->length -= IN_UCHARS(1);
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
   
   /* Unaligned read is supported. */    /* Unaligned read is supported. */
  if (othercasebit != 0 && othercasebyte == cc)  if (othercasebit != 0 && othercasechar == cc)
     {      {
    context->c.asbytes[context->byteptr] = *cc | othercasebit;    context->c.asuchars[context->ucharptr] = *cc | othercasebit;
    context->oc.asbytes[context->byteptr] = othercasebit;    context->oc.asuchars[context->ucharptr] = othercasebit;
     }      }
   else    else
     {      {
    context->c.asbytes[context->byteptr] = *cc;    context->c.asuchars[context->ucharptr] = *cc;
    context->oc.asbytes[context->byteptr] = 0;    context->oc.asuchars[context->ucharptr] = 0;
     }      }
  context->byteptr++;  context->ucharptr++;
   
  if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))#ifdef COMPILE_PCRE8
   if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
 #else
   if (context->ucharptr >= 2 || context->length == 0)
 #endif
     {      {
     if (context->length >= 4)      if (context->length >= 4)
       OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);        OP1(SLJIT_MOV_SI, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
   #ifdef COMPILE_PCRE8
     else if (context->length >= 2)      else if (context->length >= 2)
      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);
     else if (context->length >= 1)      else if (context->length >= 1)
       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);
   #else
       else if (context->length >= 2)
         OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
   #endif
     context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
   
    switch(context->byteptr)    switch(context->ucharptr)
       {        {
      case 4:      case 4 / sizeof(pcre_uchar):
       if (context->oc.asint != 0)        if (context->oc.asint != 0)
         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);
       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));
       break;        break;
   
      case 2:      case 2 / sizeof(pcre_uchar):
      if (context->oc.asshort != 0)      if (context->oc.asushort != 0)
        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);
      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));
       break;        break;
   
   #ifdef COMPILE_PCRE8
       case 1:        case 1:
       if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
         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);
       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));
       break;        break;
   #endif
   
       default:        default:
       SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
       break;        break;
       }        }
    context->byteptr = 0;    context->ucharptr = 0;
     }      }
   
 #else  #else
   
   /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
   #ifdef COMPILE_PCRE8
   if (context->length > 0)    if (context->length > 0)
     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);
   #else
     if (context->length > 0)
       OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
   #endif
   context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
   
  if (othercasebit != 0 && othercasebyte == cc)  if (othercasebit != 0 && othercasechar == cc)
     {      {
     OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
     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 2610  do
 #endif  #endif
   
   cc++;    cc++;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  utf8length--;  utflength--;
   }    }
while (utf8length > 0);while (utflength > 0);
 #endif  #endif
   
 return cc;  return cc;
 }  }
   
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
   
 #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
   if ((value) != typeoffset) \    if ((value) != typeoffset) \
Line 2396  return cc; Line 2641  return cc;
     } \      } \
   charoffset = (value);    charoffset = (value);
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 jump_list *found = NULL;  jump_list *found = NULL;
Line 2404  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fal Line 2649  jump_list **list = (*cc & XCL_NOT) == 0 ? &found : fal
 unsigned int c;  unsigned int c;
 int compares;  int compares;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
uschar *ccbegin;pcre_uchar *ccbegin;
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
 BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
 BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
Line 2414  unsigned int typeoffset; Line 2659  unsigned int typeoffset;
 int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
 unsigned int charoffset;  unsigned int charoffset;
   
/* 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. */
 check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
 read_char(common);  read_char(common);
   
 if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
   {    {
   OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
  if (common->utf8)#ifndef COMPILE_PCRE8
   jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
 #elif defined SUPPORT_UTF
   if (common->utf)
     jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
   #endif
   
   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
   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 2680  if ((*cc++ & XCL_MAP) != 0)
   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);
   add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
   
  if (common->utf8)#ifndef COMPILE_PCRE8
   JUMPHERE(jump);
 #elif defined SUPPORT_UTF
   if (common->utf)
     JUMPHERE(jump);      JUMPHERE(jump);
   #endif
   OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
   charsaved = TRUE;    charsaved = TRUE;
 #endif  #endif
  cc += 32;  cc += 32 / sizeof(pcre_uchar);
   }    }
   
 /* Scanning the necessary info. */  /* Scanning the necessary info. */
Line 2449  while (*cc != XCL_END) Line 2702  while (*cc != XCL_END)
   if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
     {      {
     cc += 2;      cc += 2;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    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]);
 #endif  #endif
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
     needschar = TRUE;      needschar = TRUE;
Line 2459  while (*cc != XCL_END) Line 2712  while (*cc != XCL_END)
   else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
     {      {
     cc += 2;      cc += 2;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    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]);
 #endif  #endif
     cc++;      cc++;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    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]);
 #endif  #endif
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
     needschar = TRUE;      needschar = TRUE;
Line 2534  if (needstype || needsscript) Line 2787  if (needstype || needsscript)
     {      {
     if (scriptreg == TMP1)      if (scriptreg == TMP1)
       {        {
      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));
       OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
       }        }
     else      else
       {        {
       OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
      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));
       OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
       }        }
     }      }
Line 2564  while (*cc != XCL_END) Line 2817  while (*cc != XCL_END)
   if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
     {      {
     cc ++;      cc ++;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    if (common->utf8)    if (common->utf)
       {        {
       GETCHARINC(c, cc);        GETCHARINC(c, cc);
       }        }
Line 2595  while (*cc != XCL_END) Line 2848  while (*cc != XCL_END)
   else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
     {      {
     cc ++;      cc ++;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    if (common->utf8)    if (common->utf)
       {        {
       GETCHARINC(c, cc);        GETCHARINC(c, cc);
       }        }
Line 2604  while (*cc != XCL_END) Line 2857  while (*cc != XCL_END)
 #endif  #endif
       c = *cc++;        c = *cc++;
     SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    if (common->utf8)    if (common->utf)
       {        {
       GETCHARINC(c, cc);        GETCHARINC(c, cc);
       }        }
Line 2661  while (*cc != XCL_END) Line 2914  while (*cc != XCL_END)
       break;        break;
   
       case PT_GC:        case PT_GC:
      c = _pcre_ucp_typerange[(int)cc[1] * 2];      c = PRIV(ucp_typerange)[(int)cc[1] * 2];
       SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
      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);
       break;        break;
   
       case PT_PC:        case PT_PC:
Line 2725  if (found != NULL) Line 2978  if (found != NULL)
   
 #endif  #endif
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 int length;  int length;
 unsigned int c, oc, bit;  unsigned int c, oc, bit;
 compare_context context;  compare_context context;
 struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
 struct sljit_label *label;  struct sljit_label *label;
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
uschar propdata[5];pcre_uchar propdata[5];
 #endif  #endif
 #endif  #endif
   
Line 2790  switch(type) Line 3043  switch(type)
     {      {
     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);
     jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
     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));
     JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
     JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
Line 2801  switch(type) Line 3054  switch(type)
   
   case OP_ALLANY:    case OP_ALLANY:
   check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  if (common->utf8)  if (common->utf)
     {      {
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
    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));
 #ifdef COMPILE_PCRE8
     jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
    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);
     OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   #else /* COMPILE_PCRE8 */
   #ifdef COMPILE_PCRE16
       jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
       OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
       OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
       COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
       OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
   #endif /* COMPILE_PCRE16 */
   #endif /* COMPILE_PCRE8 */
     JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
     return cc;      return cc;
     }      }
 #endif  #endif
  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));
   return cc;    return cc;
   
   case OP_ANYBYTE:    case OP_ANYBYTE:
   check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
  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));
   return cc;    return cc;
   
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
   case OP_NOTPROP:    case OP_NOTPROP:
   case OP_PROP:    case OP_PROP:
Line 2840  switch(type) Line 3104  switch(type)
   read_char(common);    read_char(common);
   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);
   jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
   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);
  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));
   jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
   JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
   check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
Line 2892  switch(type) Line 3156  switch(type)
   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);
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
     {      {
    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
     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));
    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
     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));
     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));
     }      }
   else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
     {      {
    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
     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));
     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));
     }      }
   else    else
     {      {
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
     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);
    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
     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);
     jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
     add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);    /* Equal. */
     OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
     jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
     add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
   
     JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
     if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
       {        {
      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
       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));
       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));
       }        }
Line 2961  switch(type) Line 3226  switch(type)
   jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
   JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
   
  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end));  add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));
  add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0)); 
 
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
     {      {
    OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);    OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
     add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
     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));
     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));
     }      }
Line 3003  switch(type) Line 3266  switch(type)
   
   if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
     {      {
    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
     add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
     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));
     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));
     }      }
Line 3021  switch(type) Line 3284  switch(type)
   case OP_CHAR:    case OP_CHAR:
   case OP_CHARI:    case OP_CHARI:
   length = 1;    length = 1;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
 #endif  #endif
   if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
     {      {
    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));
     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));
   
    context.length = length;    context.length = IN_UCHARS(length);
     context.sourcereg = -1;      context.sourcereg = -1;
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
    context.byteptr = 0;    context.ucharptr = 0;
 #endif  #endif
     return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
     }      }
  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  check_input_end(common, fallbacks);
   read_char(common);    read_char(common);
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  if (common->utf8)  if (common->utf)
     {      {
     GETCHAR(c, cc);      GETCHAR(c, cc);
     }      }
Line 3055  switch(type) Line 3318  switch(type)
   
   case OP_NOT:    case OP_NOT:
   case OP_NOTI:    case OP_NOTI:
     check_input_end(common, fallbacks);
   length = 1;    length = 1;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  if (common->utf8)  if (common->utf)
     {      {
    if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];#ifdef COMPILE_PCRE8
    c = *cc;
    check_input_end(common, fallbacks);    if (c < 128)
    GETCHAR(c, cc); 
 
    if (c <= 127) 
       {        {
       OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
       if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
Line 3076  switch(type) Line 3337  switch(type)
         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));
         }          }
       /* Skip the variable-length character. */        /* Skip the variable-length character. */
      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));
       jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
      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);
       OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
       JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
      return cc + length;      return cc + 1;
       }        }
     else      else
   #endif /* COMPILE_PCRE8 */
         {
         GETCHARLEN(c, cc, length);
       read_char(common);        read_char(common);
         }
     }      }
   else    else
#endif#endif /* SUPPORT_UTF */
     {      {
    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); 
     c = *cc;      c = *cc;
     }      }
   
Line 3112  switch(type) Line 3375  switch(type)
       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));
       }        }
     }      }
  return cc + length;  return cc + 1;
   
   case OP_CLASS:    case OP_CLASS:
   case OP_NCLASS:    case OP_NCLASS:
   check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
   read_char(common);    read_char(common);
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
   jump[0] = NULL;    jump[0] = NULL;
  if (common->utf8)#ifdef COMPILE_PCRE8
   /* This check only affects 8 bit mode. In other modes, we
   always need to compare the value with 255. */
   if (common->utf)
 #endif /* COMPILE_PCRE8 */
     {      {
     jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
     if (type == OP_CLASS)      if (type == OP_CLASS)
Line 3129  switch(type) Line 3396  switch(type)
       jump[0] = NULL;        jump[0] = NULL;
       }        }
     }      }
#endif#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
   OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
   OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
   OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
   OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
   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);
   add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || !defined COMPILE_PCRE8
   if (jump[0] != NULL)    if (jump[0] != NULL)
     JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
#endif#endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
  return cc + 32;  return cc + 32 / sizeof(pcre_uchar);
   
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || defined COMPILE_PCRE16
   case OP_XCLASS:    case OP_XCLASS:
   compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
   return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
Line 3152  switch(type) Line 3419  switch(type)
   length = GET(cc, 0);    length = GET(cc, 0);
   SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
   OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));#ifdef SUPPORT_UTF
#ifdef SUPPORT_UTF8  if (common->utf)
  if (common->utf8) 
     {      {
       OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
     OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
     label = LABEL();      label = LABEL();
    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));
     skip_char_back(common);      skip_char_back(common);
     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);
     JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;      return cc + LINK_SIZE;
     }      }
 #endif  #endif
  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
   OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
   add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
   return cc + LINK_SIZE;    return cc + LINK_SIZE;
   }    }
Line 3173  SLJIT_ASSERT_STOP(); Line 3441  SLJIT_ASSERT_STOP();
 return cc;  return cc;
 }  }
   
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)
 {  {
 /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
 /* 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. */
 DEFINE_COMPILER;  DEFINE_COMPILER;
uschar *ccbegin = cc;pcre_uchar *ccbegin = cc;
 compare_context context;  compare_context context;
 int size;  int size;
   
Line 3191  do Line 3459  do
   if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
     {      {
     size = 1;      size = 1;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    if (common->utf8 && cc[1] >= 0xc0)    if (common->utf && HAS_EXTRALEN(cc[1]))
      size += _pcre_utf8_table4[cc[1] & 0x3f];      size += GET_EXTRALEN(cc[1]);
 #endif  #endif
     }      }
   else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
     {      {
     size = 1;      size = 1;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
    if (common->utf8)    if (common->utf)
       {        {
       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)
         size = 0;          size = 0;
      else if (cc[1] >= 0xc0)      else if (HAS_EXTRALEN(cc[1]))
        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
       }        }
     else      else
 #endif  #endif
Line 3216  do Line 3484  do
     size = 0;      size = 0;
   
   cc += 1 + size;    cc += 1 + size;
  context.length += size;  context.length += IN_UCHARS(size);
   }    }
 while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
   
Line 3229  if (context.length > 0) Line 3497  if (context.length > 0)
   
   context.sourcereg = -1;    context.sourcereg = -1;
 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
  context.byteptr = 0;  context.ucharptr = 0;
 #endif  #endif
   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);
   return cc;    return cc;
Line 3239  if (context.length > 0) Line 3507  if (context.length > 0)
 return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
Line 3261  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LO Line 3529  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_MEM1(SLJIT_LO
 }  }
   
 /* Forward definitions. */  /* Forward definitions. */
static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
 static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
   
 #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
Line 3292  static void compile_fallbackpath(compiler_common *, st Line 3560  static void compile_fallbackpath(compiler_common *, st
   
 #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type*)fallback)
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
Line 3302  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG),  Line 3570  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), 
 if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
   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)));
   
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF && defined SUPPORT_UCP
#ifdef SUPPORT_UCPif (common->utf && *cc == OP_REFI)
if (common->utf8 && *cc == OP_REFI) 
   {    {
   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);
   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 3582  if (common->utf8 && *cc == OP_REFI)
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
   OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
   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);
  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));
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
   OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
   }    }
 else  else
#endif#endif /* SUPPORT_UTF && SUPPORT_UCP */
#endif 
   {    {
   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);
   if (withchecks)    if (withchecks)
Line 3341  if (jump != NULL) Line 3607  if (jump != NULL)
   else    else
     JUMPHERE(jump);      JUMPHERE(jump);
   }    }
return cc + 3;return cc + 1 + IMM2_SIZE;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
uschar type;pcre_uchar type;
 struct sljit_label *label;  struct sljit_label *label;
 struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
uschar *ccbegin = cc;pcre_uchar *ccbegin = cc;
 int min = 0, max = 0;  int min = 0, max = 0;
 BOOL minimize;  BOOL minimize;
   
 PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
   
type = cc[3];type = cc[1 + IMM2_SIZE];
 minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
 switch(type)  switch(type)
   {    {
Line 3366  switch(type) Line 3632  switch(type)
   case OP_CRMINSTAR:    case OP_CRMINSTAR:
   min = 0;    min = 0;
   max = 0;    max = 0;
  cc += 4;  cc += 1 + IMM2_SIZE + 1;
   break;    break;
   case OP_CRPLUS:    case OP_CRPLUS:
   case OP_CRMINPLUS:    case OP_CRMINPLUS:
   min = 1;    min = 1;
   max = 0;    max = 0;
  cc += 4;  cc += 1 + IMM2_SIZE + 1;
   break;    break;
   case OP_CRQUERY:    case OP_CRQUERY:
   case OP_CRMINQUERY:    case OP_CRMINQUERY:
   min = 0;    min = 0;
   max = 1;    max = 1;
  cc += 4;  cc += 1 + IMM2_SIZE + 1;
   break;    break;
   case OP_CRRANGE:    case OP_CRRANGE:
   case OP_CRMINRANGE:    case OP_CRMINRANGE:
  min = GET2(cc, 3 + 1);  min = GET2(cc, 1 + IMM2_SIZE + 1);
  max = GET2(cc, 3 + 3);  max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
  cc += 8;  cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
   break;    break;
   default:    default:
   SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
Line 3488  decrease_call_count(common); Line 3754  decrease_call_count(common);
 return cc;  return cc;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
Line 3534  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_ Line 3800  add_jump(compiler, &fallback->topfallbacks, CMP(SLJIT_
 return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 int framesize;  int framesize;
 int localptr;  int localptr;
 fallback_common altfallback;  fallback_common altfallback;
uschar *ccbegin;pcre_uchar *ccbegin;
uschar opcode;pcre_uchar opcode;
uschar bra = OP_BRA;pcre_uchar bra = OP_BRA;
 jump_list *tmp = NULL;  jump_list *tmp = NULL;
 jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
 jump_list **found;  jump_list **found;
Line 3558  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO) Line 3824  if (*cc == OP_BRAZERO || *cc == OP_BRAMINZERO)
   bra = *cc;    bra = *cc;
   cc++;    cc++;
   }    }
localptr = PRIV(cc);localptr = PRIV_DATA(cc);
 SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
 framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
 fallback->framesize = framesize;  fallback->framesize = framesize;
Line 3804  common->accept = save_accept; Line 4070  common->accept = save_accept;
 return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
 }  }
   
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)
 {  {
 int condition = FALSE;  int condition = FALSE;
uschar *slotA = name_table;pcre_uchar *slotA = name_table;
uschar *slotB;pcre_uchar *slotB;
 sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
 sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
 sljit_w no_capture;  sljit_w no_capture;
Line 3833  if (i < name_count) Line 4099  if (i < name_count)
   while (slotB > name_table)    while (slotB > name_table)
     {      {
     slotB -= name_entry_size;      slotB -= name_entry_size;
    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)    if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
       {        {
       condition = locals[GET2(slotB, 0) << 1] != no_capture;        condition = locals[GET2(slotB, 0) << 1] != no_capture;
       if (condition) break;        if (condition) break;
Line 3848  if (i < name_count) Line 4114  if (i < name_count)
     for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
       {        {
       slotB += name_entry_size;        slotB += name_entry_size;
      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
         {          {
         condition = locals[GET2(slotB, 0) << 1] != no_capture;          condition = locals[GET2(slotB, 0) << 1] != no_capture;
         if (condition) break;          if (condition) break;
Line 3860  if (i < name_count) Line 4126  if (i < name_count)
 return condition;  return condition;
 }  }
   
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)
 {  {
 int condition = FALSE;  int condition = FALSE;
uschar *slotA = name_table;pcre_uchar *slotA = name_table;
uschar *slotB;pcre_uchar *slotB;
 sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
 sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
 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 4152  if (i < name_count)
   while (slotB > name_table)    while (slotB > name_table)
     {      {
     slotB -= name_entry_size;      slotB -= name_entry_size;
    if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)    if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
       {        {
       condition = GET2(slotB, 0) == group_num;        condition = GET2(slotB, 0) == group_num;
       if (condition) break;        if (condition) break;
Line 3901  if (i < name_count) Line 4167  if (i < name_count)
     for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
       {        {
       slotB += name_entry_size;        slotB += name_entry_size;
      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
         {          {
         condition = GET2(slotB, 0) == group_num;          condition = GET2(slotB, 0) == group_num;
         if (condition) break;          if (condition) break;
Line 3967  return condition; Line 4233  return condition;
                                           Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
 */  */
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
uschar opcode;pcre_uchar opcode;
 int localptr = 0;  int localptr = 0;
 int offset = 0;  int offset = 0;
 int stacksize;  int stacksize;
uschar *ccbegin;pcre_uchar *ccbegin;
uschar *hotpath;pcre_uchar *hotpath;
uschar bra = OP_BRA;pcre_uchar bra = OP_BRA;
uschar ket;pcre_uchar ket;
 assert_fallback *assert;  assert_fallback *assert;
 BOOL has_alternatives;  BOOL has_alternatives;
 struct sljit_jump *jump;  struct sljit_jump *jump;
Line 4039  if (opcode == OP_CBRA || opcode == OP_SCBRA) Line 4305  if (opcode == OP_CBRA || opcode == OP_SCBRA)
   localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
   offset <<= 1;    offset <<= 1;
   FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
  hotpath += 2;  hotpath += IMM2_SIZE;
   }    }
 else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
   {    {
   /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
  localptr = PRIV(ccbegin);  localptr = PRIV_DATA(ccbegin);
   SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
   FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
   if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
Line 4203  if (opcode == OP_COND || opcode == OP_SCOND) Line 4469  if (opcode == OP_COND || opcode == OP_SCOND)
     SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
     add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
       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)));
    hotpath += 3;    hotpath += 1 + IMM2_SIZE;
     }      }
   else if (*hotpath == OP_NCREF)    else if (*hotpath == OP_NCREF)
     {      {
Line 4222  if (opcode == OP_COND || opcode == OP_SCOND) Line 4488  if (opcode == OP_COND || opcode == OP_SCOND)
     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));
   
     JUMPHERE(jump);      JUMPHERE(jump);
    hotpath += 3;    hotpath += 1 + IMM2_SIZE;
     }      }
   else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
     {      {
Line 4243  if (opcode == OP_COND || opcode == OP_SCOND) Line 4509  if (opcode == OP_COND || opcode == OP_SCOND)
       {        {
       SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
       if (stacksize != 0)        if (stacksize != 0)
        hotpath += 3;        hotpath += 1 + IMM2_SIZE;
       else        else
         {          {
         if (*cc == OP_ALT)          if (*cc == OP_ALT)
Line 4270  if (opcode == OP_COND || opcode == OP_SCOND) Line 4536  if (opcode == OP_COND || opcode == OP_SCOND)
       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));
       OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
       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));
      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
       }        }
     }      }
   else    else
Line 4406  cc += 1 + LINK_SIZE; Line 4672  cc += 1 + LINK_SIZE;
 return cc;  return cc;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
uschar opcode;pcre_uchar opcode;
 int localptr;  int localptr;
 int cbraprivptr = 0;  int cbraprivptr = 0;
 int framesize;  int framesize;
 int stacksize;  int stacksize;
 int offset = 0;  int offset = 0;
 BOOL zero = FALSE;  BOOL zero = FALSE;
uschar *ccbegin = NULL;pcre_uchar *ccbegin = NULL;
 int stack;  int stack;
 struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
 struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
Line 4430  if (*cc == OP_BRAPOSZERO) Line 4696  if (*cc == OP_BRAPOSZERO)
   }    }
   
 opcode = *cc;  opcode = *cc;
localptr = PRIV(cc);localptr = PRIV_DATA(cc);
 SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
 FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
 switch(opcode)  switch(opcode)
Line 4445  switch(opcode) Line 4711  switch(opcode)
   offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
   cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
   offset <<= 1;    offset <<= 1;
  ccbegin = cc + 1 + LINK_SIZE + 2;  ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
   break;    break;
   
   default:    default:
Line 4624  decrease_call_count(common); Line 4890  decrease_call_count(common);
 return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
 }  }
   
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)
 {  {
 int class_len;  int class_len;
   
Line 4663  else Line 4929  else
   SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
   *type = *opcode;    *type = *opcode;
   cc++;    cc++;
  class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);  class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
   *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
   if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
     {      {
Line 4674  else Line 4940  else
   else    else
     {      {
     SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
    *arg1 = GET2(cc, (class_len + 2));    *arg1 = GET2(cc, (class_len + IMM2_SIZE));
     *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
   
     if (*arg2 == 0)      if (*arg2 == 0)
Line 4686  else Line 4952  else
       *opcode = OP_EXACT;        *opcode = OP_EXACT;
   
     if (end != NULL)      if (end != NULL)
      *end = cc + class_len + 4;      *end = cc + class_len + 2 * IMM2_SIZE;
     }      }
   return cc;    return cc;
   }    }
Line 4694  else Line 4960  else
 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)
   {    {
   *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
  cc += 2;  cc += IMM2_SIZE;
   }    }
   
 if (*type == 0)  if (*type == 0)
Line 4709  if (*type == 0) Line 4975  if (*type == 0)
 if (end != NULL)  if (end != NULL)
   {    {
   *end = cc + 1;    *end = cc + 1;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
  if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];  if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
 #endif  #endif
   }    }
 return cc;  return cc;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
uschar opcode;pcre_uchar opcode;
uschar type;pcre_uchar type;
 int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
uschar* end;pcre_uchar* end;
 jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
 struct sljit_label *label;  struct sljit_label *label;
Line 4885  decrease_call_count(common); Line 5151  decrease_call_count(common);
 return end;  return end;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
Line 4929  add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT Line 5195  add_jump(compiler, &fallback->topfallbacks, JUMP(SLJIT
 return cc + 1;  return cc + 1;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
   
 /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
 if (common->currententry != NULL)  if (common->currententry != NULL)
  return cc + 3;  return cc + 1 + IMM2_SIZE;
   
 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));
 offset <<= 1;  offset <<= 1;
 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);
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
return cc + 3;return cc + 1 + IMM2_SIZE;
 }  }
   
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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
 fallback_common *fallback;  fallback_common *fallback;
Line 5071  while (cc < ccend) Line 5337  while (cc < ccend)
   
     case OP_CLASS:      case OP_CLASS:
     case OP_NCLASS:      case OP_NCLASS:
    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)
       cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
     else      else
       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);
     break;      break;
   
#ifdef SUPPORT_UTF8#if defined SUPPORT_UTF || defined COMPILE_PCRE16
     case OP_XCLASS:      case OP_XCLASS:
     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)
       cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
Line 5088  while (cc < ccend) Line 5354  while (cc < ccend)
   
     case OP_REF:      case OP_REF:
     case OP_REFI:      case OP_REFI:
    if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)    if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
       cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
     else      else
       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 5196  SLJIT_ASSERT(cc == ccend); Line 5462  SLJIT_ASSERT(cc == ccend);
 static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
uschar *cc = current->cc;pcre_uchar *cc = current->cc;
uschar opcode;pcre_uchar opcode;
uschar type;pcre_uchar type;
 int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
 struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
 struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
Line 5323  switch(opcode) Line 5589  switch(opcode)
 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)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
uschar *cc = current->cc;pcre_uchar *cc = current->cc;
uschar type;pcre_uchar type;
   
type = cc[3];type = cc[1 + IMM2_SIZE];
 if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
   {    {
   set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
Line 5355  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0 Line 5621  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0
 static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
uschar *cc = current->cc;pcre_uchar *cc = current->cc;
uschar bra = OP_BRA;pcre_uchar bra = OP_BRA;
 struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
   
 SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
Line 5427  int offset = 0; Line 5693  int offset = 0;
 int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
 int stacksize;  int stacksize;
 int count;  int count;
uschar *cc = current->cc;pcre_uchar *cc = current->cc;
uschar *ccbegin;pcre_uchar *ccbegin;
uschar *ccprev;pcre_uchar *ccprev;
 jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
 jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
uschar bra = OP_BRA;pcre_uchar bra = OP_BRA;
uschar ket;pcre_uchar ket;
 assert_fallback *assert;  assert_fallback *assert;
 BOOL has_alternatives;  BOOL has_alternatives;
 struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
Line 5933  while (current) Line 6199  while (current)
     case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
     case OP_CLASS:      case OP_CLASS:
     case OP_NCLASS:      case OP_NCLASS:
   #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
     case OP_XCLASS:      case OP_XCLASS:
   #endif
     compile_iterator_fallbackpath(common, current);      compile_iterator_fallbackpath(common, current);
     break;      break;
   
Line 6000  while (current) Line 6268  while (current)
 static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
 {  {
 DEFINE_COMPILER;  DEFINE_COMPILER;
uschar *cc = common->start + common->currententry->start;pcre_uchar *cc = common->start + common->currententry->start;
uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
uschar *ccend = bracketend(cc);pcre_uchar *ccend = bracketend(cc);
 int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
 int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
 int alternativesize;  int alternativesize;
Line 6090  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP) Line 6358  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP)
 #undef CURRENT_AS  #undef CURRENT_AS
   
 void  void
_pcre_jit_compile(const real_pcre *re, pcre_extra *extra)PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)
 {  {
 struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
 fallback_common rootfallback;  fallback_common rootfallback;
 compiler_common common_data;  compiler_common common_data;
 compiler_common *common = &common_data;  compiler_common *common = &common_data;
const uschar *tables = re->tables;const pcre_uint8 *tables = re->tables;
 pcre_study_data *study;  pcre_study_data *study;
uschar *ccend;pcre_uchar *ccend;
 executable_function *function;  executable_function *function;
 void *executable_func;  void *executable_func;
 sljit_uw executable_size;  sljit_uw executable_size;
Line 6114  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) != Line 6382  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_STUDY_DATA) !=
 study = extra->study_data;  study = extra->study_data;
   
 if (!tables)  if (!tables)
  tables = _pcre_default_tables;  tables = PRIV(default_tables);
   
 memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
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;
   
 common->compiler = NULL;  common->compiler = NULL;
 common->start = rootfallback.cc;  common->start = rootfallback.cc;
Line 6158  else Line 6426  else
   }    }
 common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
 common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
common->name_table = (sljit_w)re + re->name_table_offset;common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
 common->name_count = re->name_count;  common->name_count = re->name_count;
 common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
 common->acceptlabel = NULL;  common->acceptlabel = NULL;
Line 6176  common->vspace = NULL; Line 6444  common->vspace = NULL;
 common->casefulcmp = NULL;  common->casefulcmp = NULL;
 common->caselesscmp = NULL;  common->caselesscmp = NULL;
 common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
common->utf8 = (re->options & PCRE_UTF8) != 0;/* PCRE_UTF16 has the same value as PCRE_UTF8. */
 common->utf = (re->options & PCRE_UTF8) != 0;
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
common->useucp = (re->options & PCRE_UCP) != 0;common->use_ucp = (re->options & PCRE_UCP) != 0;
 #endif  #endif
common->utf8readchar = NULL;common->utfreadchar = NULL;
common->utf8readtype8 = NULL;#ifdef COMPILE_PCRE8
 common->utfreadtype8 = NULL;
 #endif  #endif
   #endif /* SUPPORT_UTF */
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
 common->getucd = NULL;  common->getucd = NULL;
 #endif  #endif
Line 6215  sljit_emit_enter(compiler, 1, 5, 5, common->localsize) Line 6486  sljit_emit_enter(compiler, 1, 5, 5, common->localsize)
 /* Register init. */  /* Register init. */
 reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
 if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
  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);
   
OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
 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));
 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));
 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 6233  if ((re->options & PCRE_ANCHORED) == 0) Line 6504  if ((re->options & PCRE_ANCHORED) == 0)
   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);
   /* Forward search if possible. */    /* Forward search if possible. */
   if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
    fast_forward_first_byte(common, re->first_byte, (re->options & PCRE_FIRSTLINE) != 0);    fast_forward_first_char(common, re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
   else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
     fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
   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)
     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);
   }    }
 if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
  reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);  reqbyte_notfound = search_requested_char(common, re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
   
 /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
 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);
Line 6265  if (common->accept != NULL) Line 6536  if (common->accept != NULL)
 /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
 copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
 leave = LABEL();  leave = LABEL();
sljit_emit_return(compiler, SLJIT_UNUSED, 0);sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
   
 empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
 compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
Line 6287  if ((re->options & PCRE_ANCHORED) == 0) Line 6558  if ((re->options & PCRE_ANCHORED) == 0)
     {      {
     if (study != NULL && study->minlength > 1)      if (study != NULL && study->minlength > 1)
       {        {
      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));
       CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
       }        }
     else      else
Line 6297  if ((re->options & PCRE_ANCHORED) == 0) Line 6568  if ((re->options & PCRE_ANCHORED) == 0)
     {      {
     if (study != NULL && study->minlength > 1)      if (study != NULL && study->minlength > 1)
       {        {
      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));
       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);
       COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
       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 6409  if (common->caselesscmp != NULL) Line 6680  if (common->caselesscmp != NULL)
   set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
   do_caselesscmp(common);    do_caselesscmp(common);
   }    }
#ifdef SUPPORT_UTF8#ifdef SUPPORT_UTF
if (common->utf8readchar != NULL)if (common->utfreadchar != NULL)
   {    {
  set_jumps(common->utf8readchar, LABEL());  set_jumps(common->utfreadchar, LABEL());
  do_utf8readchar(common);  do_utfreadchar(common);
   }    }
if (common->utf8readtype8 != NULL)#ifdef COMPILE_PCRE8
 if (common->utfreadtype8 != NULL)
   {    {
  set_jumps(common->utf8readtype8, LABEL());  set_jumps(common->utfreadtype8, LABEL());
  do_utf8readtype8(common);  do_utfreadtype8(common);
   }    }
 #endif  #endif
   #endif /* COMPILE_PCRE8 */
 #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
 if (common->getucd != NULL)  if (common->getucd != NULL)
   {    {
Line 6459  union { Line 6732  union {
    void* executable_func;     void* executable_func;
    jit_function call_executable_func;     jit_function call_executable_func;
 } convert_executable_func;  } convert_executable_func;
uschar local_area[LOCAL_SPACE_SIZE];pcre_uint8 local_area[LOCAL_SPACE_SIZE];
 struct sljit_stack local_stack;  struct sljit_stack local_stack;
   
 local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_area;
Line 6472  return convert_executable_func.call_executable_func(ar Line 6745  return convert_executable_func.call_executable_func(ar
 }  }
   
 int  int
_pcre_jit_exec(const real_pcre *re, void *executable_func,PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,
  PCRE_SPTR subject, int length, int start_offset, int options,  const pcre_uchar *subject, int length, int start_offset, int options,
   int match_limit, int *offsets, int offsetcount)    int match_limit, int *offsets, int offsetcount)
 {  {
 executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
Line 6503  workspace. We don't need the workspace here. For compa Line 6776  workspace. We don't need the workspace here. For compa
 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
 gets the same result with and without JIT. */  gets the same result with and without JIT. */
   
offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3;if (offsetcount != 2)
   offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
 maxoffsetcount = (re->top_bracket + 1) * 2;  maxoffsetcount = (re->top_bracket + 1) * 2;
 if (offsetcount > maxoffsetcount)  if (offsetcount > maxoffsetcount)
   offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
Line 6528  return retval; Line 6802  return retval;
 }  }
   
 void  void
_pcre_jit_free(void *executable_func)PRIV(jit_free)(void *executable_func)
 {  {
 executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
 sljit_free_code(function->executable_func);  sljit_free_code(function->executable_func);
Line 6536  SLJIT_FREE(function); Line 6810  SLJIT_FREE(function);
 }  }
   
 int  int
_pcre_jit_get_size(void *executable_func)PRIV(jit_get_size)(void *executable_func)
 {  {
 return ((executable_function*)executable_func)->executable_size;  return ((executable_function*)executable_func)->executable_size;
 }  }
   
   const char*
   PRIV(jit_get_target)(void)
   {
   return sljit_get_platform_name();
   }
   
   #ifdef COMPILE_PCRE8
 PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
 pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
   #else
   PCRE_EXP_DECL pcre16_jit_stack *
   pcre16_jit_stack_alloc(int startsize, int maxsize)
   #endif
 {  {
 if (startsize < 1 || maxsize < 1)  if (startsize < 1 || maxsize < 1)
   return NULL;    return NULL;
Line 6550  if (startsize > maxsize) Line 6835  if (startsize > maxsize)
   startsize = maxsize;    startsize = maxsize;
 startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
 maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
return (pcre_jit_stack*)sljit_allocate_stack(startsize, maxsize);return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
 }  }
   
   #ifdef COMPILE_PCRE8
 PCRE_EXP_DECL void  PCRE_EXP_DECL void
 pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
   #else
   PCRE_EXP_DECL void
   pcre16_jit_stack_free(pcre16_jit_stack *stack)
   #endif
 {  {
 sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack*)stack);
 }  }
   
   #ifdef COMPILE_PCRE8
 PCRE_EXP_DECL void  PCRE_EXP_DECL void
 pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
   #else
   PCRE_EXP_DECL void
   pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
   #endif
 {  {
 executable_function *function;  executable_function *function;
 if (extra != NULL &&  if (extra != NULL &&
Line 6578  if (extra != NULL && Line 6873  if (extra != NULL &&
 /* These are dummy functions to avoid linking errors when JIT support is not  /* These are dummy functions to avoid linking errors when JIT support is not
 being compiled. */  being compiled. */
   
   #ifdef COMPILE_PCRE8
 PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
 pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
   #else
   PCRE_EXP_DECL pcre16_jit_stack *
   pcre16_jit_stack_alloc(int startsize, int maxsize)
   #endif
 {  {
 (void)startsize;  (void)startsize;
 (void)maxsize;  (void)maxsize;
 return NULL;  return NULL;
 }  }
   
   #ifdef COMPILE_PCRE8
 PCRE_EXP_DECL void  PCRE_EXP_DECL void
 pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
   #else
   PCRE_EXP_DECL void
   pcre16_jit_stack_free(pcre16_jit_stack *stack)
   #endif
 {  {
 (void)stack;  (void)stack;
 }  }
   
   #ifdef COMPILE_PCRE8
 PCRE_EXP_DECL void  PCRE_EXP_DECL void
 pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)  pcre_assign_jit_stack(pcre_extra *extra, pcre_jit_callback callback, void *userdata)
   #else
   PCRE_EXP_DECL void
   pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
   #endif
 {  {
 (void)extra;  (void)extra;
 (void)callback;  (void)callback;

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>