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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 736 by zherczeg, Sun Oct 16 15:48:03 2011 UTC revision 911 by zherczeg, Fri Feb 10 08:05:30 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_function {
166    void *executable_func;    void *executable_func;
167    pcre_jit_callback callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169      sljit_uw executable_size;
170  } executable_function;  } executable_function;
171    
172  typedef struct jump_list {  typedef struct jump_list {
# Line 194  typedef struct fallback_common { Line 198  typedef struct fallback_common {
198    struct fallback_common *top;    struct fallback_common *top;
199    jump_list *topfallbacks;    jump_list *topfallbacks;
200    /* Opcode pointer. */    /* Opcode pointer. */
201    uschar *cc;    pcre_uchar *cc;
202  } fallback_common;  } fallback_common;
203    
204  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 265  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
269    
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    uschar *start;    pcre_uchar *start;
273    int localsize;    int localsize;
274    int *localptrs;    int *localptrs;
275    const uschar *fcc;    const pcre_uint8 *fcc;
276    sljit_w lcc;    sljit_w lcc;
277    int cbraptr;    int cbraptr;
278    int nltype;    int nltype;
# Line 276  typedef struct compiler_common { Line 280  typedef struct compiler_common {
280    int bsr_nltype;    int bsr_nltype;
281    int endonly;    int endonly;
282    sljit_w ctypes;    sljit_w ctypes;
283      sljit_uw name_table;
284      sljit_w name_count;
285      sljit_w name_entry_size;
286    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
287    stub_list *stubs;    stub_list *stubs;
288    recurse_entry *entries;    recurse_entry *entries;
# Line 291  typedef struct compiler_common { Line 298  typedef struct compiler_common {
298    jump_list *casefulcmp;    jump_list *casefulcmp;
299    jump_list *caselesscmp;    jump_list *caselesscmp;
300    BOOL jscript_compat;    BOOL jscript_compat;
301  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
302    BOOL utf8;    BOOL utf;
303  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
304    BOOL useucp;    BOOL use_ucp;
305  #endif  #endif
306    jump_list *utf8readchar;    jump_list *utfreadchar;
307    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
308      jump_list *utfreadtype8;
309  #endif  #endif
310    #endif /* SUPPORT_UTF */
311  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
312    jump_list *getucd;    jump_list *getucd;
313  #endif  #endif
# Line 310  typedef struct compare_context { Line 319  typedef struct compare_context {
319    int length;    int length;
320    int sourcereg;    int sourcereg;
321  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
322    int byteptr;    int ucharptr;
323    union {    union {
324      int asint;      sljit_i asint;
325      short asshort;      sljit_uh asushort;
326    #ifdef COMPILE_PCRE8
327      sljit_ub asbyte;      sljit_ub asbyte;
328      sljit_ub asbytes[4];      sljit_ub asuchars[4];
329    #else
330    #ifdef COMPILE_PCRE16
331        sljit_uh asuchars[2];
332    #endif
333    #endif
334    } c;    } c;
335    union {    union {
336      int asint;      sljit_i asint;
337      short asshort;      sljit_uh asushort;
338    #ifdef COMPILE_PCRE8
339      sljit_ub asbyte;      sljit_ub asbyte;
340      sljit_ub asbytes[4];      sljit_ub asuchars[4];
341    #else
342    #ifdef COMPILE_PCRE16
343        sljit_uh asuchars[2];
344    #endif
345    #endif
346    } oc;    } oc;
347  #endif  #endif
348  } compare_context;  } compare_context;
# Line 331  enum { Line 352  enum {
352    frame_setstrbegin = -1    frame_setstrbegin = -1
353  };  };
354    
355    /* Undefine sljit macros. */
356    #undef CMP
357    
358  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
359  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
360    
361  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
362  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
363  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
364  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
365  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
366  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
367  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
368  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
369  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
370  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
371    
372  /* Locals layout. */  /* Locals layout. */
# Line 357  enum { Line 381  enum {
381  /* Max limit of recursions. */  /* Max limit of recursions. */
382  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
383  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
384  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
385  /* End pointer of the first line. */  /* End pointer of the first line. */
386  #define FIRSTLINE_END    (7 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
387  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
# Line 367  the start pointers when the end of the c Line 391  the start pointers when the end of the c
391  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
392  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
393  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
394  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
395    
396    #ifdef COMPILE_PCRE8
397    #define MOV_UCHAR  SLJIT_MOV_UB
398    #define MOVU_UCHAR SLJIT_MOVU_UB
399    #else
400    #ifdef COMPILE_PCRE16
401    #define MOV_UCHAR  SLJIT_MOV_UH
402    #define MOVU_UCHAR SLJIT_MOVU_UH
403    #else
404    #error Unsupported compiling mode
405    #endif
406    #endif
407    
408  /* Shortcuts. */  /* Shortcuts. */
409  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 391  the start pointers when the end of the c Line 427  the start pointers when the end of the c
427  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
428    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
429    
430  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
431  {  {
432  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));
433  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 412  return cc; Line 448  return cc;
448   compile_fallbackpath   compile_fallbackpath
449  */  */
450    
451  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
452  {  {
453  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
454  switch(*cc)  switch(*cc)
# Line 468  switch(*cc) Line 504  switch(*cc)
504    return cc + 1;    return cc + 1;
505    
506    case OP_ANYBYTE:    case OP_ANYBYTE:
507  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
508    if (common->utf8) return NULL;    if (common->utf) return NULL;
509  #endif  #endif
510    return cc + 1;    return cc + 1;
511    
# Line 477  switch(*cc) Line 513  switch(*cc)
513    case OP_CHARI:    case OP_CHARI:
514    case OP_NOT:    case OP_NOT:
515    case OP_NOTI:    case OP_NOTI:
   
516    case OP_STAR:    case OP_STAR:
517    case OP_MINSTAR:    case OP_MINSTAR:
518    case OP_PLUS:    case OP_PLUS:
# Line 515  switch(*cc) Line 550  switch(*cc)
550    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
551    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
552    cc += 2;    cc += 2;
553  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
554    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]);
555  #endif  #endif
556    return cc;    return cc;
557    
# Line 536  switch(*cc) Line 571  switch(*cc)
571    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
572    case OP_NOTEXACTI:    case OP_NOTEXACTI:
573    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
574    cc += 4;    cc += 2 + IMM2_SIZE;
575  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
576    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]);
577  #endif  #endif
578    return cc;    return cc;
579    
580    case OP_NOTPROP:    case OP_NOTPROP:
581    case OP_PROP:    case OP_PROP:
582      return cc + 1 + 2;
583    
584    case OP_TYPEUPTO:    case OP_TYPEUPTO:
585    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
586    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 551  switch(*cc) Line 588  switch(*cc)
588    case OP_REF:    case OP_REF:
589    case OP_REFI:    case OP_REFI:
590    case OP_CREF:    case OP_CREF:
591      case OP_NCREF:
592      case OP_RREF:
593      case OP_NRREF:
594    case OP_CLOSE:    case OP_CLOSE:
595    cc += 3;    cc += 1 + IMM2_SIZE;
596    return cc;    return cc;
597    
598    case OP_CRRANGE:    case OP_CRRANGE:
599    case OP_CRMINRANGE:    case OP_CRMINRANGE:
600    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
601    
602    case OP_CLASS:    case OP_CLASS:
603    case OP_NCLASS:    case OP_NCLASS:
604    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
605    
606  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
607    case OP_XCLASS:    case OP_XCLASS:
608    return cc + GET(cc, 1);    return cc + GET(cc, 1);
609  #endif  #endif
# Line 593  switch(*cc) Line 633  switch(*cc)
633    case OP_CBRAPOS:    case OP_CBRAPOS:
634    case OP_SCBRA:    case OP_SCBRA:
635    case OP_SCBRAPOS:    case OP_SCBRAPOS:
636    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
637    
638    default:    default:
639    return NULL;    return NULL;
640    }    }
641  }  }
642    
643  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
644  {  {
645  int localspace = 0;  int localspace = 0;
646  uschar *alternative;  pcre_uchar *alternative;
647  /* 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. */
648  while (cc < ccend)  while (cc < ccend)
649    {    {
# Line 626  while (cc < ccend) Line 666  while (cc < ccend)
666      case OP_CBRAPOS:      case OP_CBRAPOS:
667      case OP_SCBRAPOS:      case OP_SCBRAPOS:
668      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
669      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
670      break;      break;
671    
672      case OP_COND:      case OP_COND:
# Line 647  while (cc < ccend) Line 687  while (cc < ccend)
687  return localspace;  return localspace;
688  }  }
689    
690  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
691  {  {
692  uschar *cc = common->start;  pcre_uchar *cc = common->start;
693  uschar *alternative;  pcre_uchar *alternative;
694  while (cc < ccend)  while (cc < ccend)
695    {    {
696    switch(*cc)    switch(*cc)
# Line 674  while (cc < ccend) Line 714  while (cc < ccend)
714      case OP_SCBRAPOS:      case OP_SCBRAPOS:
715      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
716      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
717      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
718      break;      break;
719    
720      case OP_COND:      case OP_COND:
# Line 697  while (cc < ccend) Line 737  while (cc < ccend)
737  }  }
738    
739  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
740  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
741  {  {
742  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
743  int length = 0;  int length = 0;
744  BOOL possessive = FALSE;  BOOL possessive = FALSE;
745  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
# Line 730  while (cc < ccend) Line 770  while (cc < ccend)
770      case OP_SCBRA:      case OP_SCBRA:
771      case OP_SCBRAPOS:      case OP_SCBRAPOS:
772      length += 3;      length += 3;
773      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
774      break;      break;
775    
776      default:      default:
# Line 748  if (length > 0) Line 788  if (length > 0)
788  return -1;  return -1;
789  }  }
790    
791  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)
792  {  {
793  DEFINE_COMPILER;  DEFINE_COMPILER;
794  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
795  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
796  int offset;  int offset;
797    
798  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
799    SLJIT_UNUSED_ARG(stacktop);
800  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
801    
802  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 793  while (cc < ccend) Line 834  while (cc < ccend)
834      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
835      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
836    
837      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
838      break;      break;
839    
840      default:      default:
# Line 806  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 847  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
847  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
848  }  }
849    
850  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)
851  {  {
852  int localsize = 2;  int localsize = 2;
853  uschar *alternative;  pcre_uchar *alternative;
854  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
855  while (cc < ccend)  while (cc < ccend)
856    {    {
# Line 832  while (cc < ccend) Line 873  while (cc < ccend)
873      case OP_CBRA:      case OP_CBRA:
874      case OP_SCBRA:      case OP_SCBRA:
875      localsize++;      localsize++;
876      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
877      break;      break;
878    
879      case OP_CBRAPOS:      case OP_CBRAPOS:
880      case OP_SCBRAPOS:      case OP_SCBRAPOS:
881      localsize += 2;      localsize += 2;
882      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
883      break;      break;
884    
885      case OP_COND:      case OP_COND:
# Line 859  SLJIT_ASSERT(cc == ccend); Line 900  SLJIT_ASSERT(cc == ccend);
900  return localsize;  return localsize;
901  }  }
902    
903  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
904    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
905  {  {
906  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 868  int count; Line 909  int count;
909  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
910  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
911  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
912  uschar *alternative;  pcre_uchar *alternative;
913  enum {  enum {
914    start,    start,
915    loop,    loop,
# Line 929  while (status != end) Line 970  while (status != end)
970        case OP_SBRAPOS:        case OP_SBRAPOS:
971        case OP_SCOND:        case OP_SCOND:
972        count = 1;        count = 1;
973        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
974        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
975        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
976        break;        break;
# Line 938  while (status != end) Line 979  while (status != end)
979        case OP_SCBRA:        case OP_SCBRA:
980        count = 1;        count = 1;
981        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
982        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
983        break;        break;
984    
985        case OP_CBRAPOS:        case OP_CBRAPOS:
986        case OP_SCBRAPOS:        case OP_SCBRAPOS:
987        count = 2;        count = 2;
988        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
989        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
990        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
991        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
992        break;        break;
993    
994        case OP_COND:        case OP_COND:
# Line 956  while (status != end) Line 997  while (status != end)
997        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
998          {          {
999          count = 1;          count = 1;
1000          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1001          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1002          }          }
1003        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1164  struct sljit_label *loop; Line 1205  struct sljit_label *loop;
1205  int i;  int i;
1206  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1207  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1208  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));
1209  if (length < 8)  if (length < 8)
1210    {    {
1211    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1188  struct sljit_label *loop; Line 1229  struct sljit_label *loop;
1229  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1230    
1231  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1232  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));
1233  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);
1234    
1235  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1236  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));
1237  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));
1238  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));
1239  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);
1240  /* Unlikely, but possible */  /* Unlikely, but possible */
1241  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1242  loop = LABEL();  loop = LABEL();
1243  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);
1244  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));
1245  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1246  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1247    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1248    #endif
1249    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1250  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);
1251  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1252  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1213  if (topbracket > 1) Line 1257  if (topbracket > 1)
1257    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));
1258    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1259    
1260    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1261    loop = LABEL();    loop = LABEL();
1262    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)));
1263    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);
1264    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);
1265    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1266    }    }
1267  else  else
1268    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1269  }  }
1270    
1271  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)
1272  {  {
1273  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1274  unsigned int c;  unsigned int c;
1275    
1276  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1277  if (common->utf8)  if (common->utf)
1278    {    {
1279    GETCHAR(c, cc);    GETCHAR(c, cc);
1280    if (c > 127)    if (c > 127)
# Line 1241  if (common->utf8) Line 1285  if (common->utf8)
1285      return FALSE;      return FALSE;
1286  #endif  #endif
1287      }      }
1288    #ifndef COMPILE_PCRE8
1289      return common->fcc[c] != c;
1290    #endif
1291    }    }
1292  else  else
1293  #endif  #endif
1294    c = *cc;    c = *cc;
1295  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1296  }  }
1297    
1298  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)
1299  {  {
1300  /* Returns with the othercase. */  /* Returns with the othercase. */
1301  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1302  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1303    {    {
1304  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1305    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1261  if (common->utf8 && c > 127) Line 1308  if (common->utf8 && c > 127)
1308  #endif  #endif
1309    }    }
1310  #endif  #endif
1311  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1312  }  }
1313    
1314  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)
1315  {  {
1316  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1317  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1318  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1319  int n;  int n;
1320  #endif  #endif
1321    
1322  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1323  if (common->utf8)  if (common->utf)
1324    {    {
1325    GETCHAR(c, cc);    GETCHAR(c, cc);
1326    if (c <= 127)    if (c <= 127)
# Line 1290  if (common->utf8) Line 1337  if (common->utf8)
1337  else  else
1338    {    {
1339    c = *cc;    c = *cc;
1340    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1341    }    }
1342  #else  #else
1343  c = *cc;  c = *cc;
1344  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1345  #endif  #endif
1346    
1347  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1308  if (c <= 127 && bit == 0x20) Line 1355  if (c <= 127 && bit == 0x20)
1355  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1356    return 0;    return 0;
1357    
1358  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1359  if (common->utf8 && c > 127)  
1360    #ifdef SUPPORT_UTF
1361    if (common->utf && c > 127)
1362    {    {
1363    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1364    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1365      {      {
1366      n--;      n--;
# Line 1319  if (common->utf8 && c > 127) Line 1368  if (common->utf8 && c > 127)
1368      }      }
1369    return (n << 8) | bit;    return (n << 8) | bit;
1370    }    }
1371  #endif  #endif /* SUPPORT_UTF */
1372  return (0 << 8) | bit;  return (0 << 8) | bit;
1373    
1374    #else /* COMPILE_PCRE8 */
1375    
1376    #ifdef COMPILE_PCRE16
1377    #ifdef SUPPORT_UTF
1378    if (common->utf && c > 65535)
1379      {
1380      if (bit >= (1 << 10))
1381        bit >>= 10;
1382      else
1383        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1384      }
1385    #endif /* SUPPORT_UTF */
1386    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1387    #endif /* COMPILE_PCRE16 */
1388    
1389    #endif /* COMPILE_PCRE8 */
1390  }  }
1391    
1392  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 1334  static void read_char(compiler_common *c Line 1400  static void read_char(compiler_common *c
1400  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1401  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1402  DEFINE_COMPILER;  DEFINE_COMPILER;
1403  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1404  struct sljit_jump *jump;  struct sljit_jump *jump;
1405  #endif  #endif
1406    
1407  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1408  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1409  if (common->utf8)  if (common->utf)
1410    {    {
1411    #ifdef COMPILE_PCRE8
1412    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1413    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1414    #ifdef COMPILE_PCRE16
1415      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1416    #endif
1417    #endif /* COMPILE_PCRE8 */
1418      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1419    JUMPHERE(jump);    JUMPHERE(jump);
1420    }    }
1421  #endif  #endif
1422  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));
1423  }  }
1424    
1425  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1355  static void peek_char(compiler_common *c Line 1427  static void peek_char(compiler_common *c
1427  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1428  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1429  DEFINE_COMPILER;  DEFINE_COMPILER;
1430  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1431  struct sljit_jump *jump;  struct sljit_jump *jump;
1432  #endif  #endif
1433    
1434  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1435  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1436  if (common->utf8)  if (common->utf)
1437    {    {
1438    #ifdef COMPILE_PCRE8
1439    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1440    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1441    #ifdef COMPILE_PCRE16
1442      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1443    #endif
1444    #endif /* COMPILE_PCRE8 */
1445      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1446    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1447    JUMPHERE(jump);    JUMPHERE(jump);
1448    }    }
# Line 1375  static void read_char8_type(compiler_com Line 1453  static void read_char8_type(compiler_com
1453  {  {
1454  /* 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. */
1455  DEFINE_COMPILER;  DEFINE_COMPILER;
1456  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1457  struct sljit_jump *jump;  struct sljit_jump *jump;
1458  #endif  #endif
1459    
1460  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1461  if (common->utf8)  if (common->utf)
1462    {    {
1463    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1464    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));
1465    #ifdef COMPILE_PCRE8
1466    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1467    it is a clever early read in most cases. */    it is needed in most cases. */
1468    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1469    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1470    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1471    JUMPHERE(jump);    JUMPHERE(jump);
1472    #else
1473    #ifdef COMPILE_PCRE16
1474      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1475      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1476      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1477      JUMPHERE(jump);
1478      /* Skip low surrogate if necessary. */
1479      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1480      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1481      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1482      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1483      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1484    #endif
1485    #endif /* COMPILE_PCRE8 */
1486    return;    return;
1487    }    }
1488  #endif  #endif
1489  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1490  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));
1491  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1492    /* The ctypes array contains only 256 values. */
1493    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1494    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1495    #endif
1496    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1497    #ifdef COMPILE_PCRE16
1498    JUMPHERE(jump);
1499    #endif
1500  }  }
1501    
1502  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1503  {  {
1504  /* 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. */
1505  DEFINE_COMPILER;  DEFINE_COMPILER;
1506  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1507  struct sljit_label *label;  struct sljit_label *label;
1508    
1509  if (common->utf8)  if (common->utf)
1510    {    {
1511    label = LABEL();    label = LABEL();
1512    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1513    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));
1514    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1515    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1516    return;    return;
1517    }    }
1518  #endif  #endif
1519  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1520    if (common->utf)
1521      {
1522      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1523      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1524      /* Skip low surrogate if necessary. */
1525      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1526      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1527      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1528      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1529      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1530      return;
1531      }
1532    #endif
1533    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1534  }  }
1535    
1536  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 1438  else if (nltype == NLTYPE_ANYCRLF) Line 1553  else if (nltype == NLTYPE_ANYCRLF)
1553    }    }
1554  else  else
1555    {    {
1556    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1557    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));
1558    }    }
1559  }  }
1560    
1561  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1562  static void do_utf8readchar(compiler_common *common)  
1563    #ifdef COMPILE_PCRE8
1564    static void do_utfreadchar(compiler_common *common)
1565  {  {
1566  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1567  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. */
1568  DEFINE_COMPILER;  DEFINE_COMPILER;
1569  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 1455  sljit_emit_fast_enter(compiler, RETURN_A Line 1572  sljit_emit_fast_enter(compiler, RETURN_A
1572  /* Searching for the first zero. */  /* Searching for the first zero. */
1573  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);
1574  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1575  /* 2 byte sequence */  /* Two byte sequence. */
1576  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1577  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));
1578  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1579  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1580  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1581  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1582  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1583  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1584  JUMPHERE(jump);  JUMPHERE(jump);
1585    
1586  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);
1587  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1588  /* 3 byte sequence */  /* Three byte sequence. */
1589  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1590  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1591  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1592  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1593  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1594  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1595  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1596  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));
1597  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1598  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1599  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1600  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1601  JUMPHERE(jump);  JUMPHERE(jump);
1602    
1603  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1604  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);  
1605  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1606  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1607  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1608  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1609  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1610  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
1611  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1612  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1613  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1614  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1615  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1616  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1617  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1618  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1619  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1620  }  }
1621    
1622  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1623  {  {
1624  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1625  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1626  DEFINE_COMPILER;  DEFINE_COMPILER;
1627  struct sljit_jump *jump;  struct sljit_jump *jump;
1628  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1539  sljit_emit_fast_enter(compiler, RETURN_A Line 1631  sljit_emit_fast_enter(compiler, RETURN_A
1631    
1632  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);
1633  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1634  /* 2 byte sequence */  /* Two byte sequence. */
1635  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1636  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));
1637  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1638  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1639  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1556  sljit_emit_fast_return(compiler, RETURN_ Line 1648  sljit_emit_fast_return(compiler, RETURN_
1648  JUMPHERE(jump);  JUMPHERE(jump);
1649    
1650  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1651  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);
1652  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1653  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1654  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1655  }  }
1656    
1657  #endif  #else /* COMPILE_PCRE8 */
1658    
1659    #ifdef COMPILE_PCRE16
1660    static void do_utfreadchar(compiler_common *common)
1661    {
1662    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1663    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1664    DEFINE_COMPILER;
1665    struct sljit_jump *jump;
1666    
1667    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1668    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1669    /* Do nothing, only return. */
1670    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1671    
1672    JUMPHERE(jump);
1673    /* Combine two 16 bit characters. */
1674    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1675    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1676    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1677    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1678    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1679    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1680    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1681    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1682    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1683    }
1684    #endif /* COMPILE_PCRE16 */
1685    
1686    #endif /* COMPILE_PCRE8 */
1687    
1688    #endif /* SUPPORT_UTF */
1689    
1690  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1691    
# Line 1580  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1703  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1703    
1704  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);
1705  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1706  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));
1707  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1708  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1709  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1710  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1711  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1712  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));
1713  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1714  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1715  }  }
# Line 1600  struct sljit_label *newlinelabel = NULL; Line 1723  struct sljit_label *newlinelabel = NULL;
1723  struct sljit_jump *start;  struct sljit_jump *start;
1724  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1725  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1726  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1727  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
1728  #endif  #endif
1729  jump_list *newline = NULL;  jump_list *newline = NULL;
1730  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1731  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1732    
1733  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1734      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1620  if (firstline) Line 1743  if (firstline)
1743    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1744      {      {
1745      mainloop = LABEL();      mainloop = LABEL();
1746      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));
1747      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1748      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1749      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1750      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);
1751      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);
1752      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));
1753      }      }
1754    else    else
1755      {      {
# Line 1650  start = JUMP(SLJIT_JUMP); Line 1773  start = JUMP(SLJIT_JUMP);
1773  if (newlinecheck)  if (newlinecheck)
1774    {    {
1775    newlinelabel = LABEL();    newlinelabel = LABEL();
1776    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));
1777    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1778    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1779    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);
1780    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1781    #ifdef COMPILE_PCRE16
1782      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1783    #endif
1784    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1785    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1786    }    }
# Line 1662  if (newlinecheck) Line 1788  if (newlinecheck)
1788  mainloop = LABEL();  mainloop = LABEL();
1789    
1790  /* 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. */
1791  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1792  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1793  #endif  #endif
1794  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1795    
1796  if (readbyte)  if (readuchar)
1797    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1798    
1799  if (newlinecheck)  if (newlinecheck)
1800    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);
1801    
1802  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));
1803  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1804  if (common->utf8)  if (common->utf)
1805    {    {
1806    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1807    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);
1808    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1809    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
1810      }
1811    #endif
1812    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1813    if (common->utf)
1814      {
1815      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1816      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1817      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1818      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1819      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1820      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1821      JUMPHERE(singlechar);
1822    }    }
1823  #endif  #endif
1824  JUMPHERE(start);  JUMPHERE(start);
# Line 1694  if (newlinecheck) Line 1832  if (newlinecheck)
1832  return mainloop;  return mainloop;
1833  }  }
1834    
1835  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)
1836  {  {
1837  DEFINE_COMPILER;  DEFINE_COMPILER;
1838  struct sljit_label *start;  struct sljit_label *start;
1839  struct sljit_jump *leave;  struct sljit_jump *leave;
1840  struct sljit_jump *found;  struct sljit_jump *found;
1841  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1842    
1843  if (firstline)  if (firstline)
1844    {    {
# Line 1710  if (firstline) Line 1848  if (firstline)
1848    
1849  start = LABEL();  start = LABEL();
1850  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1851  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1852    
1853  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1854    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
1855      {
1856      oc = TABLE_GET(first_char, common->fcc, first_char);
1857    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1858      if (first_char > 127 && common->utf)
1859        oc = UCD_OTHERCASE(first_char);
1860    #endif
1861      }
1862    if (first_char == oc)
1863      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
1864  else  else
1865    {    {
1866    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
1867    if (ispowerof2(bit))    if (ispowerof2(bit))
1868      {      {
1869      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
1870      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
1871      }      }
1872    else    else
1873      {      {
1874      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);
1875      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1876      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);
1877      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 1734  else Line 1879  else
1879      }      }
1880    }    }
1881    
1882  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));
1883  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1884  if (common->utf8)  if (common->utf)
1885    {    {
1886    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
1887    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);
1888      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1889      }
1890    #endif
1891    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1892    if (common->utf)
1893      {
1894      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
1895      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1896      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1897      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1898      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1899    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1900    }    }
1901  #endif  #endif
# Line 1776  if (common->nltype == NLTYPE_FIXED && co Line 1932  if (common->nltype == NLTYPE_FIXED && co
1932    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));
1933    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1934    
1935    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
1936    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);
1937    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
1938    #ifdef COMPILE_PCRE16
1939      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1940    #endif
1941    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1942    
1943    loop = LABEL();    loop = LABEL();
1944    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));
1945    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1946    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
1947    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1948    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);
1949    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);
1950    
# Line 1816  if (common->nltype == NLTYPE_ANY || comm Line 1975  if (common->nltype == NLTYPE_ANY || comm
1975    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
1976    JUMPHERE(foundcr);    JUMPHERE(foundcr);
1977    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1978    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1979    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);
1980    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1981    #ifdef COMPILE_PCRE16
1982      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1983    #endif
1984    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1985    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
1986    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1836  DEFINE_COMPILER; Line 1998  DEFINE_COMPILER;
1998  struct sljit_label *start;  struct sljit_label *start;
1999  struct sljit_jump *leave;  struct sljit_jump *leave;
2000  struct sljit_jump *found;  struct sljit_jump *found;
2001    #ifndef COMPILE_PCRE8
2002    struct sljit_jump *jump;
2003    #endif
2004    
2005  if (firstline)  if (firstline)
2006    {    {
# Line 1845  if (firstline) Line 2010  if (firstline)
2010    
2011  start = LABEL();  start = LABEL();
2012  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2013  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2014  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2015  if (common->utf8)  if (common->utf)
2016    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2017  #endif  #endif
2018    #ifndef COMPILE_PCRE8
2019    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2020    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2021    JUMPHERE(jump);
2022    #endif
2023  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2024  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2025  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1857  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2027  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2027  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);
2028  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2029    
2030  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2031  if (common->utf8)  if (common->utf)
2032    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2033  #endif  #endif
2034  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));
2035  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2036  if (common->utf8)  if (common->utf)
2037    {    {
2038    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2039    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);
2040      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2041      }
2042    #endif
2043    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2044    if (common->utf)
2045      {
2046      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2047      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2048      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2049      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2050      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2051    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2052    }    }
2053  #endif  #endif
# Line 1878  if (firstline) Line 2059  if (firstline)
2059    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2060  }  }
2061    
2062  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)
2063  {  {
2064  DEFINE_COMPILER;  DEFINE_COMPILER;
2065  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1887  struct sljit_jump *alreadyfound; Line 2068  struct sljit_jump *alreadyfound;
2068  struct sljit_jump *found;  struct sljit_jump *found;
2069  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2070  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2071  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2072    
2073  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);
2074  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);
2075  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2076  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2077    
2078  if (has_firstbyte)  if (has_firstchar)
2079    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2080  else  else
2081    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2082    
2083  loop = LABEL();  loop = LABEL();
2084  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2085    
2086  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2087  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2088    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2089      {
2090      oc = TABLE_GET(req_char, common->fcc, req_char);
2091    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2092      if (req_char > 127 && common->utf)
2093        oc = UCD_OTHERCASE(req_char);
2094    #endif
2095      }
2096    if (req_char == oc)
2097      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2098  else  else
2099    {    {
2100    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2101    if (ispowerof2(bit))    if (ispowerof2(bit))
2102      {      {
2103      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2104      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2105      }      }
2106    else    else
2107      {      {
2108      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2109      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2110      }      }
2111    }    }
2112  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2113  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2114    
2115  JUMPHERE(found);  JUMPHERE(found);
2116  if (foundoc)  if (foundoc)
2117    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2118  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);
2119  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2120  JUMPHERE(toolong);  JUMPHERE(toolong);
2121  return notfound;  return notfound;
# Line 1975  static void check_wordboundary(compiler_ Line 2163  static void check_wordboundary(compiler_
2163  {  {
2164  DEFINE_COMPILER;  DEFINE_COMPILER;
2165  struct sljit_jump *beginend;  struct sljit_jump *beginend;
2166  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2167  struct sljit_jump *jump;  struct sljit_jump *jump;
2168  #endif  #endif
2169    
2170  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2171    
2172  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
2173  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 1992  read_char(common); Line 2180  read_char(common);
2180    
2181  /* Testing char type. */  /* Testing char type. */
2182  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2183  if (common->useucp)  if (common->use_ucp)
2184    {    {
2185    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2186    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2009  if (common->useucp) Line 2197  if (common->useucp)
2197  else  else
2198  #endif  #endif
2199    {    {
2200  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2201      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2202    #elif defined SUPPORT_UTF
2203    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2204    jump = NULL;    jump = NULL;
2205    if (common->utf8)    if (common->utf)
2206      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2207  #endif  #endif /* COMPILE_PCRE8 */
2208    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2209    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2210    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2211    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2212  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2213      JUMPHERE(jump);
2214    #elif defined SUPPORT_UTF
2215    if (jump != NULL)    if (jump != NULL)
2216      JUMPHERE(jump);      JUMPHERE(jump);
2217  #endif  #endif /* COMPILE_PCRE8 */
2218    }    }
2219  JUMPHERE(beginend);  JUMPHERE(beginend);
2220    
# Line 2032  peek_char(common); Line 2224  peek_char(common);
2224    
2225  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2226  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2227  if (common->useucp)  if (common->use_ucp)
2228    {    {
2229    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2230    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2048  if (common->useucp) Line 2240  if (common->useucp)
2240  else  else
2241  #endif  #endif
2242    {    {
2243  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2244      /* TMP2 may be destroyed by peek_char. */
2245      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2246      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2247    #elif defined SUPPORT_UTF
2248    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2249    jump = NULL;    jump = NULL;
2250    if (common->utf8)    if (common->utf)
2251      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2252  #endif  #endif
2253    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2254    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2255    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2256  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2257      JUMPHERE(jump);
2258    #elif defined SUPPORT_UTF
2259    if (jump != NULL)    if (jump != NULL)
2260      JUMPHERE(jump);      JUMPHERE(jump);
2261  #endif  #endif /* COMPILE_PCRE8 */
2262    }    }
2263  JUMPHERE(beginend);  JUMPHERE(beginend);
2264    
# Line 2079  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2277  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2277  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);
2278  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2279  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);
2280  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2281  if (common->utf8)  #ifdef COMPILE_PCRE8
2282    if (common->utf)
2283    {    {
2284    #endif
2285    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2286    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2287    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);
2288    #ifdef COMPILE_PCRE8
2289    }    }
2290  #endif  #endif
2291    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2292  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2293  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2294  }  }
# Line 2103  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2305  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2305  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);
2306  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2307  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);
2308  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2309  if (common->utf8)  #ifdef COMPILE_PCRE8
2310    if (common->utf)
2311    {    {
2312    #endif
2313    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2314    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);
2315    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2119  if (common->utf8) Line 2323  if (common->utf8)
2323    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);
2324    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2325    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);
2326    #ifdef COMPILE_PCRE8
2327    }    }
2328  #endif  #endif
2329    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2330  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2331    
2332  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2137  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2343  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2343  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);
2344  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2345  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);
2346  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2347  if (common->utf8)  #ifdef COMPILE_PCRE8
2348    if (common->utf)
2349    {    {
2350    #endif
2351    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2352    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2353    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);
2354    #ifdef COMPILE_PCRE8
2355    }    }
2356  #endif  #endif
2357    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2358  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2359    
2360  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2163  sljit_emit_fast_enter(compiler, RETURN_A Line 2373  sljit_emit_fast_enter(compiler, RETURN_A
2373  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2374  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2375  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2376  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2377  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));
2378    
2379  label = LABEL();  label = LABEL();
2380  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2381  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2382  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2383  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));
2384  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2385    
2386  JUMPHERE(jump);  JUMPHERE(jump);
2387  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));
2388  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2389  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2390  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2195  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2405  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2405  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2406  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2407  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2408  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2409  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));
2410    
2411  label = LABEL();  label = LABEL();
2412  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2413  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2414    #ifndef COMPILE_PCRE8
2415    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2416    #endif
2417  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2418    #ifndef COMPILE_PCRE8
2419    JUMPHERE(jump);
2420    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2421    #endif
2422  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2423    #ifndef COMPILE_PCRE8
2424    JUMPHERE(jump);
2425    #endif
2426  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2427  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));
2428  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2429    
2430  JUMPHERE(jump);  JUMPHERE(jump);
2431  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));
2432  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2433  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2434  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2219  sljit_emit_fast_return(compiler, RETURN_ Line 2439  sljit_emit_fast_return(compiler, RETURN_
2439  #undef CHAR1  #undef CHAR1
2440  #undef CHAR2  #undef CHAR2
2441    
2442  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2443    
2444  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)
2445  {  {
2446  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2447  int c1, c2;  int c1, c2;
2448  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2449  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2450    
2451  while (src1 < end1)  while (src1 < end1)
2452    {    {
# Line 2240  while (src1 < end1) Line 2459  while (src1 < end1)
2459  return src2;  return src2;
2460  }  }
2461    
2462  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2463    
2464  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,
2465      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2466  {  {
2467  DEFINE_COMPILER;  DEFINE_COMPILER;
2468  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2469  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2470  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2471  int utf8length;  int utflength;
2472  #endif  #endif
2473    
2474  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2258  if (caseless && char_has_othercase(commo Line 2476  if (caseless && char_has_othercase(commo
2476    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2477    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2478    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2479    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2480      othercasechar = cc + (othercasebit >> 8);
2481    othercasebit &= 0xff;    othercasebit &= 0xff;
2482    #else
2483    #ifdef COMPILE_PCRE16
2484      othercasechar = cc + (othercasebit >> 9);
2485      if ((othercasebit & 0x100) != 0)
2486        othercasebit = (othercasebit & 0xff) << 8;
2487      else
2488        othercasebit &= 0xff;
2489    #endif
2490    #endif
2491    }    }
2492    
2493  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2494    {    {
2495    #ifdef COMPILE_PCRE8
2496  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2497    if (context->length >= 4)    if (context->length >= 4)
2498      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2499    else if (context->length >= 2)    else if (context->length >= 2)
2500      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2501    else    else
2502  #endif  #endif
2503      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2504    #else
2505    #ifdef COMPILE_PCRE16
2506    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2507      if (context->length >= 4)
2508        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2509      else
2510    #endif
2511        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2512    #endif
2513    #endif /* COMPILE_PCRE8 */
2514    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2515    }    }
2516    
2517  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2518  utf8length = 1;  utflength = 1;
2519  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2520    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2521    
2522  do  do
2523    {    {
2524  #endif  #endif
2525    
2526    context->length--;    context->length -= IN_UCHARS(1);
2527  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2528    
2529    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2530    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2531      {      {
2532      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2533      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2534      }      }
2535    else    else
2536      {      {
2537      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2538      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2539      }      }
2540    context->byteptr++;    context->ucharptr++;
2541    
2542    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2543      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2544    #else
2545      if (context->ucharptr >= 2 || context->length == 0)
2546    #endif
2547      {      {
2548      if (context->length >= 4)      if (context->length >= 4)
2549        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);
2550    #ifdef COMPILE_PCRE8
2551      else if (context->length >= 2)      else if (context->length >= 2)
2552        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);
2553      else if (context->length >= 1)      else if (context->length >= 1)
2554        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);
2555    #else
2556        else if (context->length >= 2)
2557          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2558    #endif
2559      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2560    
2561      switch(context->byteptr)      switch(context->ucharptr)
2562        {        {
2563        case 4:        case 4 / sizeof(pcre_uchar):
2564        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2565          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);
2566        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));
2567        break;        break;
2568    
2569        case 2:        case 2 / sizeof(pcre_uchar):
2570        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2571          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);
2572        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));
2573        break;        break;
2574    
2575    #ifdef COMPILE_PCRE8
2576        case 1:        case 1:
2577        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2578          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);
2579        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));
2580        break;        break;
2581    #endif
2582    
2583        default:        default:
2584        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2585        break;        break;
2586        }        }
2587      context->byteptr = 0;      context->ucharptr = 0;
2588      }      }
2589    
2590  #else  #else
2591    
2592    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2593    #ifdef COMPILE_PCRE8
2594    if (context->length > 0)    if (context->length > 0)
2595      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);
2596    #else
2597      if (context->length > 0)
2598        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2599    #endif
2600    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2601    
2602    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2603      {      {
2604      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2605      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 2355  do Line 2610  do
2610  #endif  #endif
2611    
2612    cc++;    cc++;
2613  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2614    utf8length--;    utflength--;
2615    }    }
2616  while (utf8length > 0);  while (utflength > 0);
2617  #endif  #endif
2618    
2619  return cc;  return cc;
2620  }  }
2621    
2622  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2623    
2624  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2625    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2386  return cc; Line 2641  return cc;
2641      } \      } \
2642    charoffset = (value);    charoffset = (value);
2643    
2644  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)
2645  {  {
2646  DEFINE_COMPILER;  DEFINE_COMPILER;
2647  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2394  jump_list **list = (*cc & XCL_NOT) == 0 Line 2649  jump_list **list = (*cc & XCL_NOT) == 0
2649  unsigned int c;  unsigned int c;
2650  int compares;  int compares;
2651  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2652  uschar *ccbegin;  pcre_uchar *ccbegin;
2653  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2654  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2655  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2404  unsigned int typeoffset; Line 2659  unsigned int typeoffset;
2659  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2660  unsigned int charoffset;  unsigned int charoffset;
2661    
2662  /* 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. */
2663  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
2664  read_char(common);  read_char(common);
2665    
2666  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2667    {    {
2668    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2669    if (common->utf8)  #ifndef COMPILE_PCRE8
2670      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2671    #elif defined SUPPORT_UTF
2672      if (common->utf)
2673      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2674    #endif
2675    
2676    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2677    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2421  if ((*cc++ & XCL_MAP) != 0) Line 2680  if ((*cc++ & XCL_MAP) != 0)
2680    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);
2681    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2682    
2683    if (common->utf8)  #ifndef COMPILE_PCRE8
2684      JUMPHERE(jump);
2685    #elif defined SUPPORT_UTF
2686      if (common->utf)
2687      JUMPHERE(jump);      JUMPHERE(jump);
2688    #endif
2689    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2690  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2691    charsaved = TRUE;    charsaved = TRUE;
2692  #endif  #endif
2693    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2694    }    }
2695    
2696  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2439  while (*cc != XCL_END) Line 2702  while (*cc != XCL_END)
2702    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2703      {      {
2704      cc += 2;      cc += 2;
2705  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2706      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]);
2707  #endif  #endif
2708  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2709      needschar = TRUE;      needschar = TRUE;
# Line 2449  while (*cc != XCL_END) Line 2712  while (*cc != XCL_END)
2712    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2713      {      {
2714      cc += 2;      cc += 2;
2715  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2716      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]);
2717  #endif  #endif
2718      cc++;      cc++;
2719  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2720      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]);
2721  #endif  #endif
2722  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2723      needschar = TRUE;      needschar = TRUE;
# Line 2524  if (needstype || needsscript) Line 2787  if (needstype || needsscript)
2787      {      {
2788      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2789        {        {
2790        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));
2791        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2792        }        }
2793      else      else
2794        {        {
2795        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2796        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));
2797        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2798        }        }
2799      }      }
# Line 2554  while (*cc != XCL_END) Line 2817  while (*cc != XCL_END)
2817    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2818      {      {
2819      cc ++;      cc ++;
2820  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2821      if (common->utf8)      if (common->utf)
2822        {        {
2823        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2824        }        }
# Line 2585  while (*cc != XCL_END) Line 2848  while (*cc != XCL_END)
2848    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2849      {      {
2850      cc ++;      cc ++;
2851  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2852      if (common->utf8)      if (common->utf)
2853        {        {
2854        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2855        }        }
# Line 2594  while (*cc != XCL_END) Line 2857  while (*cc != XCL_END)
2857  #endif  #endif
2858        c = *cc++;        c = *cc++;
2859      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
2860  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2861      if (common->utf8)      if (common->utf)
2862        {        {
2863        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2864        }        }
# Line 2651  while (*cc != XCL_END) Line 2914  while (*cc != XCL_END)
2914        break;        break;
2915    
2916        case PT_GC:        case PT_GC:
2917        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
2918        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
2919        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);
2920        break;        break;
2921    
2922        case PT_PC:        case PT_PC:
# Line 2715  if (found != NULL) Line 2978  if (found != NULL)
2978    
2979  #endif  #endif
2980    
2981  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)
2982  {  {
2983  DEFINE_COMPILER;  DEFINE_COMPILER;
2984  int length;  int length;
2985  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2986  compare_context context;  compare_context context;
2987  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
2988  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2989  struct sljit_label *label;  struct sljit_label *label;
2990  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2991  uschar propdata[5];  pcre_uchar propdata[5];
2992  #endif  #endif
2993  #endif  #endif
2994    
# Line 2780  switch(type) Line 3043  switch(type)
3043      {      {
3044      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);
3045      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);
3046      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3047      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));
3048      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3049      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 2791  switch(type) Line 3054  switch(type)
3054    
3055    case OP_ALLANY:    case OP_ALLANY:
3056    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3057  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3058    if (common->utf8)    if (common->utf)
3059      {      {
3060      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3061      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));
3062    #ifdef COMPILE_PCRE8
3063      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3064      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);
3065        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3066    #else /* COMPILE_PCRE8 */
3067    #ifdef COMPILE_PCRE16
3068        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3069        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3070        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3071        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3072        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3073      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3074    #endif /* COMPILE_PCRE16 */
3075    #endif /* COMPILE_PCRE8 */
3076      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3077      return cc;      return cc;
3078      }      }
3079  #endif  #endif
3080    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));
3081    return cc;    return cc;
3082    
3083    case OP_ANYBYTE:    case OP_ANYBYTE:
3084    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3085    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));
3086    return cc;    return cc;
3087    
3088  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3089  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3090    case OP_NOTPROP:    case OP_NOTPROP:
3091    case OP_PROP:    case OP_PROP:
# Line 2830  switch(type) Line 3104  switch(type)
3104    read_char(common);    read_char(common);
3105    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);
3106    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);
3107    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3108    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);
3109    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));
3110    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3111    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3112    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2882  switch(type) Line 3156  switch(type)
3156    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);
3157    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3158      {      {
3159      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3160      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3161      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));
3162      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3163      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));
3164      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));
3165      }      }
3166    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3167      {      {
3168      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3169      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3170      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));
3171      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));
3172      }      }
3173    else    else
3174      {      {
3175      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3176      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);
3177      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3178      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);
3179      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3180      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3181      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3182        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3183      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3184      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3185    
3186      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3187      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3188        {        {
3189        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3190        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));
3191        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));
3192        }        }
# Line 2951  switch(type) Line 3226  switch(type)
3226    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3227    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3228    
3229    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));  
   
3230    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3231      {      {
3232      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3233      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3234      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3235      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3236      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));
3237      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));
3238      }      }
# Line 2993  switch(type) Line 3266  switch(type)
3266    
3267    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3268      {      {
3269      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3270      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));
3271      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3272      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3273      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));
3274      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));
3275      }      }
# Line 3011  switch(type) Line 3284  switch(type)
3284    case OP_CHAR:    case OP_CHAR:
3285    case OP_CHARI:    case OP_CHARI:
3286    length = 1;    length = 1;
3287  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3288    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3289  #endif  #endif
3290    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)
3291      {      {
3292      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));
3293      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));
3294    
3295      context.length = length;      context.length = IN_UCHARS(length);
3296      context.sourcereg = -1;      context.sourcereg = -1;
3297  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3298      context.byteptr = 0;      context.ucharptr = 0;
3299  #endif  #endif
3300      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3301      }      }
3302    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    check_input_end(common, fallbacks);
3303    read_char(common);    read_char(common);
3304  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3305    if (common->utf8)    if (common->utf)
3306      {      {
3307      GETCHAR(c, cc);      GETCHAR(c, cc);
3308      }      }
# Line 3045  switch(type) Line 3318  switch(type)
3318    
3319    case OP_NOT:    case OP_NOT:
3320    case OP_NOTI:    case OP_NOTI:
3321      check_input_end(common, fallbacks);
3322    length = 1;    length = 1;
3323  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3324    if (common->utf8)    if (common->utf)
3325      {      {
3326      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3327        c = *cc;
3328      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3329        {        {
3330        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3331        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
# Line 3066  switch(type) Line 3337  switch(type)
3337          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));
3338          }          }
3339        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3340        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));
3341        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3342        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);
3343        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3344        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
3345        return cc + length;        return cc + 1;
3346        }        }
3347      else      else
3348    #endif /* COMPILE_PCRE8 */
3349          {
3350          GETCHARLEN(c, cc, length);
3351        read_char(common);        read_char(common);
3352          }
3353      }      }
3354    else    else
3355  #endif  #endif /* SUPPORT_UTF */
3356      {      {
3357      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);  
3358      c = *cc;      c = *cc;
3359      }      }
3360    
# Line 3102  switch(type) Line 3375  switch(type)
3375        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));
3376        }        }
3377      }      }
3378    return cc + length;    return cc + 1;
3379    
3380    case OP_CLASS:    case OP_CLASS:
3381    case OP_NCLASS:    case OP_NCLASS:
3382    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3383    read_char(common);    read_char(common);
3384  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3385    jump[0] = NULL;    jump[0] = NULL;
3386    if (common->utf8)  #ifdef COMPILE_PCRE8
3387      /* This check only affects 8 bit mode. In other modes, we
3388      always need to compare the value with 255. */
3389      if (common->utf)
3390    #endif /* COMPILE_PCRE8 */
3391      {      {
3392      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3393      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3119  switch(type) Line 3396  switch(type)
3396        jump[0] = NULL;        jump[0] = NULL;
3397        }        }
3398      }      }
3399  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3400    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3401    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3402    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3403    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3404    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);
3405    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3406  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3407    if (jump[0] != NULL)    if (jump[0] != NULL)
3408      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3409  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3410    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3411    
3412  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3413    case OP_XCLASS:    case OP_XCLASS:
3414    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3415    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3142  switch(type) Line 3419  switch(type)
3419    length = GET(cc, 0);    length = GET(cc, 0);
3420    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3421    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3422    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3423  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3424      {      {
3425        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3426      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3427      label = LABEL();      label = LABEL();
3428      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));
3429      skip_char_back(common);      skip_char_back(common);
3430      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);
3431      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
3432      return cc + LINK_SIZE;      return cc + LINK_SIZE;
3433      }      }
3434  #endif  #endif
3435    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));
3436      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3437    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));
3438    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3439    }    }
# Line 3163  SLJIT_ASSERT_STOP(); Line 3441  SLJIT_ASSERT_STOP();
3441  return cc;  return cc;
3442  }  }
3443    
3444  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)
3445  {  {
3446  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3447  /* 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. */
3448  DEFINE_COMPILER;  DEFINE_COMPILER;
3449  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3450  compare_context context;  compare_context context;
3451  int size;  int size;
3452    
# Line 3181  do Line 3459  do
3459    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3460      {      {
3461      size = 1;      size = 1;
3462  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3463      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3464        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3465  #endif  #endif
3466      }      }
3467    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3468      {      {
3469      size = 1;      size = 1;
3470  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3471      if (common->utf8)      if (common->utf)
3472        {        {
3473        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)
3474          size = 0;          size = 0;
3475        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3476          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3477        }        }
3478      else      else
3479  #endif  #endif
# Line 3206  do Line 3484  do
3484      size = 0;      size = 0;
3485    
3486    cc += 1 + size;    cc += 1 + size;
3487    context.length += size;    context.length += IN_UCHARS(size);
3488    }    }
3489  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3490    
# Line 3219  if (context.length > 0) Line 3497  if (context.length > 0)
3497    
3498    context.sourcereg = -1;    context.sourcereg = -1;
3499  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3500    context.byteptr = 0;    context.ucharptr = 0;
3501  #endif  #endif
3502    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);
3503    return cc;    return cc;
# Line 3229  if (context.length > 0) Line 3507  if (context.length > 0)
3507  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3508  }  }
3509    
3510  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)
3511  {  {
3512  DEFINE_COMPILER;  DEFINE_COMPILER;
3513  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3251  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3529  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3529  }  }
3530    
3531  /* Forward definitions. */  /* Forward definitions. */
3532  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3533  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3534    
3535  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3282  static void compile_fallbackpath(compile Line 3560  static void compile_fallbackpath(compile
3560    
3561  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type*)fallback)
3562    
3563  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)
3564  {  {
3565  DEFINE_COMPILER;  DEFINE_COMPILER;
3566  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3292  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT Line 3570  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT
3570  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3571    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)));
3572    
3573  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3574  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3575    {    {
3576    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);
3577    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 3305  if (common->utf8 && *cc == OP_REFI) Line 3582  if (common->utf8 && *cc == OP_REFI)
3582    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3583    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3584    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);
3585    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));
3586    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3587    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));
3588    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3589    }    }
3590  else  else
3591  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3592    {    {
3593    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);
3594    if (withchecks)    if (withchecks)
# Line 3331  if (jump != NULL) Line 3607  if (jump != NULL)
3607    else    else
3608      JUMPHERE(jump);      JUMPHERE(jump);
3609    }    }
3610  return cc + 3;  return cc + 1 + IMM2_SIZE;
3611  }  }
3612    
3613  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)
3614  {  {
3615  DEFINE_COMPILER;  DEFINE_COMPILER;
3616  fallback_common *fallback;  fallback_common *fallback;
3617  uschar type;  pcre_uchar type;
3618  struct sljit_label *label;  struct sljit_label *label;
3619  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3620  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3621  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3622  int min = 0, max = 0;  int min = 0, max = 0;
3623  BOOL minimize;  BOOL minimize;
3624    
3625  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3626    
3627  type = cc[3];  type = cc[1 + IMM2_SIZE];
3628  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3629  switch(type)  switch(type)
3630    {    {
# Line 3356  switch(type) Line 3632  switch(type)
3632    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3633    min = 0;    min = 0;
3634    max = 0;    max = 0;
3635    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3636    break;    break;
3637    case OP_CRPLUS:    case OP_CRPLUS:
3638    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3639    min = 1;    min = 1;
3640    max = 0;    max = 0;
3641    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3642    break;    break;
3643    case OP_CRQUERY:    case OP_CRQUERY:
3644    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3645    min = 0;    min = 0;
3646    max = 1;    max = 1;
3647    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3648    break;    break;
3649    case OP_CRRANGE:    case OP_CRRANGE:
3650    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3651    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3652    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3653    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3654    break;    break;
3655    default:    default:
3656    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3478  decrease_call_count(common); Line 3754  decrease_call_count(common);
3754  return cc;  return cc;
3755  }  }
3756    
3757  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)
3758  {  {
3759  DEFINE_COMPILER;  DEFINE_COMPILER;
3760  fallback_common *fallback;  fallback_common *fallback;
# Line 3524  add_jump(compiler, &fallback->topfallbac Line 3800  add_jump(compiler, &fallback->topfallbac
3800  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3801  }  }
3802    
3803  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)
3804  {  {
3805  DEFINE_COMPILER;  DEFINE_COMPILER;
3806  int framesize;  int framesize;
3807  int localptr;  int localptr;
3808  fallback_common altfallback;  fallback_common altfallback;
3809  uschar *ccbegin;  pcre_uchar *ccbegin;
3810  uschar opcode;  pcre_uchar opcode;
3811  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
3812  jump_list *tmp = NULL;  jump_list *tmp = NULL;
3813  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
3814  jump_list **found;  jump_list **found;
# Line 3548  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3824  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3824    bra = *cc;    bra = *cc;
3825    cc++;    cc++;
3826    }    }
3827  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
3828  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
3829  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
3830  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3794  common->accept = save_accept; Line 4070  common->accept = save_accept;
4070  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4071  }  }
4072    
4073    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4074    {
4075    int condition = FALSE;
4076    pcre_uchar *slotA = name_table;
4077    pcre_uchar *slotB;
4078    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4079    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4080    sljit_w no_capture;
4081    int i;
4082    
4083    locals += OVECTOR_START / sizeof(sljit_w);
4084    no_capture = locals[1];
4085    
4086    for (i = 0; i < name_count; i++)
4087      {
4088      if (GET2(slotA, 0) == refno) break;
4089      slotA += name_entry_size;
4090      }
4091    
4092    if (i < name_count)
4093      {
4094      /* Found a name for the number - there can be only one; duplicate names
4095      for different numbers are allowed, but not vice versa. First scan down
4096      for duplicates. */
4097    
4098      slotB = slotA;
4099      while (slotB > name_table)
4100        {
4101        slotB -= name_entry_size;
4102        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4103          {
4104          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4105          if (condition) break;
4106          }
4107        else break;
4108        }
4109    
4110      /* Scan up for duplicates */
4111      if (!condition)
4112        {
4113        slotB = slotA;
4114        for (i++; i < name_count; i++)
4115          {
4116          slotB += name_entry_size;
4117          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4118            {
4119            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4120            if (condition) break;
4121            }
4122          else break;
4123          }
4124        }
4125      }
4126    return condition;
4127    }
4128    
4129    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4130    {
4131    int condition = FALSE;
4132    pcre_uchar *slotA = name_table;
4133    pcre_uchar *slotB;
4134    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4135    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4136    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4137    int i;
4138    
4139    for (i = 0; i < name_count; i++)
4140      {
4141      if (GET2(slotA, 0) == recno) break;
4142      slotA += name_entry_size;
4143      }
4144    
4145    if (i < name_count)
4146      {
4147      /* Found a name for the number - there can be only one; duplicate
4148      names for different numbers are allowed, but not vice versa. First
4149      scan down for duplicates. */
4150    
4151      slotB = slotA;
4152      while (slotB > name_table)
4153        {
4154        slotB -= name_entry_size;
4155        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4156          {
4157          condition = GET2(slotB, 0) == group_num;
4158          if (condition) break;
4159          }
4160        else break;
4161        }
4162    
4163      /* Scan up for duplicates */
4164      if (!condition)
4165        {
4166        slotB = slotA;
4167        for (i++; i < name_count; i++)
4168          {
4169          slotB += name_entry_size;
4170          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4171            {
4172            condition = GET2(slotB, 0) == group_num;
4173            if (condition) break;
4174            }
4175          else break;
4176          }
4177        }
4178      }
4179    return condition;
4180    }
4181    
4182  /*  /*
4183    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4184    
# Line 3848  return cc + 1 + LINK_SIZE; Line 4233  return cc + 1 + LINK_SIZE;
4233                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
4234  */  */
4235    
4236  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)
4237  {  {
4238  DEFINE_COMPILER;  DEFINE_COMPILER;
4239  fallback_common *fallback;  fallback_common *fallback;
4240  uschar opcode;  pcre_uchar opcode;
4241  int localptr = 0;  int localptr = 0;
4242  int offset = 0;  int offset = 0;
4243  int stacksize;  int stacksize;
4244  uschar *ccbegin;  pcre_uchar *ccbegin;
4245  uschar *hotpath;  pcre_uchar *hotpath;
4246  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4247  uschar ket;  pcre_uchar ket;
4248  assert_fallback *assert;  assert_fallback *assert;
4249  BOOL has_alternatives;  BOOL has_alternatives;
4250  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3878  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4263  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4263    
4264  opcode = *cc;  opcode = *cc;
4265  ccbegin = cc;  ccbegin = cc;
4266    hotpath = ccbegin + 1 + LINK_SIZE;
4267    
4268  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
4269    {    {
4270    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3889  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4276  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4276  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4277  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
4278  cc += GET(cc, 1);  cc += GET(cc, 1);
4279  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4280    has_alternatives = *cc == OP_ALT;
4281    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4282      {
4283      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4284      if (*hotpath == OP_NRREF)
4285        {
4286        stacksize = GET2(hotpath, 1);
4287        if (common->currententry == NULL || stacksize == RREF_ANY)
4288          has_alternatives = FALSE;
4289        else if (common->currententry->start == 0)
4290          has_alternatives = stacksize != 0;
4291        else
4292          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4293        }
4294      }
4295    
4296  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4297    opcode = OP_SCOND;    opcode = OP_SCOND;
4298  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))  if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
# Line 3902  if (opcode == OP_CBRA || opcode == OP_SC Line 4305  if (opcode == OP_CBRA || opcode == OP_SC
4305    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4306    offset <<= 1;    offset <<= 1;
4307    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4308      hotpath += IMM2_SIZE;
4309    }    }
4310  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4311    {    {
4312    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4313    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4314    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4315    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4316    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4058  else if (has_alternatives) Line 4462  else if (has_alternatives)
4462    }    }
4463    
4464  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4465  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4466    {    {
4467    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4468      {      {
4469        SLJIT_ASSERT(has_alternatives);
4470      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4471        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)));
4472      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4473        }
4474      else if (*hotpath == OP_NCREF)
4475        {
4476        SLJIT_ASSERT(has_alternatives);
4477        stacksize = GET2(hotpath, 1);
4478        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4479    
4480        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4481        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4482        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4483        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4484        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4485        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4486        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4487        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4488        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4489    
4490        JUMPHERE(jump);
4491        hotpath += 1 + IMM2_SIZE;
4492        }
4493      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4494        {
4495        /* Never has other case. */
4496        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4497    
4498        stacksize = GET2(hotpath, 1);
4499        if (common->currententry == NULL)
4500          stacksize = 0;
4501        else if (stacksize == RREF_ANY)
4502          stacksize = 1;
4503        else if (common->currententry->start == 0)
4504          stacksize = stacksize == 0;
4505        else
4506          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4507    
4508        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4509          {
4510          SLJIT_ASSERT(!has_alternatives);
4511          if (stacksize != 0)
4512            hotpath += 1 + IMM2_SIZE;
4513          else
4514            {
4515            if (*cc == OP_ALT)
4516              {
4517              hotpath = cc + 1 + LINK_SIZE;
4518              cc += GET(cc, 1);
4519              }
4520            else
4521              hotpath = cc;
4522            }
4523          }
4524        else
4525          {
4526          SLJIT_ASSERT(has_alternatives);
4527    
4528          stacksize = GET2(hotpath, 1);
4529          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4530          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4531          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4532          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4533          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4534          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4535          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4536          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4537          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4538          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4539          hotpath += 1 + IMM2_SIZE;
4540          }
4541      }      }
4542    else    else
4543      {      {
4544      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4545      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4546      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4547      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4202  cc += 1 + LINK_SIZE; Line 4672  cc += 1 + LINK_SIZE;
4672  return cc;  return cc;
4673  }  }
4674    
4675  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)
4676  {  {
4677  DEFINE_COMPILER;  DEFINE_COMPILER;
4678  fallback_common *fallback;  fallback_common *fallback;
4679  uschar opcode;  pcre_uchar opcode;
4680  int localptr;  int localptr;
4681  int cbraprivptr = 0;  int cbraprivptr = 0;
4682  int framesize;  int framesize;
4683  int stacksize;  int stacksize;
4684  int offset = 0;  int offset = 0;
4685  BOOL zero = FALSE;  BOOL zero = FALSE;
4686  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4687  int stack;  int stack;
4688  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4689  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4226  if (*cc == OP_BRAPOSZERO) Line 4696  if (*cc == OP_BRAPOSZERO)
4696    }    }
4697    
4698  opcode = *cc;  opcode = *cc;
4699  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4700  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4701  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4702  switch(opcode)  switch(opcode)
# Line 4241  switch(opcode) Line 4711  switch(opcode)
4711    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4712    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4713    offset <<= 1;    offset <<= 1;
4714    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4715    break;    break;
4716    
4717    default:    default:
# Line 4420  decrease_call_count(common); Line 4890  decrease_call_count(common);
4890  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4891  }  }
4892    
4893  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)
4894  {  {
4895  int class_len;  int class_len;
4896    
# Line 4459  else Line 4929  else
4929    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
4930    *type = *opcode;    *type = *opcode;
4931    cc++;    cc++;
4932    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
4933    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
4934    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
4935      {      {
# Line 4470  else Line 4940  else
4940    else    else
4941      {      {
4942      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
4943      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
4944      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
4945    
4946      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4482  else Line 4952  else
4952        *opcode = OP_EXACT;        *opcode = OP_EXACT;
4953    
4954      if (end != NULL)      if (end != NULL)
4955        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
4956      }      }
4957    return cc;    return cc;
4958    }    }
# Line 4490  else Line 4960  else
4960  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)
4961    {    {
4962    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
4963    cc += 2;    cc += IMM2_SIZE;
4964    }    }
4965    
4966  if (*type == 0)  if (*type == 0)
# Line 4505  if (*type == 0) Line 4975  if (*type == 0)
4975  if (end != NULL)  if (end != NULL)
4976    {    {
4977    *end = cc + 1;    *end = cc + 1;
4978  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4979    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
4980  #endif  #endif
4981    }    }
4982  return cc;  return cc;
4983  }  }
4984    
4985  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)
4986  {  {
4987  DEFINE_COMPILER;  DEFINE_COMPILER;
4988  fallback_common *fallback;  fallback_common *fallback;
4989  uschar opcode;  pcre_uchar opcode;
4990  uschar type;  pcre_uchar type;
4991  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
4992  uschar* end;  pcre_uchar* end;
4993  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
4994  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4995  struct sljit_label *label;  struct sljit_label *label;
# Line 4681  decrease_call_count(common); Line 5151  decrease_call_count(common);
5151  return end;  return end;
5152  }  }
5153    
5154  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)
5155  {  {
5156  DEFINE_COMPILER;  DEFINE_COMPILER;
5157  fallback_common *fallback;  fallback_common *fallback;
# Line 4725  add_jump(compiler, &fallback->topfallbac Line 5195  add_jump(compiler, &fallback->topfallbac
5195  return cc + 1;  return cc + 1;
5196  }  }
5197    
5198  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)
5199  {  {
5200  DEFINE_COMPILER;  DEFINE_COMPILER;
5201  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5202    
5203  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5204  if (common->currententry != NULL)  if (common->currententry != NULL)
5205    return cc + 3;    return cc + 1 + IMM2_SIZE;
5206    
5207  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));
5208  offset <<= 1;  offset <<= 1;
5209  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);
5210  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5211  return cc + 3;  return cc + 1 + IMM2_SIZE;
5212  }  }
5213    
5214  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)
5215  {  {
5216  DEFINE_COMPILER;  DEFINE_COMPILER;
5217  fallback_common *fallback;  fallback_common *fallback;
# Line 4867  while (cc < ccend) Line 5337  while (cc < ccend)
5337    
5338      case OP_CLASS:      case OP_CLASS:
5339      case OP_NCLASS:      case OP_NCLASS:
5340      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)
5341        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5342      else      else
5343        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);
5344      break;      break;
5345    
5346  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5347      case OP_XCLASS:      case OP_XCLASS:
5348      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)
5349        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 4884  while (cc < ccend) Line 5354  while (cc < ccend)
5354    
5355      case OP_REF:      case OP_REF:
5356      case OP_REFI:      case OP_REFI:
5357      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5358        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5359      else      else
5360        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 4992  SLJIT_ASSERT(cc == ccend); Line 5462  SLJIT_ASSERT(cc == ccend);
5462  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5463  {  {
5464  DEFINE_COMPILER;  DEFINE_COMPILER;
5465  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5466  uschar opcode;  pcre_uchar opcode;
5467  uschar type;  pcre_uchar type;
5468  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5469  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5470  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5119  switch(opcode) Line 5589  switch(opcode)
5589  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)
5590  {  {
5591  DEFINE_COMPILER;  DEFINE_COMPILER;
5592  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5593  uschar type;  pcre_uchar type;
5594    
5595  type = cc[3];  type = cc[1 + IMM2_SIZE];
5596  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5597    {    {
5598    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5151  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5621  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5621  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5622  {  {
5623  DEFINE_COMPILER;  DEFINE_COMPILER;
5624  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5625  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5626  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5627    
5628  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5223  int offset = 0; Line 5693  int offset = 0;
5693  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5694  int stacksize;  int stacksize;
5695  int count;  int count;
5696  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5697  uschar *ccbegin;  pcre_uchar *ccbegin;
5698  uschar *ccprev;  pcre_uchar *ccprev;
5699  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5700  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5701  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5702  uschar ket;  pcre_uchar ket;
5703  assert_fallback *assert;  assert_fallback *assert;
5704    BOOL has_alternatives;
5705  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5706  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5707  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5246  opcode = *cc; Line 5717  opcode = *cc;
5717  ccbegin = cc;  ccbegin = cc;
5718  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5719  cc += GET(cc, 1);  cc += GET(cc, 1);
5720    has_alternatives = *cc == OP_ALT;
5721    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5722      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5723  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5724    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5725  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
# Line 5294  else if (bra == OP_BRAZERO) Line 5768  else if (bra == OP_BRAZERO)
5768    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5769    }    }
5770    
5771  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5772    {    {
5773    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5774      {      {
# Line 5303  if (opcode == OP_ONCE) Line 5777  if (opcode == OP_ONCE)
5777      }      }
5778    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5779    }    }
5780    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5781      {
5782      if (has_alternatives)
5783        {
5784        /* Always exactly one alternative. */
5785        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5786        free_stack(common, 1);
5787    
5788        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5789        if (SLJIT_UNLIKELY(!jumplistitem))
5790          return;
5791        jumplist = jumplistitem;
5792        jumplistitem->next = NULL;
5793        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5794        }
5795      }
5796  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5797    {    {
5798    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5334  else if (*cc == OP_ALT) Line 5824  else if (*cc == OP_ALT)
5824    
5825    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5826    }    }
 else if (opcode == OP_COND || opcode == OP_SCOND)  
   {  
   /* Always one. */  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
   free_stack(common, 1);  
   
   jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));  
   if (SLJIT_UNLIKELY(!jumplistitem))  
     return;  
   jumplist = jumplistitem;  
   jumplistitem->next = NULL;  
   jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);  
   }  
5827    
5828  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5829  if (current->topfallbacks)  if (current->topfallbacks)
5830    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5831    
5832  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5833    {    {
5834    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5835    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
5836      {      {
5837        SLJIT_ASSERT(has_alternatives);
5838      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5839      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
5840        {        {
# Line 5367  if (opcode == OP_COND || opcode == OP_SC Line 5845  if (opcode == OP_COND || opcode == OP_SC
5845      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5846      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5847      }      }
5848    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5849      {      {
5850        SLJIT_ASSERT(has_alternatives);
5851      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5852      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5853      }      }
5854      else
5855        SLJIT_ASSERT(!has_alternatives);
5856    }    }
5857    
5858  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5859    {    {
5860    count = 1;    count = 1;
5861    do    do
# Line 5483  if (*cc == OP_ALT || opcode == OP_COND | Line 5964  if (*cc == OP_ALT || opcode == OP_COND |
5964      {      {
5965      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
5966      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5967      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT))      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
5968    
5969        {        {
5970        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
5971        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5717  while (current) Line 6199  while (current)
6199      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6200      case OP_CLASS:      case OP_CLASS:
6201      case OP_NCLASS:      case OP_NCLASS:
6202    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6203      case OP_XCLASS:      case OP_XCLASS:
6204    #endif
6205      compile_iterator_fallbackpath(common, current);      compile_iterator_fallbackpath(common, current);
6206      break;      break;
6207    
# Line 5784  while (current) Line 6268  while (current)
6268  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
6269  {  {
6270  DEFINE_COMPILER;  DEFINE_COMPILER;
6271  uschar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
6272  uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6273  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
6274  int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
6275  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6276  int alternativesize;  int alternativesize;
# Line 5874  sljit_emit_fast_return(compiler, SLJIT_M Line 6358  sljit_emit_fast_return(compiler, SLJIT_M
6358  #undef CURRENT_AS  #undef CURRENT_AS
6359    
6360  void  void
6361  _pcre_jit_compile(const real_pcre *re, pcre_extra *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra)
6362  {  {
6363  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6364  fallback_common rootfallback;  fallback_common rootfallback;
6365  compiler_common common_data;  compiler_common common_data;
6366  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6367  const unsigned char *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6368  pcre_study_data *study;  pcre_study_data *study;
6369  uschar *ccend;  pcre_uchar *ccend;
6370  executable_function *function;  executable_function *function;
6371  void *executable_func;  void *executable_func;
6372    sljit_uw executable_size;
6373  struct sljit_label *leave;  struct sljit_label *leave;
6374  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6375  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
# Line 5897  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_ Line 6382  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_
6382  study = extra->study_data;  study = extra->study_data;
6383    
6384  if (!tables)  if (!tables)
6385    tables = _pcre_default_tables;    tables = PRIV(default_tables);
6386    
6387  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6388  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;
6389    
6390  common->compiler = NULL;  common->compiler = NULL;
6391  common->start = rootfallback.cc;  common->start = rootfallback.cc;
# Line 5941  else Line 6426  else
6426    }    }
6427  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6428  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6429    common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6430    common->name_count = re->name_count;
6431    common->name_entry_size = re->name_entry_size;
6432  common->acceptlabel = NULL;  common->acceptlabel = NULL;
6433  common->stubs = NULL;  common->stubs = NULL;
6434  common->entries = NULL;  common->entries = NULL;
# Line 5956  common->vspace = NULL; Line 6444  common->vspace = NULL;
6444  common->casefulcmp = NULL;  common->casefulcmp = NULL;
6445  common->caselesscmp = NULL;  common->caselesscmp = NULL;
6446  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6447  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6448  common->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6449    common->utf = (re->options & PCRE_UTF8) != 0;
6450  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6451  common->useucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
6452  #endif  #endif
6453  common->utf8readchar = NULL;  common->utfreadchar = NULL;
6454  common->utf8readtype8 = NULL;  #ifdef COMPILE_PCRE8
6455    common->utfreadtype8 = NULL;
6456  #endif  #endif
6457    #endif /* SUPPORT_UTF */
6458  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6459  common->getucd = NULL;  common->getucd = NULL;
6460  #endif  #endif
# Line 5995  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6486  sljit_emit_enter(compiler, 1, 5, 5, comm
6486  /* Register init. */  /* Register init. */
6487  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6488  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6489    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);
6490    
6491  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6492  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6493  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));
6494  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));
6495  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 6013  if ((re->options & PCRE_ANCHORED) == 0) Line 6504  if ((re->options & PCRE_ANCHORED) == 0)
6504    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);
6505    /* Forward search if possible. */    /* Forward search if possible. */
6506    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6507      fast_forward_first_byte(common, re->first_byte, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6508    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6509      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6510    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)
6511      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);
6512    }    }
6513  if ((re->flags & PCRE_REQCHSET) != 0)  if ((re->flags & PCRE_REQCHSET) != 0)
6514    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6515    
6516  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6517  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 6045  if (common->accept != NULL) Line 6536  if (common->accept != NULL)
6536  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6537  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
6538  leave = LABEL();  leave = LABEL();
6539  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6540    
6541  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
6542  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
# Line 6067  if ((re->options & PCRE_ANCHORED) == 0) Line 6558  if ((re->options & PCRE_ANCHORED) == 0)
6558      {      {
6559      if (study != NULL && study->minlength > 1)      if (study != NULL && study->minlength > 1)
6560        {        {
6561        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));
6562        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
6563        }        }
6564      else      else
# Line 6077  if ((re->options & PCRE_ANCHORED) == 0) Line 6568  if ((re->options & PCRE_ANCHORED) == 0)
6568      {      {
6569      if (study != NULL && study->minlength > 1)      if (study != NULL && study->minlength > 1)
6570        {        {
6571        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));
6572        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);
6573        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
6574        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 6189  if (common->caselesscmp != NULL) Line 6680  if (common->caselesscmp != NULL)
6680    set_jumps(common->caselesscmp, LABEL());    set_jumps(common->caselesscmp, LABEL());
6681    do_caselesscmp(common);    do_caselesscmp(common);
6682    }    }
6683  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6684  if (common->utf8readchar != NULL)  if (common->utfreadchar != NULL)
6685    {    {
6686    set_jumps(common->utf8readchar, LABEL());    set_jumps(common->utfreadchar, LABEL());
6687    do_utf8readchar(common);    do_utfreadchar(common);
6688    }    }
6689  if (common->utf8readtype8 != NULL)  #ifdef COMPILE_PCRE8
6690    if (common->utfreadtype8 != NULL)
6691    {    {
6692    set_jumps(common->utf8readtype8, LABEL());    set_jumps(common->utfreadtype8, LABEL());
6693    do_utf8readtype8(common);    do_utfreadtype8(common);
6694    }    }
6695  #endif  #endif
6696    #endif /* COMPILE_PCRE8 */
6697  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6698  if (common->getucd != NULL)  if (common->getucd != NULL)
6699    {    {
# Line 6211  if (common->getucd != NULL) Line 6704  if (common->getucd != NULL)
6704    
6705  SLJIT_FREE(common->localptrs);  SLJIT_FREE(common->localptrs);
6706  executable_func = sljit_generate_code(compiler);  executable_func = sljit_generate_code(compiler);
6707    executable_size = sljit_get_generated_code_size(compiler);
6708  sljit_free_compiler(compiler);  sljit_free_compiler(compiler);
6709  if (executable_func == NULL)  if (executable_func == NULL)
6710    return;    return;
# Line 6225  if (function == NULL) Line 6719  if (function == NULL)
6719    }    }
6720    
6721  function->executable_func = executable_func;  function->executable_func = executable_func;
6722    function->executable_size = executable_size;
6723  function->callback = NULL;  function->callback = NULL;
6724  function->userdata = NULL;  function->userdata = NULL;
6725  extra->executable_jit = function;  extra->executable_jit = function;
# Line 6237  union { Line 6732  union {
6732     void* executable_func;     void* executable_func;
6733     jit_function call_executable_func;     jit_function call_executable_func;
6734  } convert_executable_func;  } convert_executable_func;
6735  uschar local_area[LOCAL_SPACE_SIZE];  pcre_uint8 local_area[LOCAL_SPACE_SIZE];
6736  struct sljit_stack local_stack;  struct sljit_stack local_stack;
6737    
6738  local_stack.top = (sljit_w)&local_area;  local_stack.top = (sljit_w)&local_area;
# Line 6250  return convert_executable_func.call_exec Line 6745  return convert_executable_func.call_exec
6745  }  }
6746    
6747  int  int
6748  _pcre_jit_exec(const real_pcre *re, void *executable_func,  PRIV(jit_exec)(const REAL_PCRE *re, void *executable_func,
6749    PCRE_SPTR subject, int length, int start_offset, int options,    const pcre_uchar *subject, int length, int start_offset, int options,
6750    int match_limit, int *offsets, int offsetcount)    int match_limit, int *offsets, int offsetcount)
6751  {  {
6752  executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
# Line 6281  workspace. We don't need the workspace h Line 6776  workspace. We don't need the workspace h
6776  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
6777  gets the same result with and without JIT. */  gets the same result with and without JIT. */
6778    
6779  offsetcount = ((offsetcount - (offsetcount % 3)) * 2)/3;  if (offsetcount != 2)
6780      offsetcount = ((offsetcount - (offsetcount % 3)) * 2) / 3;
6781  maxoffsetcount = (re->top_bracket + 1) * 2;  maxoffsetcount = (re->top_bracket + 1) * 2;
6782  if (offsetcount > maxoffsetcount)  if (offsetcount > maxoffsetcount)
6783    offsetcount = maxoffsetcount;    offsetcount = maxoffsetcount;
# Line 6306  return retval; Line 6802  return retval;
6802  }  }
6803    
6804  void  void
6805  _pcre_jit_free(void *executable_func)  PRIV(jit_free)(void *executable_func)
6806  {  {
6807  executable_function *function = (executable_function*)executable_func;  executable_function *function = (executable_function*)executable_func;
6808  sljit_free_code(function->executable_func);  sljit_free_code(function->executable_func);
6809  SLJIT_FREE(function);  SLJIT_FREE(function);
6810  }  }
6811    
6812    int
6813    PRIV(jit_get_size)(void *executable_func)
6814    {
6815    return ((executable_function*)executable_func)->executable_size;
6816    }
6817    
6818    const char*
6819    PRIV(jit_get_target)(void)
6820    {
6821    return sljit_get_platform_name();
6822    }
6823    
6824    #ifdef COMPILE_PCRE8
6825  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
6826  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
6827    #else
6828    PCRE_EXP_DECL pcre16_jit_stack *
6829    pcre16_jit_stack_alloc(int startsize, int maxsize)
6830    #endif
6831  {  {
6832  if (startsize < 1 || maxsize < 1)  if (startsize < 1 || maxsize < 1)
6833    return NULL;    return NULL;
# Line 6322  if (startsize > maxsize) Line 6835  if (startsize > maxsize)
6835    startsize = maxsize;    startsize = maxsize;
6836  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  startsize = (startsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
6837  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);  maxsize = (maxsize + STACK_GROWTH_RATE - 1) & ~(STACK_GROWTH_RATE - 1);
6838  return (pcre_jit_stack*)sljit_allocate_stack(startsize, maxsize);  return (PUBL(jit_stack)*)sljit_allocate_stack(startsize, maxsize);
6839  }  }
6840    
6841    #ifdef COMPILE_PCRE8
6842  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6843  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
6844    #else
6845    PCRE_EXP_DECL void
6846    pcre16_jit_stack_free(pcre16_jit_stack *stack)
6847    #endif
6848  {  {
6849  sljit_free_stack((struct sljit_stack*)stack);  sljit_free_stack((struct sljit_stack*)stack);
6850  }  }
6851    
6852    #ifdef COMPILE_PCRE8
6853  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6854  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)
6855    #else
6856    PCRE_EXP_DECL void
6857    pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
6858    #endif
6859  {  {
6860  executable_function *function;  executable_function *function;
6861  if (extra != NULL &&  if (extra != NULL &&
# Line 6350  if (extra != NULL && Line 6873  if (extra != NULL &&
6873  /* 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
6874  being compiled. */  being compiled. */
6875    
6876    #ifdef COMPILE_PCRE8
6877  PCRE_EXP_DECL pcre_jit_stack *  PCRE_EXP_DECL pcre_jit_stack *
6878  pcre_jit_stack_alloc(int startsize, int maxsize)  pcre_jit_stack_alloc(int startsize, int maxsize)
6879    #else
6880    PCRE_EXP_DECL pcre16_jit_stack *
6881    pcre16_jit_stack_alloc(int startsize, int maxsize)
6882    #endif
6883  {  {
6884  (void)startsize;  (void)startsize;
6885  (void)maxsize;  (void)maxsize;
6886  return NULL;  return NULL;
6887  }  }
6888    
6889    #ifdef COMPILE_PCRE8
6890  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6891  pcre_jit_stack_free(pcre_jit_stack *stack)  pcre_jit_stack_free(pcre_jit_stack *stack)
6892    #else
6893    PCRE_EXP_DECL void
6894    pcre16_jit_stack_free(pcre16_jit_stack *stack)
6895    #endif
6896  {  {
6897  (void)stack;  (void)stack;
6898  }  }
6899    
6900    #ifdef COMPILE_PCRE8
6901  PCRE_EXP_DECL void  PCRE_EXP_DECL void
6902  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)
6903    #else
6904    PCRE_EXP_DECL void
6905    pcre16_assign_jit_stack(pcre16_extra *extra, pcre16_jit_callback callback, void *userdata)
6906    #endif
6907  {  {
6908  (void)extra;  (void)extra;
6909  (void)callback;  (void)callback;

Legend:
Removed from v.736  
changed lines
  Added in v.911

  ViewVC Help
Powered by ViewVC 1.1.5