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

Diff of /code/trunk/pcre_jit_compile.c

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

revision 792 by ph10, Wed Dec 7 16:44:48 2011 UTC revision 929 by zherczeg, Fri Feb 24 11:07:47 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55  #define SLJIT_MALLOC(size) (pcre_malloc)(size)  #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56  #define SLJIT_FREE(ptr) (pcre_free)(ptr)  #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 62  system files. */ Line 62  system files. */
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 148  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *uchar_ptr;
156      pcre_uchar *mark_ptr;
157    /* Everything else after. */    /* Everything else after. */
158    int offsetcount;    int offsetcount;
159    int calllimit;    int calllimit;
160    uschar notbol;    pcre_uint8 notbol;
161    uschar noteol;    pcre_uint8 noteol;
162    uschar notempty;    pcre_uint8 notempty;
163    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
164  } jit_arguments;  } jit_arguments;
165    
166  typedef struct executable_function {  typedef struct executable_functions {
167    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
168    pcre_jit_callback callback;    PUBL(jit_callback) callback;
169    void *userdata;    void *userdata;
170    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
171  } executable_function;  } executable_functions;
172    
173  typedef struct jump_list {  typedef struct jump_list {
174    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 198  typedef struct fallback_common { Line 199  typedef struct fallback_common {
199    struct fallback_common *top;    struct fallback_common *top;
200    jump_list *topfallbacks;    jump_list *topfallbacks;
201    /* Opcode pointer. */    /* Opcode pointer. */
202    uschar *cc;    pcre_uchar *cc;
203  } fallback_common;  } fallback_common;
204    
205  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 269  typedef struct recurse_fallback { Line 270  typedef struct recurse_fallback {
270    
271  typedef struct compiler_common {  typedef struct compiler_common {
272    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
273    uschar *start;    pcre_uchar *start;
274    
275      /* Local stack area size and variable pointers. */
276    int localsize;    int localsize;
277    int *localptrs;    int *localptrs;
   const uschar *fcc;  
   sljit_w lcc;  
278    int cbraptr;    int cbraptr;
279      /* OVector starting point. Must be divisible by 2. */
280      int ovector_start;
281      /* Last known position of the requested byte. */
282      int req_char_ptr;
283      /* Head of the last recursion. */
284      int recursive_head;
285      /* First inspected character for partial matching. */
286      int start_used_ptr;
287      /* Starting pointer for partial soft matches. */
288      int hit_start;
289      /* End pointer of the first line. */
290      int first_line_end;
291      /* Points to the marked string. */
292      int mark_ptr;
293    
294      /* Other  */
295      const pcre_uint8 *fcc;
296      sljit_w lcc;
297      int mode;
298    int nltype;    int nltype;
299    int newline;    int newline;
300    int bsr_nltype;    int bsr_nltype;
301    int endonly;    int endonly;
302      BOOL has_set_som;
303    sljit_w ctypes;    sljit_w ctypes;
304    sljit_uw name_table;    sljit_uw name_table;
305    sljit_w name_count;    sljit_w name_count;
306    sljit_w name_entry_size;    sljit_w name_entry_size;
307    
308      /* Labels and jump lists. */
309      struct sljit_label *partialmatchlabel;
310    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
311    stub_list *stubs;    stub_list *stubs;
312    recurse_entry *entries;    recurse_entry *entries;
313    recurse_entry *currententry;    recurse_entry *currententry;
314      jump_list *partialmatch;
315    jump_list *accept;    jump_list *accept;
316    jump_list *calllimit;    jump_list *calllimit;
317    jump_list *stackalloc;    jump_list *stackalloc;
# Line 298  typedef struct compiler_common { Line 323  typedef struct compiler_common {
323    jump_list *casefulcmp;    jump_list *casefulcmp;
324    jump_list *caselesscmp;    jump_list *caselesscmp;
325    BOOL jscript_compat;    BOOL jscript_compat;
326  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
327    BOOL utf8;    BOOL utf;
328  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
329    BOOL useucp;    BOOL use_ucp;
330  #endif  #endif
331    jump_list *utf8readchar;    jump_list *utfreadchar;
332    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
333      jump_list *utfreadtype8;
334  #endif  #endif
335    #endif /* SUPPORT_UTF */
336  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
337    jump_list *getucd;    jump_list *getucd;
338  #endif  #endif
# Line 317  typedef struct compare_context { Line 344  typedef struct compare_context {
344    int length;    int length;
345    int sourcereg;    int sourcereg;
346  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
347    int byteptr;    int ucharptr;
348    union {    union {
349      int asint;      sljit_i asint;
350      short asshort;      sljit_uh asushort;
351    #ifdef COMPILE_PCRE8
352      sljit_ub asbyte;      sljit_ub asbyte;
353      sljit_ub asbytes[4];      sljit_ub asuchars[4];
354    #else
355    #ifdef COMPILE_PCRE16
356        sljit_uh asuchars[2];
357    #endif
358    #endif
359    } c;    } c;
360    union {    union {
361      int asint;      sljit_i asint;
362      short asshort;      sljit_uh asushort;
363    #ifdef COMPILE_PCRE8
364      sljit_ub asbyte;      sljit_ub asbyte;
365      sljit_ub asbytes[4];      sljit_ub asuchars[4];
366    #else
367    #ifdef COMPILE_PCRE16
368        sljit_uh asuchars[2];
369    #endif
370    #endif
371    } oc;    } oc;
372  #endif  #endif
373  } compare_context;  } compare_context;
374    
375  enum {  enum {
376    frame_end = 0,    frame_end = 0,
377    frame_setstrbegin = -1    frame_setstrbegin = -1,
378      frame_setmark = -2
379  };  };
380    
381    /* Undefine sljit macros. */
382    #undef CMP
383    
384  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
385  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
386    
387  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
388  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
389  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
390  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
391  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
392  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
393  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
394  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
395  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
396  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
397    
398  /* Locals layout. */  /* Locals layout. */
# Line 359  enum { Line 402  enum {
402  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
403  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
404  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
405  /* Max limit of recursions. */  /* Max limit of recursions. */
406  #define CALL_LIMIT       (5 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (7 * sizeof(sljit_w))  
407  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
408  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
409  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
410  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
411  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
412  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
413  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
414  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
415    
416    #ifdef COMPILE_PCRE8
417    #define MOV_UCHAR  SLJIT_MOV_UB
418    #define MOVU_UCHAR SLJIT_MOVU_UB
419    #else
420    #ifdef COMPILE_PCRE16
421    #define MOV_UCHAR  SLJIT_MOV_UH
422    #define MOVU_UCHAR SLJIT_MOVU_UH
423    #else
424    #error Unsupported compiling mode
425    #endif
426    #endif
427    
428  /* Shortcuts. */  /* Shortcuts. */
429  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 398  the start pointers when the end of the c Line 447  the start pointers when the end of the c
447  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
448    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
449    
450  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
451  {  {
452  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));
453  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 419  return cc; Line 468  return cc;
468   compile_fallbackpath   compile_fallbackpath
469  */  */
470    
471  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
472  {  {
473  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
474  switch(*cc)  switch(*cc)
# Line 475  switch(*cc) Line 524  switch(*cc)
524    return cc + 1;    return cc + 1;
525    
526    case OP_ANYBYTE:    case OP_ANYBYTE:
527  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
528    if (common->utf8) return NULL;    if (common->utf) return NULL;
529  #endif  #endif
530    return cc + 1;    return cc + 1;
531    
# Line 484  switch(*cc) Line 533  switch(*cc)
533    case OP_CHARI:    case OP_CHARI:
534    case OP_NOT:    case OP_NOT:
535    case OP_NOTI:    case OP_NOTI:
   
536    case OP_STAR:    case OP_STAR:
537    case OP_MINSTAR:    case OP_MINSTAR:
538    case OP_PLUS:    case OP_PLUS:
# Line 522  switch(*cc) Line 570  switch(*cc)
570    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
571    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
572    cc += 2;    cc += 2;
573  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
574    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]);
575  #endif  #endif
576    return cc;    return cc;
577    
# Line 543  switch(*cc) Line 591  switch(*cc)
591    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
592    case OP_NOTEXACTI:    case OP_NOTEXACTI:
593    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
594    cc += 4;    cc += 2 + IMM2_SIZE;
595  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
596    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]);
597  #endif  #endif
598    return cc;    return cc;
599    
600    case OP_NOTPROP:    case OP_NOTPROP:
601    case OP_PROP:    case OP_PROP:
602      return cc + 1 + 2;
603    
604    case OP_TYPEUPTO:    case OP_TYPEUPTO:
605    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
606    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 562  switch(*cc) Line 612  switch(*cc)
612    case OP_RREF:    case OP_RREF:
613    case OP_NRREF:    case OP_NRREF:
614    case OP_CLOSE:    case OP_CLOSE:
615    cc += 3;    cc += 1 + IMM2_SIZE;
616    return cc;    return cc;
617    
618    case OP_CRRANGE:    case OP_CRRANGE:
619    case OP_CRMINRANGE:    case OP_CRMINRANGE:
620    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
621    
622    case OP_CLASS:    case OP_CLASS:
623    case OP_NCLASS:    case OP_NCLASS:
624    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
625    
626  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
627    case OP_XCLASS:    case OP_XCLASS:
628    return cc + GET(cc, 1);    return cc + GET(cc, 1);
629  #endif  #endif
# Line 603  switch(*cc) Line 653  switch(*cc)
653    case OP_CBRAPOS:    case OP_CBRAPOS:
654    case OP_SCBRA:    case OP_SCBRA:
655    case OP_SCBRAPOS:    case OP_SCBRAPOS:
656    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
657    
658      case OP_MARK:
659      return cc + 1 + 2 + cc[1];
660    
661    default:    default:
662    return NULL;    return NULL;
663    }    }
664  }  }
665    
666  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
667  {  {
668  int localspace = 0;  int localspace = 0;
669  uschar *alternative;  pcre_uchar *alternative;
670  /* 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. */
671  while (cc < ccend)  while (cc < ccend)
672    {    {
673    switch(*cc)    switch(*cc)
674      {      {
675        case OP_SET_SOM:
676        common->has_set_som = TRUE;
677        cc += 1;
678        break;
679    
680      case OP_ASSERT:      case OP_ASSERT:
681      case OP_ASSERT_NOT:      case OP_ASSERT_NOT:
682      case OP_ASSERTBACK:      case OP_ASSERTBACK:
# Line 636  while (cc < ccend) Line 694  while (cc < ccend)
694      case OP_CBRAPOS:      case OP_CBRAPOS:
695      case OP_SCBRAPOS:      case OP_SCBRAPOS:
696      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
697      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
698      break;      break;
699    
700      case OP_COND:      case OP_COND:
# Line 647  while (cc < ccend) Line 705  while (cc < ccend)
705      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
706      break;      break;
707    
708        case OP_RECURSE:
709        /* Set its value only once. */
710        if (common->recursive_head == 0)
711          {
712          common->recursive_head = common->ovector_start;
713          common->ovector_start += sizeof(sljit_w);
714          }
715        cc += 1 + LINK_SIZE;
716        break;
717    
718        case OP_MARK:
719        if (common->mark_ptr == 0)
720          {
721          common->mark_ptr = common->ovector_start;
722          common->ovector_start += sizeof(sljit_w);
723          }
724        cc += 1 + 2 + cc[1];
725        break;
726    
727      default:      default:
728      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
729      if (cc == NULL)      if (cc == NULL)
# Line 657  while (cc < ccend) Line 734  while (cc < ccend)
734  return localspace;  return localspace;
735  }  }
736    
737  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
738  {  {
739  uschar *cc = common->start;  pcre_uchar *cc = common->start;
740  uschar *alternative;  pcre_uchar *alternative;
741  while (cc < ccend)  while (cc < ccend)
742    {    {
743    switch(*cc)    switch(*cc)
# Line 684  while (cc < ccend) Line 761  while (cc < ccend)
761      case OP_SCBRAPOS:      case OP_SCBRAPOS:
762      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
763      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
764      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
765      break;      break;
766    
767      case OP_COND:      case OP_COND:
# Line 707  while (cc < ccend) Line 784  while (cc < ccend)
784  }  }
785    
786  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
787  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
788  {  {
789  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
790  int length = 0;  int length = 0;
791  BOOL possessive = FALSE;  BOOL possessive = FALSE;
792  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
793    BOOL setmark_found = recursive;
794    
795  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
796    {    {
# Line 726  while (cc < ccend) Line 804  while (cc < ccend)
804    switch(*cc)    switch(*cc)
805      {      {
806      case OP_SET_SOM:      case OP_SET_SOM:
807      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
808      if (!setsom_found)      if (!setsom_found)
809        {        {
810        length += 2;        length += 2;
811        setsom_found = TRUE;        setsom_found = TRUE;
812        }        }
813      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
814        break;
815    
816        case OP_MARK:
817        SLJIT_ASSERT(common->mark_ptr != 0);
818        if (!setmark_found)
819          {
820          length += 2;
821          setmark_found = TRUE;
822          }
823        cc += 1 + 2 + cc[1];
824        break;
825    
826        case OP_RECURSE:
827        if (common->has_set_som && !setsom_found)
828          {
829          length += 2;
830          setsom_found = TRUE;
831          }
832        if (common->mark_ptr != 0 && !setmark_found)
833          {
834          length += 2;
835          setmark_found = TRUE;
836          }
837        cc += 1 + LINK_SIZE;
838      break;      break;
839    
840      case OP_CBRA:      case OP_CBRA:
# Line 740  while (cc < ccend) Line 842  while (cc < ccend)
842      case OP_SCBRA:      case OP_SCBRA:
843      case OP_SCBRAPOS:      case OP_SCBRAPOS:
844      length += 3;      length += 3;
845      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
846      break;      break;
847    
848      default:      default:
# Line 758  if (length > 0) Line 860  if (length > 0)
860  return -1;  return -1;
861  }  }
862    
863  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)
864  {  {
865  DEFINE_COMPILER;  DEFINE_COMPILER;
866  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
867  BOOL setsom_found = FALSE;  BOOL setsom_found = recursive;
868    BOOL setmark_found = recursive;
869  int offset;  int offset;
870    
871  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
872    SLJIT_UNUSED_ARG(stacktop);
873  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
874    
875  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 776  while (cc < ccend) Line 880  while (cc < ccend)
880    switch(*cc)    switch(*cc)
881      {      {
882      case OP_SET_SOM:      case OP_SET_SOM:
883      case OP_RECURSE:      SLJIT_ASSERT(common->has_set_som);
884      if (!setsom_found)      if (!setsom_found)
885        {        {
886        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 786  while (cc < ccend) Line 890  while (cc < ccend)
890        stackpos += (int)sizeof(sljit_w);        stackpos += (int)sizeof(sljit_w);
891        setsom_found = TRUE;        setsom_found = TRUE;
892        }        }
893      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += 1;
894        break;
895    
896        case OP_MARK:
897        SLJIT_ASSERT(common->mark_ptr != 0);
898        if (!setmark_found)
899          {
900          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
901          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
902          stackpos += (int)sizeof(sljit_w);
903          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
904          stackpos += (int)sizeof(sljit_w);
905          setmark_found = TRUE;
906          }
907        cc += 1 + 2 + cc[1];
908        break;
909    
910        case OP_RECURSE:
911        if (common->has_set_som && !setsom_found)
912          {
913          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
914          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setstrbegin);
915          stackpos += (int)sizeof(sljit_w);
916          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
917          stackpos += (int)sizeof(sljit_w);
918          setsom_found = TRUE;
919          }
920        if (common->mark_ptr != 0 && !setmark_found)
921          {
922          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
923          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmark);
924          stackpos += (int)sizeof(sljit_w);
925          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP1, 0);
926          stackpos += (int)sizeof(sljit_w);
927          setmark_found = TRUE;
928          }
929        cc += 1 + LINK_SIZE;
930      break;      break;
931    
932      case OP_CBRA:      case OP_CBRA:
# Line 803  while (cc < ccend) Line 943  while (cc < ccend)
943      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
944      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
945    
946      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
947      break;      break;
948    
949      default:      default:
# Line 816  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 956  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
956  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
957  }  }
958    
959  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)
960  {  {
961  int localsize = 2;  int localsize = 2;
962  uschar *alternative;  pcre_uchar *alternative;
963  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
964  while (cc < ccend)  while (cc < ccend)
965    {    {
# Line 842  while (cc < ccend) Line 982  while (cc < ccend)
982      case OP_CBRA:      case OP_CBRA:
983      case OP_SCBRA:      case OP_SCBRA:
984      localsize++;      localsize++;
985      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
986      break;      break;
987    
988      case OP_CBRAPOS:      case OP_CBRAPOS:
989      case OP_SCBRAPOS:      case OP_SCBRAPOS:
990      localsize += 2;      localsize += 2;
991      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
992      break;      break;
993    
994      case OP_COND:      case OP_COND:
# Line 869  SLJIT_ASSERT(cc == ccend); Line 1009  SLJIT_ASSERT(cc == ccend);
1009  return localsize;  return localsize;
1010  }  }
1011    
1012  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
1013    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
1014  {  {
1015  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 878  int count; Line 1018  int count;
1018  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
1019  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
1020  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
1021  uschar *alternative;  pcre_uchar *alternative;
1022  enum {  enum {
1023    start,    start,
1024    loop,    loop,
# Line 913  while (status != end) Line 1053  while (status != end)
1053    switch(status)    switch(status)
1054      {      {
1055      case start:      case start:
1056      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
1057      count = 1;      count = 1;
1058      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
1059      status = loop;      status = loop;
1060      break;      break;
1061    
# Line 939  while (status != end) Line 1079  while (status != end)
1079        case OP_SBRAPOS:        case OP_SBRAPOS:
1080        case OP_SCOND:        case OP_SCOND:
1081        count = 1;        count = 1;
1082        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1083        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1084        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1085        break;        break;
# Line 948  while (status != end) Line 1088  while (status != end)
1088        case OP_SCBRA:        case OP_SCBRA:
1089        count = 1;        count = 1;
1090        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1091        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1092        break;        break;
1093    
1094        case OP_CBRAPOS:        case OP_CBRAPOS:
1095        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1096        count = 2;        count = 2;
1097        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1098        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1099        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1100        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1101        break;        break;
1102    
1103        case OP_COND:        case OP_COND:
# Line 966  while (status != end) Line 1106  while (status != end)
1106        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1107          {          {
1108          count = 1;          count = 1;
1109          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1110          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1111          }          }
1112        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1174  struct sljit_label *loop; Line 1314  struct sljit_label *loop;
1314  int i;  int i;
1315  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1316  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1317  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));
1318  if (length < 8)  if (length < 8)
1319    {    {
1320    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1198  struct sljit_label *loop; Line 1338  struct sljit_label *loop;
1338  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1339    
1340  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1341  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));
1342  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);
1343    
1344  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1345    if (common->mark_ptr != 0)
1346      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
1347  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));
1348    if (common->mark_ptr != 0)
1349      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), SLJIT_TEMPORARY_REG3, 0);
1350  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));
1351  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));
1352  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);
1353  /* Unlikely, but possible */  /* Unlikely, but possible */
1354  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1355  loop = LABEL();  loop = LABEL();
1356  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);
1357  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));
1358  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1359  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1360    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1361    #endif
1362    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1363  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);
1364  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1365  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1223  if (topbracket > 1) Line 1370  if (topbracket > 1)
1370    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));
1371    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1372    
1373    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1374    loop = LABEL();    loop = LABEL();
1375    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)));
1376    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);
1377    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);
1378    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1379    }    }
1380  else  else
1381    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1382  }  }
1383    
1384  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE void return_with_partial_match(compiler_common *common, struct sljit_label *leave)
1385    {
1386    DEFINE_COMPILER;
1387    
1388    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1389    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1390    
1391    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1392    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1393    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1394    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1395    
1396    /* Store match begin and end. */
1397    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1398    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1399    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mode == JIT_PARTIAL_HARD_COMPILE ? common->start_used_ptr : common->hit_start);
1400    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1401    #ifdef COMPILE_PCRE16
1402    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1403    #endif
1404    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1405    
1406    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1407    #ifdef COMPILE_PCRE16
1408    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1409    #endif
1410    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1411    
1412    JUMPTO(SLJIT_JUMP, leave);
1413    }
1414    
1415    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1416    {
1417    /* May destroy TMP1. */
1418    DEFINE_COMPILER;
1419    struct sljit_jump *jump;
1420    
1421    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1422      {
1423      /* The value of -1 must be kept for start_used_ptr! */
1424      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1425      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1426      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1427      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1428      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1429      JUMPHERE(jump);
1430      }
1431    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1432      {
1433      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1434      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1435      JUMPHERE(jump);
1436      }
1437    }
1438    
1439    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1440  {  {
1441  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1442  unsigned int c;  unsigned int c;
1443    
1444  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1445  if (common->utf8)  if (common->utf)
1446    {    {
1447    GETCHAR(c, cc);    GETCHAR(c, cc);
1448    if (c > 127)    if (c > 127)
# Line 1251  if (common->utf8) Line 1453  if (common->utf8)
1453      return FALSE;      return FALSE;
1454  #endif  #endif
1455      }      }
1456    #ifndef COMPILE_PCRE8
1457      return common->fcc[c] != c;
1458    #endif
1459    }    }
1460  else  else
1461  #endif  #endif
1462    c = *cc;    c = *cc;
1463  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1464  }  }
1465    
1466  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)
1467  {  {
1468  /* Returns with the othercase. */  /* Returns with the othercase. */
1469  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1470  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1471    {    {
1472  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1473    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1271  if (common->utf8 && c > 127) Line 1476  if (common->utf8 && c > 127)
1476  #endif  #endif
1477    }    }
1478  #endif  #endif
1479  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1480  }  }
1481    
1482  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)
1483  {  {
1484  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1485  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1486  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1487  int n;  int n;
1488  #endif  #endif
1489    
1490  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1491  if (common->utf8)  if (common->utf)
1492    {    {
1493    GETCHAR(c, cc);    GETCHAR(c, cc);
1494    if (c <= 127)    if (c <= 127)
# Line 1300  if (common->utf8) Line 1505  if (common->utf8)
1505  else  else
1506    {    {
1507    c = *cc;    c = *cc;
1508    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1509    }    }
1510  #else  #else
1511  c = *cc;  c = *cc;
1512  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1513  #endif  #endif
1514    
1515  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1318  if (c <= 127 && bit == 0x20) Line 1523  if (c <= 127 && bit == 0x20)
1523  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1524    return 0;    return 0;
1525    
1526  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1527  if (common->utf8 && c > 127)  
1528    #ifdef SUPPORT_UTF
1529    if (common->utf && c > 127)
1530    {    {
1531    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1532    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1533      {      {
1534      n--;      n--;
# Line 1329  if (common->utf8 && c > 127) Line 1536  if (common->utf8 && c > 127)
1536      }      }
1537    return (n << 8) | bit;    return (n << 8) | bit;
1538    }    }
1539  #endif  #endif /* SUPPORT_UTF */
1540  return (0 << 8) | bit;  return (0 << 8) | bit;
1541    
1542    #else /* COMPILE_PCRE8 */
1543    
1544    #ifdef COMPILE_PCRE16
1545    #ifdef SUPPORT_UTF
1546    if (common->utf && c > 65535)
1547      {
1548      if (bit >= (1 << 10))
1549        bit >>= 10;
1550      else
1551        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1552      }
1553    #endif /* SUPPORT_UTF */
1554    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1555    #endif /* COMPILE_PCRE16 */
1556    
1557    #endif /* COMPILE_PCRE8 */
1558    }
1559    
1560    static void check_partial(compiler_common *common, BOOL force)
1561    {
1562    /* Checks whether a partial matching is occured. Does not modify registers. */
1563    DEFINE_COMPILER;
1564    struct sljit_jump *jump = NULL;
1565    
1566    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1567    
1568    if (common->mode == JIT_COMPILE)
1569      return;
1570    
1571    if (!force)
1572      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1573    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1574      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1575    
1576    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1577      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1578    else
1579      {
1580      if (common->partialmatchlabel != NULL)
1581        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1582      else
1583        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1584      }
1585    
1586    if (jump != NULL)
1587      JUMPHERE(jump);
1588    }
1589    
1590    static struct sljit_jump *check_str_end(compiler_common *common)
1591    {
1592    /* Does not affect registers. Usually used in a tight spot. */
1593    DEFINE_COMPILER;
1594    struct sljit_jump *jump;
1595    struct sljit_jump *nohit;
1596    struct sljit_jump *return_value;
1597    
1598    if (common->mode == JIT_COMPILE)
1599      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1600    
1601    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1602    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1603      {
1604      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1605      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1606      JUMPHERE(nohit);
1607      return_value = JUMP(SLJIT_JUMP);
1608      }
1609    else
1610      {
1611      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1612      if (common->partialmatchlabel != NULL)
1613        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1614      else
1615        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1616      }
1617    JUMPHERE(jump);
1618    return return_value;
1619  }  }
1620    
1621  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1622  {  {
1623  DEFINE_COMPILER;  DEFINE_COMPILER;
1624  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1625    
1626    if (common->mode == JIT_COMPILE)
1627      {
1628      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1629      return;
1630      }
1631    
1632    /* Partial matching mode. */
1633    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1634    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1635    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1636      {
1637      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1638      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1639      }
1640    else
1641      {
1642      if (common->partialmatchlabel != NULL)
1643        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1644      else
1645        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1646      }
1647    JUMPHERE(jump);
1648  }  }
1649    
1650  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1344  static void read_char(compiler_common *c Line 1652  static void read_char(compiler_common *c
1652  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1653  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1654  DEFINE_COMPILER;  DEFINE_COMPILER;
1655  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1656  struct sljit_jump *jump;  struct sljit_jump *jump;
1657  #endif  #endif
1658    
1659  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1660  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1661  if (common->utf8)  if (common->utf)
1662    {    {
1663    #ifdef COMPILE_PCRE8
1664    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1665    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1666    #ifdef COMPILE_PCRE16
1667      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1668    #endif
1669    #endif /* COMPILE_PCRE8 */
1670      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1671    JUMPHERE(jump);    JUMPHERE(jump);
1672    }    }
1673  #endif  #endif
1674  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));
1675  }  }
1676    
1677  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1365  static void peek_char(compiler_common *c Line 1679  static void peek_char(compiler_common *c
1679  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1680  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1681  DEFINE_COMPILER;  DEFINE_COMPILER;
1682  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1683  struct sljit_jump *jump;  struct sljit_jump *jump;
1684  #endif  #endif
1685    
1686  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1687  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1688  if (common->utf8)  if (common->utf)
1689    {    {
1690    #ifdef COMPILE_PCRE8
1691    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1692    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1693    #ifdef COMPILE_PCRE16
1694      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1695    #endif
1696    #endif /* COMPILE_PCRE8 */
1697      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1698    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1699    JUMPHERE(jump);    JUMPHERE(jump);
1700    }    }
# Line 1385  static void read_char8_type(compiler_com Line 1705  static void read_char8_type(compiler_com
1705  {  {
1706  /* 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. */
1707  DEFINE_COMPILER;  DEFINE_COMPILER;
1708  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1709  struct sljit_jump *jump;  struct sljit_jump *jump;
1710  #endif  #endif
1711    
1712  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1713  if (common->utf8)  if (common->utf)
1714    {    {
1715    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1716    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));
1717    #ifdef COMPILE_PCRE8
1718    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1719    it is a clever early read in most cases. */    it is needed in most cases. */
1720    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1721    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1722    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1723      JUMPHERE(jump);
1724    #else
1725    #ifdef COMPILE_PCRE16
1726      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1727      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1728      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1729    JUMPHERE(jump);    JUMPHERE(jump);
1730      /* Skip low surrogate if necessary. */
1731      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1732      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1733      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1734      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1735      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1736    #endif
1737    #endif /* COMPILE_PCRE8 */
1738    return;    return;
1739    }    }
1740  #endif  #endif
1741  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1742  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));
1743  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1744    /* The ctypes array contains only 256 values. */
1745    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1746    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1747    #endif
1748    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1749    #ifdef COMPILE_PCRE16
1750    JUMPHERE(jump);
1751    #endif
1752  }  }
1753    
1754  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1755  {  {
1756  /* 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. */
1757  DEFINE_COMPILER;  DEFINE_COMPILER;
1758  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1759  struct sljit_label *label;  struct sljit_label *label;
1760    
1761  if (common->utf8)  if (common->utf)
1762    {    {
1763    label = LABEL();    label = LABEL();
1764    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1765    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));
1766    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1767    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1768    return;    return;
1769    }    }
1770  #endif  #endif
1771  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1772    if (common->utf)
1773      {
1774      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1775      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1776      /* Skip low surrogate if necessary. */
1777      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1778      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1779      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1780      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1781      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1782      return;
1783      }
1784    #endif
1785    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1786  }  }
1787    
1788  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)  static void check_newlinechar(compiler_common *common, int nltype, jump_list **fallbacks, BOOL jumpiftrue)
# Line 1448  else if (nltype == NLTYPE_ANYCRLF) Line 1805  else if (nltype == NLTYPE_ANYCRLF)
1805    }    }
1806  else  else
1807    {    {
1808    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1809    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));
1810    }    }
1811  }  }
1812    
1813  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1814  static void do_utf8readchar(compiler_common *common)  
1815    #ifdef COMPILE_PCRE8
1816    static void do_utfreadchar(compiler_common *common)
1817  {  {
1818  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1819  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. */
1820  DEFINE_COMPILER;  DEFINE_COMPILER;
1821  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 1465  sljit_emit_fast_enter(compiler, RETURN_A Line 1824  sljit_emit_fast_enter(compiler, RETURN_A
1824  /* Searching for the first zero. */  /* Searching for the first zero. */
1825  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);
1826  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1827  /* 2 byte sequence */  /* Two byte sequence. */
1828  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1829  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));
1830  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1831  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1832  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1833  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1834  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1835  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1836  JUMPHERE(jump);  JUMPHERE(jump);
1837    
1838  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);
1839  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1840  /* 3 byte sequence */  /* Three byte sequence. */
1841  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1842  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1843  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1844  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1845  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1846  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1847  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1848  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));
1849  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1850  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1851  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1852  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1853  JUMPHERE(jump);  JUMPHERE(jump);
1854    
1855  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1856  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);  
1857  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1858  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1859  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1860  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1861  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1862  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);  
1863  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1864  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1865  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1866  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1867  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));
1868  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1869  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1870  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1871  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1872  }  }
1873    
1874  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1875  {  {
1876  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1877  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1878  DEFINE_COMPILER;  DEFINE_COMPILER;
1879  struct sljit_jump *jump;  struct sljit_jump *jump;
1880  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1549  sljit_emit_fast_enter(compiler, RETURN_A Line 1883  sljit_emit_fast_enter(compiler, RETURN_A
1883    
1884  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);
1885  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1886  /* 2 byte sequence */  /* Two byte sequence. */
1887  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1888  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));
1889  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1890  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1891  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1566  sljit_emit_fast_return(compiler, RETURN_ Line 1900  sljit_emit_fast_return(compiler, RETURN_
1900  JUMPHERE(jump);  JUMPHERE(jump);
1901    
1902  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1903  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);
1904  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1905  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1906  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1907  }  }
1908    
1909  #endif  #else /* COMPILE_PCRE8 */
1910    
1911    #ifdef COMPILE_PCRE16
1912    static void do_utfreadchar(compiler_common *common)
1913    {
1914    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1915    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1916    DEFINE_COMPILER;
1917    struct sljit_jump *jump;
1918    
1919    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1920    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1921    /* Do nothing, only return. */
1922    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1923    
1924    JUMPHERE(jump);
1925    /* Combine two 16 bit characters. */
1926    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1927    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1928    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1929    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1930    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1931    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1932    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1933    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1934    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1935    }
1936    #endif /* COMPILE_PCRE16 */
1937    
1938    #endif /* COMPILE_PCRE8 */
1939    
1940    #endif /* SUPPORT_UTF */
1941    
1942  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1943    
# Line 1590  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1955  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1955    
1956  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);
1957  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1958  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));
1959  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1960  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1961  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1962  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1963  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1964  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));
1965  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1966  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1967  }  }
# Line 1610  struct sljit_label *newlinelabel = NULL; Line 1975  struct sljit_label *newlinelabel = NULL;
1975  struct sljit_jump *start;  struct sljit_jump *start;
1976  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1977  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1978  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1979  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
1980  #endif  #endif
1981  jump_list *newline = NULL;  jump_list *newline = NULL;
1982  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1983  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1984    
1985  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1986      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1624  if (!(hascrorlf || firstline) && (common Line 1989  if (!(hascrorlf || firstline) && (common
1989  if (firstline)  if (firstline)
1990    {    {
1991    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1992      SLJIT_ASSERT(common->first_line_end != 0);
1993    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1994    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_END, 0);
1995    
1996    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1997      {      {
1998      mainloop = LABEL();      mainloop = LABEL();
1999      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));
2000      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2001      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2002      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
2003      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);
2004      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);
2005      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2006      }      }
2007    else    else
2008      {      {
2009      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2010      mainloop = LABEL();      mainloop = LABEL();
2011      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
2012      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2013      read_char(common);      read_char(common);
2014      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
2015      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
2016      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, STR_PTR, 0);
2017      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
2018      }      }
2019    
# Line 1660  start = JUMP(SLJIT_JUMP); Line 2026  start = JUMP(SLJIT_JUMP);
2026  if (newlinecheck)  if (newlinecheck)
2027    {    {
2028    newlinelabel = LABEL();    newlinelabel = LABEL();
2029    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));
2030    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2031    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2032    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);
2033    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2034    #ifdef COMPILE_PCRE16
2035      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2036    #endif
2037    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2038    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
2039    }    }
# Line 1672  if (newlinecheck) Line 2041  if (newlinecheck)
2041  mainloop = LABEL();  mainloop = LABEL();
2042    
2043  /* 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. */
2044  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2045  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
2046  #endif  #endif
2047  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
2048    
2049  if (readbyte)  if (readuchar)
2050    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2051    
2052  if (newlinecheck)  if (newlinecheck)
2053    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);
2054    
2055  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));
2056  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2057  if (common->utf8)  if (common->utf)
2058    {    {
2059    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
2060    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);
2061      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2062      JUMPHERE(singlechar);
2063      }
2064    #endif
2065    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2066    if (common->utf)
2067      {
2068      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
2069      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2070      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2071      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2072      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2073    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2074    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
2075    }    }
2076  #endif  #endif
2077  JUMPHERE(start);  JUMPHERE(start);
# Line 1704  if (newlinecheck) Line 2085  if (newlinecheck)
2085  return mainloop;  return mainloop;
2086  }  }
2087    
2088  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)
2089  {  {
2090  DEFINE_COMPILER;  DEFINE_COMPILER;
2091  struct sljit_label *start;  struct sljit_label *start;
2092  struct sljit_jump *leave;  struct sljit_jump *leave;
2093  struct sljit_jump *found;  struct sljit_jump *found;
2094  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2095    
2096  if (firstline)  if (firstline)
2097    {    {
2098    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2099    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2100    }    }
2101    
2102  start = LABEL();  start = LABEL();
2103  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2104  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2105    
2106  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2107    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2108      {
2109      oc = TABLE_GET(first_char, common->fcc, first_char);
2110    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2111      if (first_char > 127 && common->utf)
2112        oc = UCD_OTHERCASE(first_char);
2113    #endif
2114      }
2115    if (first_char == oc)
2116      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2117  else  else
2118    {    {
2119    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2120    if (ispowerof2(bit))    if (ispowerof2(bit))
2121      {      {
2122      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2123      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2124      }      }
2125    else    else
2126      {      {
2127      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);
2128      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2129      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);
2130      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
# Line 1744  else Line 2132  else
2132      }      }
2133    }    }
2134    
2135  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));
2136  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2137  if (common->utf8)  if (common->utf)
2138    {    {
2139    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2140    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);
2141      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2142      }
2143    #endif
2144    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2145    if (common->utf)
2146      {
2147      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2148      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2149      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2150      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2151      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2152    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2153    }    }
2154  #endif  #endif
# Line 1775  jump_list *newline = NULL; Line 2174  jump_list *newline = NULL;
2174  if (firstline)  if (firstline)
2175    {    {
2176    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2177    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2178    }    }
2179    
2180  if (common->nltype == NLTYPE_FIXED && common->newline > 255)  if (common->nltype == NLTYPE_FIXED && common->newline > 255)
# Line 1786  if (common->nltype == NLTYPE_FIXED && co Line 2185  if (common->nltype == NLTYPE_FIXED && co
2185    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));
2186    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2187    
2188    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2189    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);
2190    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2191    #ifdef COMPILE_PCRE16
2192      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2193    #endif
2194    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2195    
2196    loop = LABEL();    loop = LABEL();
2197    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));
2198    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2199    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2200    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2201    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);
2202    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);
2203    
# Line 1826  if (common->nltype == NLTYPE_ANY || comm Line 2228  if (common->nltype == NLTYPE_ANY || comm
2228    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2229    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2230    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2231    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2232    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);
2233    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2234    #ifdef COMPILE_PCRE16
2235      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2236    #endif
2237    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2238    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2239    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1846  DEFINE_COMPILER; Line 2251  DEFINE_COMPILER;
2251  struct sljit_label *start;  struct sljit_label *start;
2252  struct sljit_jump *leave;  struct sljit_jump *leave;
2253  struct sljit_jump *found;  struct sljit_jump *found;
2254    #ifndef COMPILE_PCRE8
2255    struct sljit_jump *jump;
2256    #endif
2257    
2258  if (firstline)  if (firstline)
2259    {    {
2260    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2261    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
2262    }    }
2263    
2264  start = LABEL();  start = LABEL();
2265  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2266  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2267  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2268  if (common->utf8)  if (common->utf)
2269    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2270  #endif  #endif
2271    #ifndef COMPILE_PCRE8
2272    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2273    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2274    JUMPHERE(jump);
2275    #endif
2276  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2277  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2278  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), start_bits);
# Line 1867  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2280  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2280  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);
2281  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2282    
2283  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2284  if (common->utf8)  if (common->utf)
2285    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2286  #endif  #endif
2287  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));
2288  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2289  if (common->utf8)  if (common->utf)
2290    {    {
2291    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2292    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);
2293      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2294      }
2295    #endif
2296    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2297    if (common->utf)
2298      {
2299      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2300      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2301      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2302      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2303      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2304    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2305    }    }
2306  #endif  #endif
# Line 1888  if (firstline) Line 2312  if (firstline)
2312    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2313  }  }
2314    
2315  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)
2316  {  {
2317  DEFINE_COMPILER;  DEFINE_COMPILER;
2318  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1897  struct sljit_jump *alreadyfound; Line 2321  struct sljit_jump *alreadyfound;
2321  struct sljit_jump *found;  struct sljit_jump *found;
2322  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2323  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2324  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2325    
2326  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2327    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2328  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);
2329  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2330  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2331    
2332  if (has_firstbyte)  if (has_firstchar)
2333    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2334  else  else
2335    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2336    
2337  loop = LABEL();  loop = LABEL();
2338  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2339    
2340  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2341  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2342    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2343      {
2344      oc = TABLE_GET(req_char, common->fcc, req_char);
2345    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2346      if (req_char > 127 && common->utf)
2347        oc = UCD_OTHERCASE(req_char);
2348    #endif
2349      }
2350    if (req_char == oc)
2351      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2352  else  else
2353    {    {
2354    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2355    if (ispowerof2(bit))    if (ispowerof2(bit))
2356      {      {
2357      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2358      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2359      }      }
2360    else    else
2361      {      {
2362      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2363      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2364      }      }
2365    }    }
2366  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2367  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2368    
2369  JUMPHERE(found);  JUMPHERE(found);
2370  if (foundoc)  if (foundoc)
2371    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2372  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, TMP1, 0);
2373  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2374  JUMPHERE(toolong);  JUMPHERE(toolong);
2375  return notfound;  return notfound;
# Line 1976  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 2408  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
2408  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
2409    
2410  JUMPHERE(jump);  JUMPHERE(jump);
2411    if (common->mark_ptr != 0)
2412      {
2413      jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmark);
2414      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2415      OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2416      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
2417      JUMPTO(SLJIT_JUMP, mainloop);
2418    
2419      JUMPHERE(jump);
2420      }
2421    
2422  /* Unknown command. */  /* Unknown command. */
2423  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2424  JUMPTO(SLJIT_JUMP, mainloop);  JUMPTO(SLJIT_JUMP, mainloop);
# Line 1984  JUMPTO(SLJIT_JUMP, mainloop); Line 2427  JUMPTO(SLJIT_JUMP, mainloop);
2427  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2428  {  {
2429  DEFINE_COMPILER;  DEFINE_COMPILER;
2430  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2431  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2432  struct sljit_jump *jump;  struct sljit_jump *jump;
2433  #endif  #endif
2434    
# Line 1996  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2439  sljit_emit_fast_enter(compiler, SLJIT_ME
2439  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2440  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));
2441  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2442  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2443  skip_char_back(common);  skip_char_back(common);
2444    check_start_used_ptr(common);
2445  read_char(common);  read_char(common);
2446    
2447  /* Testing char type. */  /* Testing char type. */
2448  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2449  if (common->useucp)  if (common->use_ucp)
2450    {    {
2451    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2452    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2019  if (common->useucp) Line 2463  if (common->useucp)
2463  else  else
2464  #endif  #endif
2465    {    {
2466  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2467      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2468    #elif defined SUPPORT_UTF
2469    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2470    jump = NULL;    jump = NULL;
2471    if (common->utf8)    if (common->utf)
2472      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2473  #endif  #endif /* COMPILE_PCRE8 */
2474    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2475    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2476    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2477    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2478  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2479      JUMPHERE(jump);
2480    #elif defined SUPPORT_UTF
2481    if (jump != NULL)    if (jump != NULL)
2482      JUMPHERE(jump);      JUMPHERE(jump);
2483  #endif  #endif /* COMPILE_PCRE8 */
2484    }    }
2485  JUMPHERE(beginend);  JUMPHERE(skipread);
2486    
2487  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2488  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2489  peek_char(common);  peek_char(common);
2490    
2491  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2492  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2493  if (common->useucp)  if (common->use_ucp)
2494    {    {
2495    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2496    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2058  if (common->useucp) Line 2506  if (common->useucp)
2506  else  else
2507  #endif  #endif
2508    {    {
2509  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2510      /* TMP2 may be destroyed by peek_char. */
2511      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2512      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2513    #elif defined SUPPORT_UTF
2514    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2515    jump = NULL;    jump = NULL;
2516    if (common->utf8)    if (common->utf)
2517      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2518  #endif  #endif
2519    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2520    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2521    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2522  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2523      JUMPHERE(jump);
2524    #elif defined SUPPORT_UTF
2525    if (jump != NULL)    if (jump != NULL)
2526      JUMPHERE(jump);      JUMPHERE(jump);
2527  #endif  #endif /* COMPILE_PCRE8 */
2528    }    }
2529  JUMPHERE(beginend);  JUMPHERE(skipread);
2530    
2531  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP2(SLJIT_XOR | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
2532  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
# Line 2089  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2543  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2543  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);
2544  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2545  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);
2546  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2547  if (common->utf8)  #ifdef COMPILE_PCRE8
2548    if (common->utf)
2549    {    {
2550    #endif
2551    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2552    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2553    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);
2554    #ifdef COMPILE_PCRE8
2555    }    }
2556  #endif  #endif
2557    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2558  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2559  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2560  }  }
# Line 2113  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2571  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2571  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);
2572  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2573  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);
2574  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2575  if (common->utf8)  #ifdef COMPILE_PCRE8
2576    if (common->utf)
2577    {    {
2578    #endif
2579    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2580    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);
2581    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2129  if (common->utf8) Line 2589  if (common->utf8)
2589    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);
2590    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2591    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);
2592    #ifdef COMPILE_PCRE8
2593    }    }
2594  #endif  #endif
2595    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2596  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2597    
2598  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2147  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2609  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2609  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);
2610  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2611  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);
2612  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2613  if (common->utf8)  #ifdef COMPILE_PCRE8
2614    if (common->utf)
2615    {    {
2616    #endif
2617    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2618    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2619    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);
2620    #ifdef COMPILE_PCRE8
2621    }    }
2622  #endif  #endif
2623    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2624  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2625    
2626  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2173  sljit_emit_fast_enter(compiler, RETURN_A Line 2639  sljit_emit_fast_enter(compiler, RETURN_A
2639  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2640  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2641  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2642  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2643  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));
2644    
2645  label = LABEL();  label = LABEL();
2646  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2647  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2648  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2649  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));
2650  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2651    
2652  JUMPHERE(jump);  JUMPHERE(jump);
2653  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));
2654  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2655  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2656  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2205  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2671  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2671  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2672  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2673  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2674  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2675  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));
2676    
2677  label = LABEL();  label = LABEL();
2678  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2679  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2680    #ifndef COMPILE_PCRE8
2681    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2682    #endif
2683  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2684    #ifndef COMPILE_PCRE8
2685    JUMPHERE(jump);
2686    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2687    #endif
2688  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2689    #ifndef COMPILE_PCRE8
2690    JUMPHERE(jump);
2691    #endif
2692  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2693  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));
2694  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2695    
2696  JUMPHERE(jump);  JUMPHERE(jump);
2697  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));
2698  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2699  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2700  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2229  sljit_emit_fast_return(compiler, RETURN_ Line 2705  sljit_emit_fast_return(compiler, RETURN_
2705  #undef CHAR1  #undef CHAR1
2706  #undef CHAR2  #undef CHAR2
2707    
2708  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2709    
2710  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)
2711  {  {
2712  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2713  int c1, c2;  int c1, c2;
2714  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->uchar_ptr;
2715  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2716    
2717  while (src1 < end1)  while (src1 < end1)
2718    {    {
2719    if (src2 >= end2)    if (src2 >= end2)
2720      return 0;      return (pcre_uchar*)1;
2721    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2722    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2723    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2724    }    }
2725  return src2;  return src2;
2726  }  }
2727    
2728  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2729    
2730  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,
2731      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2732  {  {
2733  DEFINE_COMPILER;  DEFINE_COMPILER;
2734  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2735  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2736  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2737  int utf8length;  int utflength;
2738  #endif  #endif
2739    
2740  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2268  if (caseless && char_has_othercase(commo Line 2742  if (caseless && char_has_othercase(commo
2742    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2743    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2744    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2745    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2746      othercasechar = cc + (othercasebit >> 8);
2747    othercasebit &= 0xff;    othercasebit &= 0xff;
2748    #else
2749    #ifdef COMPILE_PCRE16
2750      othercasechar = cc + (othercasebit >> 9);
2751      if ((othercasebit & 0x100) != 0)
2752        othercasebit = (othercasebit & 0xff) << 8;
2753      else
2754        othercasebit &= 0xff;
2755    #endif
2756    #endif
2757    }    }
2758    
2759  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2760    {    {
2761    #ifdef COMPILE_PCRE8
2762  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2763    if (context->length >= 4)    if (context->length >= 4)
2764      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2765    else if (context->length >= 2)    else if (context->length >= 2)
2766      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2767    else    else
2768  #endif  #endif
2769      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2770    #else
2771    #ifdef COMPILE_PCRE16
2772    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2773      if (context->length >= 4)
2774        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2775      else
2776    #endif
2777        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2778    #endif
2779    #endif /* COMPILE_PCRE8 */
2780    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2781    }    }
2782    
2783  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2784  utf8length = 1;  utflength = 1;
2785  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2786    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2787    
2788  do  do
2789    {    {
2790  #endif  #endif
2791    
2792    context->length--;    context->length -= IN_UCHARS(1);
2793  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2794    
2795    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2796    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2797      {      {
2798      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2799      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2800      }      }
2801    else    else
2802      {      {
2803      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2804      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2805      }      }
2806    context->byteptr++;    context->ucharptr++;
2807    
2808    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2809      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2810    #else
2811      if (context->ucharptr >= 2 || context->length == 0)
2812    #endif
2813      {      {
2814      if (context->length >= 4)      if (context->length >= 4)
2815        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);
2816    #ifdef COMPILE_PCRE8
2817      else if (context->length >= 2)      else if (context->length >= 2)
2818        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);
2819      else if (context->length >= 1)      else if (context->length >= 1)
2820        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);
2821    #else
2822        else if (context->length >= 2)
2823          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2824    #endif
2825      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2826    
2827      switch(context->byteptr)      switch(context->ucharptr)
2828        {        {
2829        case 4:        case 4 / sizeof(pcre_uchar):
2830        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2831          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);
2832        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));
2833        break;        break;
2834    
2835        case 2:        case 2 / sizeof(pcre_uchar):
2836        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2837          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);
2838        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));
2839        break;        break;
2840    
2841    #ifdef COMPILE_PCRE8
2842        case 1:        case 1:
2843        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2844          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);
2845        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));
2846        break;        break;
2847    #endif
2848    
2849        default:        default:
2850        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2851        break;        break;
2852        }        }
2853      context->byteptr = 0;      context->ucharptr = 0;
2854      }      }
2855    
2856  #else  #else
2857    
2858    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2859    #ifdef COMPILE_PCRE8
2860    if (context->length > 0)    if (context->length > 0)
2861      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);
2862    #else
2863      if (context->length > 0)
2864        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2865    #endif
2866    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2867    
2868    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2869      {      {
2870      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2871      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, context->sourcereg, 0, SLJIT_IMM, *cc | othercasebit));
# Line 2365  do Line 2876  do
2876  #endif  #endif
2877    
2878    cc++;    cc++;
2879  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2880    utf8length--;    utflength--;
2881    }    }
2882  while (utf8length > 0);  while (utflength > 0);
2883  #endif  #endif
2884    
2885  return cc;  return cc;
2886  }  }
2887    
2888  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2889    
2890  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2891    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2396  return cc; Line 2907  return cc;
2907      } \      } \
2908    charoffset = (value);    charoffset = (value);
2909    
2910  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)
2911  {  {
2912  DEFINE_COMPILER;  DEFINE_COMPILER;
2913  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2404  jump_list **list = (*cc & XCL_NOT) == 0 Line 2915  jump_list **list = (*cc & XCL_NOT) == 0
2915  unsigned int c;  unsigned int c;
2916  int compares;  int compares;
2917  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2918  uschar *ccbegin;  pcre_uchar *ccbegin;
2919  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2920  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2921  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2414  unsigned int typeoffset; Line 2925  unsigned int typeoffset;
2925  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2926  unsigned int charoffset;  unsigned int charoffset;
2927    
2928  /* 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. */
2929  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2930  read_char(common);  read_char(common);
2931    
2932  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2933    {    {
2934    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2935    if (common->utf8)  #ifndef COMPILE_PCRE8
2936      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2937    #elif defined SUPPORT_UTF
2938      if (common->utf)
2939      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2940    #endif
2941    
2942    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2943    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2431  if ((*cc++ & XCL_MAP) != 0) Line 2946  if ((*cc++ & XCL_MAP) != 0)
2946    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);
2947    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2948    
2949    if (common->utf8)  #ifndef COMPILE_PCRE8
2950      JUMPHERE(jump);
2951    #elif defined SUPPORT_UTF
2952      if (common->utf)
2953      JUMPHERE(jump);      JUMPHERE(jump);
2954    #endif
2955    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2956  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2957    charsaved = TRUE;    charsaved = TRUE;
2958  #endif  #endif
2959    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2960    }    }
2961    
2962  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2449  while (*cc != XCL_END) Line 2968  while (*cc != XCL_END)
2968    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2969      {      {
2970      cc += 2;      cc += 2;
2971  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2972      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]);
2973  #endif  #endif
2974  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2975      needschar = TRUE;      needschar = TRUE;
# Line 2459  while (*cc != XCL_END) Line 2978  while (*cc != XCL_END)
2978    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2979      {      {
2980      cc += 2;      cc += 2;
2981  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2982      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]);
2983  #endif  #endif
2984      cc++;      cc++;
2985  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2986      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]);
2987  #endif  #endif
2988  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2989      needschar = TRUE;      needschar = TRUE;
# Line 2534  if (needstype || needsscript) Line 3053  if (needstype || needsscript)
3053      {      {
3054      if (scriptreg == TMP1)      if (scriptreg == TMP1)
3055        {        {
3056        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));
3057        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
3058        }        }
3059      else      else
3060        {        {
3061        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
3062        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));
3063        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
3064        }        }
3065      }      }
# Line 2564  while (*cc != XCL_END) Line 3083  while (*cc != XCL_END)
3083    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
3084      {      {
3085      cc ++;      cc ++;
3086  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3087      if (common->utf8)      if (common->utf)
3088        {        {
3089        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3090        }        }
# Line 2595  while (*cc != XCL_END) Line 3114  while (*cc != XCL_END)
3114    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3115      {      {
3116      cc ++;      cc ++;
3117  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3118      if (common->utf8)      if (common->utf)
3119        {        {
3120        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3121        }        }
# Line 2604  while (*cc != XCL_END) Line 3123  while (*cc != XCL_END)
3123  #endif  #endif
3124        c = *cc++;        c = *cc++;
3125      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3126  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3127      if (common->utf8)      if (common->utf)
3128        {        {
3129        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3130        }        }
# Line 2661  while (*cc != XCL_END) Line 3180  while (*cc != XCL_END)
3180        break;        break;
3181    
3182        case PT_GC:        case PT_GC:
3183        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3184        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3185        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);
3186        break;        break;
3187    
3188        case PT_PC:        case PT_PC:
# Line 2725  if (found != NULL) Line 3244  if (found != NULL)
3244    
3245  #endif  #endif
3246    
3247  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)
3248  {  {
3249  DEFINE_COMPILER;  DEFINE_COMPILER;
3250  int length;  int length;
3251  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3252  compare_context context;  compare_context context;
3253  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3254  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3255  struct sljit_label *label;  struct sljit_label *label;
3256  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3257  uschar propdata[5];  pcre_uchar propdata[5];
3258  #endif  #endif
3259  #endif  #endif
3260    
# Line 2761  switch(type) Line 3280  switch(type)
3280    
3281    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3282    case OP_DIGIT:    case OP_DIGIT:
3283    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3284    read_char8_type(common);    read_char8_type(common);
3285    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit);
3286    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_DIGIT ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2769  switch(type) Line 3288  switch(type)
3288    
3289    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3290    case OP_WHITESPACE:    case OP_WHITESPACE:
3291    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3292    read_char8_type(common);    read_char8_type(common);
3293    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space);
3294    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WHITESPACE ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
# Line 2777  switch(type) Line 3296  switch(type)
3296    
3297    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3298    case OP_WORDCHAR:    case OP_WORDCHAR:
3299    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3300    read_char8_type(common);    read_char8_type(common);
3301    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);    OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word);
3302    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_WORDCHAR ? SLJIT_C_ZERO : SLJIT_C_NOT_ZERO));
3303    return cc;    return cc;
3304    
3305    case OP_ANY:    case OP_ANY:
3306    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3307    read_char(common);    read_char(common);
3308    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3309      {      {
3310      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);
3311      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3312      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3313        else
3314          jump[1] = check_str_end(common);
3315    
3316        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3317      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));
3318      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3319          JUMPHERE(jump[1]);
3320      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3321      }      }
3322    else    else
# Line 2800  switch(type) Line 3324  switch(type)
3324    return cc;    return cc;
3325    
3326    case OP_ALLANY:    case OP_ALLANY:
3327    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3328  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3329    if (common->utf8)    if (common->utf)
3330      {      {
3331      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3332      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));
3333    #ifdef COMPILE_PCRE8
3334      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3335      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);
3336      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3337    #else /* COMPILE_PCRE8 */
3338    #ifdef COMPILE_PCRE16
3339        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3340        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3341        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3342        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3343        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3344        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3345    #endif /* COMPILE_PCRE16 */
3346    #endif /* COMPILE_PCRE8 */
3347      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3348      return cc;      return cc;
3349      }      }
3350  #endif  #endif
3351    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));
3352    return cc;    return cc;
3353    
3354    case OP_ANYBYTE:    case OP_ANYBYTE:
3355    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3356    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));
3357    return cc;    return cc;
3358    
3359  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3360  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3361    case OP_NOTPROP:    case OP_NOTPROP:
3362    case OP_PROP:    case OP_PROP:
# Line 2836  switch(type) Line 3371  switch(type)
3371  #endif  #endif
3372    
3373    case OP_ANYNL:    case OP_ANYNL:
3374    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3375    read_char(common);    read_char(common);
3376    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);
3377    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3378    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3379        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3380      else
3381        jump[1] = check_str_end(common);
3382      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3383    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);
3384    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));
3385    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3386    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3387    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2853  switch(type) Line 3392  switch(type)
3392    
3393    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3394    case OP_HSPACE:    case OP_HSPACE:
3395    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3396    read_char(common);    read_char(common);
3397    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3398    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_HSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2861  switch(type) Line 3400  switch(type)
3400    
3401    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3402    case OP_VSPACE:    case OP_VSPACE:
3403    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3404    read_char(common);    read_char(common);
3405    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3406    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(type == OP_NOT_VSPACE ? SLJIT_C_NOT_ZERO : SLJIT_C_ZERO));
# Line 2869  switch(type) Line 3408  switch(type)
3408    
3409  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3410    case OP_EXTUNI:    case OP_EXTUNI:
3411    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3412    read_char(common);    read_char(common);
3413    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3414    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);    OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Mc);
# Line 2885  switch(type) Line 3424  switch(type)
3424    
3425    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3426    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3427      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3428        {
3429        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3430        /* Since we successfully read a char above, partial matching must occure. */
3431        check_partial(common, TRUE);
3432        JUMPHERE(jump[0]);
3433        }
3434    return cc;    return cc;
3435  #endif  #endif
3436    
3437    case OP_EODN:    case OP_EODN:
3438      /* Requires rather complex checks. */
3439    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);
3440    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3441      {      {
3442      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3443      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3444      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3445      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));
3446        else
3447          {
3448          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3449          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3450          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3451          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3452          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3453          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3454          check_partial(common, TRUE);
3455          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3456          JUMPHERE(jump[1]);
3457          }
3458        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3459      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));
3460      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));
3461      }      }
3462    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3463      {      {
3464      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3465      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3466      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));
3467      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));
3468      }      }
3469    else    else
3470      {      {
3471      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3472      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);
3473      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3474      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);
3475      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3476      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3477      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3478        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3479      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3480      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3481    
3482      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3483      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3484        {        {
3485        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3486        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));
3487        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));
3488        }        }
# Line 2938  switch(type) Line 3499  switch(type)
3499      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3500      }      }
3501    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3502      check_partial(common, FALSE);
3503    return cc;    return cc;
3504    
3505    case OP_EOD:    case OP_EOD:
3506    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, STR_PTR, 0, STR_END, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3507      check_partial(common, FALSE);
3508    return cc;    return cc;
3509    
3510    case OP_CIRC:    case OP_CIRC:
# Line 2961  switch(type) Line 3524  switch(type)
3524    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3525    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3526    
3527    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end));    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0));  
   
3528    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3529      {      {
3530      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3531      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3532      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3533      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3534      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));
3535      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));
3536      }      }
# Line 2990  switch(type) Line 3551  switch(type)
3551    if (!common->endonly)    if (!common->endonly)
3552      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3553    else    else
3554        {
3555      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0));
3556        check_partial(common, FALSE);
3557        }
3558    return cc;    return cc;
3559    
3560    case OP_DOLLM:    case OP_DOLLM:
# Line 2998  switch(type) Line 3562  switch(type)
3562    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3563    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, noteol));
3564    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3565      check_partial(common, FALSE);
3566    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3567    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3568    
3569    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3570      {      {
3571      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3572      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3573      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3574      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3575        else
3576          {
3577          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3578          /* STR_PTR = STR_END - IN_UCHARS(1) */
3579          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3580          check_partial(common, TRUE);
3581          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3582          JUMPHERE(jump[1]);
3583          }
3584    
3585        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3586      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));
3587      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));
3588      }      }
# Line 3021  switch(type) Line 3597  switch(type)
3597    case OP_CHAR:    case OP_CHAR:
3598    case OP_CHARI:    case OP_CHARI:
3599    length = 1;    length = 1;
3600  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3601    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3602  #endif  #endif
3603    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (common->mode == JIT_COMPILE && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0))
3604      {      {
3605      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));
3606      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));
3607    
3608      context.length = length;      context.length = IN_UCHARS(length);
3609      context.sourcereg = -1;      context.sourcereg = -1;
3610  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3611      context.byteptr = 0;      context.ucharptr = 0;
3612  #endif  #endif
3613      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3614      }      }
3615    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3616    read_char(common);    read_char(common);
3617  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3618    if (common->utf8)    if (common->utf)
3619      {      {
3620      GETCHAR(c, cc);      GETCHAR(c, cc);
3621      }      }
3622    else    else
3623  #endif  #endif
3624      c = *cc;      c = *cc;
3625      if (type == OP_CHAR || !char_has_othercase(common, cc))
3626        {
3627        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3628        return cc + length;
3629        }
3630      oc = char_othercase(common, c);
3631      bit = c ^ oc;
3632      if (ispowerof2(bit))
3633        {
3634        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3635        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3636        return cc + length;
3637        }
3638    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, c);
3639    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3640    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));    OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, char_othercase(common, c));
# Line 3055  switch(type) Line 3644  switch(type)
3644    
3645    case OP_NOT:    case OP_NOT:
3646    case OP_NOTI:    case OP_NOTI:
3647      fallback_at_str_end(common, fallbacks);
3648    length = 1;    length = 1;
3649  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3650    if (common->utf8)    if (common->utf)
3651      {      {
3652      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3653        c = *cc;
3654      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3655        {        {
3656        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3657        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
# Line 3076  switch(type) Line 3663  switch(type)
3663          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));
3664          }          }
3665        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3666        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));
3667        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3668        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);
3669        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3670        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
3671        return cc + length;        return cc + 1;
3672        }        }
3673      else      else
3674    #endif /* COMPILE_PCRE8 */
3675          {
3676          GETCHARLEN(c, cc, length);
3677        read_char(common);        read_char(common);
3678          }
3679      }      }
3680    else    else
3681  #endif  #endif /* SUPPORT_UTF */
3682      {      {
3683      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);  
3684      c = *cc;      c = *cc;
3685      }      }
3686    
# Line 3116  switch(type) Line 3705  switch(type)
3705    
3706    case OP_CLASS:    case OP_CLASS:
3707    case OP_NCLASS:    case OP_NCLASS:
3708    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3709    read_char(common);    read_char(common);
3710  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3711    jump[0] = NULL;    jump[0] = NULL;
3712    if (common->utf8)  #ifdef COMPILE_PCRE8
3713      /* This check only affects 8 bit mode. In other modes, we
3714      always need to compare the value with 255. */
3715      if (common->utf)
3716    #endif /* COMPILE_PCRE8 */
3717      {      {
3718      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3719      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3129  switch(type) Line 3722  switch(type)
3722        jump[0] = NULL;        jump[0] = NULL;
3723        }        }
3724      }      }
3725  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3726    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3727    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3728    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3729    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3730    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);
3731    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3732  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3733    if (jump[0] != NULL)    if (jump[0] != NULL)
3734      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3735  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3736    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3737    
3738  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3739    case OP_XCLASS:    case OP_XCLASS:
3740    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3741    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3152  switch(type) Line 3745  switch(type)
3745    length = GET(cc, 0);    length = GET(cc, 0);
3746    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3747    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3748    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3749  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3750      {      {
3751        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3752      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3753      label = LABEL();      label = LABEL();
3754      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));
3755      skip_char_back(common);      skip_char_back(common);
3756      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);
3757      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3758      }      }
3759      else
3760  #endif  #endif
3761    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3762    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3763        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3764        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3765        }
3766      check_start_used_ptr(common);
3767    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3768    }    }
3769  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3770  return cc;  return cc;
3771  }  }
3772    
3773  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)
3774  {  {
3775  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3776  /* 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. */
3777  DEFINE_COMPILER;  DEFINE_COMPILER;
3778  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3779  compare_context context;  compare_context context;
3780  int size;  int size;
3781    
# Line 3191  do Line 3788  do
3788    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3789      {      {
3790      size = 1;      size = 1;
3791  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3792      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3793        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3794  #endif  #endif
3795      }      }
3796    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3797      {      {
3798      size = 1;      size = 1;
3799  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3800      if (common->utf8)      if (common->utf)
3801        {        {
3802        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)
3803          size = 0;          size = 0;
3804        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3805          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3806        }        }
3807      else      else
3808  #endif  #endif
# Line 3216  do Line 3813  do
3813      size = 0;      size = 0;
3814    
3815    cc += 1 + size;    cc += 1 + size;
3816    context.length += size;    context.length += IN_UCHARS(size);
3817    }    }
3818  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3819    
# Line 3229  if (context.length > 0) Line 3826  if (context.length > 0)
3826    
3827    context.sourcereg = -1;    context.sourcereg = -1;
3828  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3829    context.byteptr = 0;    context.ucharptr = 0;
3830  #endif  #endif
3831    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);
3832    return cc;    return cc;
# Line 3239  if (context.length > 0) Line 3836  if (context.length > 0)
3836  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3837  }  }
3838    
3839  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)
3840  {  {
3841  DEFINE_COMPILER;  DEFINE_COMPILER;
3842  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3249  if (!common->jscript_compat) Line 3846  if (!common->jscript_compat)
3846    {    {
3847    if (fallbacks == NULL)    if (fallbacks == NULL)
3848      {      {
3849        /* OVECTOR(1) contains the "string begin - 1" constant. */
3850      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
3851      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3852      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3261  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3859  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3859  }  }
3860    
3861  /* Forward definitions. */  /* Forward definitions. */
3862  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3863  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3864    
3865  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3290  static void compile_fallbackpath(compile Line 3888  static void compile_fallbackpath(compile
3888      } \      } \
3889    while (0)    while (0)
3890    
3891  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3892    
3893  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)
3894  {  {
3895  DEFINE_COMPILER;  DEFINE_COMPILER;
3896  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3897  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3898    struct sljit_jump *partial;
3899    struct sljit_jump *nopartial;
3900    
3901  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3902    /* OVECTOR(1) contains the "string begin - 1" constant. */
3903  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3904    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)));
3905    
3906  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3907  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3908    {    {
3909    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);
3910    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 3314  if (common->utf8 && *cc == OP_REFI) Line 3914  if (common->utf8 && *cc == OP_REFI)
3914    /* Needed to save important temporary registers. */    /* Needed to save important temporary registers. */
3915    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3916    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3917    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, uchar_ptr), STR_PTR, 0);
3918    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));
3919    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3920    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3921        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3922      else
3923        {
3924        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3925        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3926        check_partial(common, FALSE);
3927        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3928        JUMPHERE(nopartial);
3929        }
3930    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3931    }    }
3932  else  else
3933  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3934    {    {
3935    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);
3936    if (withchecks)    if (withchecks)
3937      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3938    
3939    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3940      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3941      if (common->mode == JIT_COMPILE)
3942        add_jump(compiler, fallbacks, partial);
3943    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3944    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3945    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3946    
3947      if (common->mode != JIT_COMPILE)
3948        {
3949        nopartial = JUMP(SLJIT_JUMP);
3950        JUMPHERE(partial);
3951        /* TMP2 -= STR_END - STR_PTR */
3952        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3953        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3954        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3955        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3956        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3957        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3958        JUMPHERE(partial);
3959        check_partial(common, FALSE);
3960        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3961        JUMPHERE(nopartial);
3962        }
3963    }    }
3964    
3965  if (jump != NULL)  if (jump != NULL)
# Line 3341  if (jump != NULL) Line 3969  if (jump != NULL)
3969    else    else
3970      JUMPHERE(jump);      JUMPHERE(jump);
3971    }    }
3972  return cc + 3;  return cc + 1 + IMM2_SIZE;
3973  }  }
3974    
3975  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)
3976  {  {
3977  DEFINE_COMPILER;  DEFINE_COMPILER;
3978  fallback_common *fallback;  fallback_common *fallback;
3979  uschar type;  pcre_uchar type;
3980  struct sljit_label *label;  struct sljit_label *label;
3981  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3982  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3983  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3984  int min = 0, max = 0;  int min = 0, max = 0;
3985  BOOL minimize;  BOOL minimize;
3986    
3987  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3988    
3989  type = cc[3];  type = cc[1 + IMM2_SIZE];
3990  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3991  switch(type)  switch(type)
3992    {    {
# Line 3366  switch(type) Line 3994  switch(type)
3994    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3995    min = 0;    min = 0;
3996    max = 0;    max = 0;
3997    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3998    break;    break;
3999    case OP_CRPLUS:    case OP_CRPLUS:
4000    case OP_CRMINPLUS:    case OP_CRMINPLUS:
4001    min = 1;    min = 1;
4002    max = 0;    max = 0;
4003    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4004    break;    break;
4005    case OP_CRQUERY:    case OP_CRQUERY:
4006    case OP_CRMINQUERY:    case OP_CRMINQUERY:
4007    min = 0;    min = 0;
4008    max = 1;    max = 1;
4009    cc += 4;    cc += 1 + IMM2_SIZE + 1;
4010    break;    break;
4011    case OP_CRRANGE:    case OP_CRRANGE:
4012    case OP_CRMINRANGE:    case OP_CRMINRANGE:
4013    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
4014    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
4015    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
4016    break;    break;
4017    default:    default:
4018    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3488  decrease_call_count(common); Line 4116  decrease_call_count(common);
4116  return cc;  return cc;
4117  }  }
4118    
4119  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)
4120  {  {
4121  DEFINE_COMPILER;  DEFINE_COMPILER;
4122  fallback_common *fallback;  fallback_common *fallback;
# Line 3521  if (entry == NULL) Line 4149  if (entry == NULL)
4149      common->entries = entry;      common->entries = entry;
4150    }    }
4151    
4152  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  if (common->has_set_som && common->mark_ptr != 0)
4153  allocate_stack(common, 1);    {
4154  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
4155      allocate_stack(common, 2);
4156      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
4157      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4158      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP1, 0);
4159      }
4160    else if (common->has_set_som || common->mark_ptr != 0)
4161      {
4162      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr);
4163      allocate_stack(common, 1);
4164      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
4165      }
4166    
4167  if (entry->entry == NULL)  if (entry->entry == NULL)
4168    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &entry->calls, JUMP(SLJIT_FAST_CALL));
# Line 3534  add_jump(compiler, &fallback->topfallbac Line 4173  add_jump(compiler, &fallback->topfallbac
4173  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4174  }  }
4175    
4176  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)
4177  {  {
4178  DEFINE_COMPILER;  DEFINE_COMPILER;
4179  int framesize;  int framesize;
4180  int localptr;  int localptr;
4181  fallback_common altfallback;  fallback_common altfallback;
4182  uschar *ccbegin;  pcre_uchar *ccbegin;
4183  uschar opcode;  pcre_uchar opcode;
4184  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4185  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4186  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4187  jump_list **found;  jump_list **found;
# Line 3558  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4197  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4197    bra = *cc;    bra = *cc;
4198    cc++;    cc++;
4199    }    }
4200  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4201  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4202  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4203  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3804  common->accept = save_accept; Line 4443  common->accept = save_accept;
4443  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4444  }  }
4445    
4446  static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, uschar *name_table)  static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4447  {  {
4448  int condition = FALSE;  int condition = FALSE;
4449  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4450  uschar *slotB;  pcre_uchar *slotB;
4451  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4452  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4453  sljit_w no_capture;  sljit_w no_capture;
4454  int i;  int i;
4455    
4456  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4457    refno >>= 8;
4458  no_capture = locals[1];  no_capture = locals[1];
4459    
4460  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 3833  if (i < name_count) Line 4473  if (i < name_count)
4473    while (slotB > name_table)    while (slotB > name_table)
4474      {      {
4475      slotB -= name_entry_size;      slotB -= name_entry_size;
4476      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4477        {        {
4478        condition = locals[GET2(slotB, 0) << 1] != no_capture;        condition = locals[GET2(slotB, 0) << 1] != no_capture;
4479        if (condition) break;        if (condition) break;
# Line 3848  if (i < name_count) Line 4488  if (i < name_count)
4488      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4489        {        {
4490        slotB += name_entry_size;        slotB += name_entry_size;
4491        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4492          {          {
4493          condition = locals[GET2(slotB, 0) << 1] != no_capture;          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4494          if (condition) break;          if (condition) break;
# Line 3860  if (i < name_count) Line 4500  if (i < name_count)
4500  return condition;  return condition;
4501  }  }
4502    
4503  static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, uschar *name_table)  static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4504  {  {
4505  int condition = FALSE;  int condition = FALSE;
4506  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4507  uschar *slotB;  pcre_uchar *slotB;
4508  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4509  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4510  sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];  sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
# Line 3886  if (i < name_count) Line 4526  if (i < name_count)
4526    while (slotB > name_table)    while (slotB > name_table)
4527      {      {
4528      slotB -= name_entry_size;      slotB -= name_entry_size;
4529      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4530        {        {
4531        condition = GET2(slotB, 0) == group_num;        condition = GET2(slotB, 0) == group_num;
4532        if (condition) break;        if (condition) break;
# Line 3901  if (i < name_count) Line 4541  if (i < name_count)
4541      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4542        {        {
4543        slotB += name_entry_size;        slotB += name_entry_size;
4544        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4545          {          {
4546          condition = GET2(slotB, 0) == group_num;          condition = GET2(slotB, 0) == group_num;
4547          if (condition) break;          if (condition) break;
# Line 3967  return condition; Line 4607  return condition;
4607                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
4608  */  */
4609    
4610  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)
4611  {  {
4612  DEFINE_COMPILER;  DEFINE_COMPILER;
4613  fallback_common *fallback;  fallback_common *fallback;
4614  uschar opcode;  pcre_uchar opcode;
4615  int localptr = 0;  int localptr = 0;
4616  int offset = 0;  int offset = 0;
4617  int stacksize;  int stacksize;
4618  uschar *ccbegin;  pcre_uchar *ccbegin;
4619  uschar *hotpath;  pcre_uchar *hotpath;
4620  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4621  uschar ket;  pcre_uchar ket;
4622  assert_fallback *assert;  assert_fallback *assert;
4623  BOOL has_alternatives;  BOOL has_alternatives;
4624  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 4039  if (opcode == OP_CBRA || opcode == OP_SC Line 4679  if (opcode == OP_CBRA || opcode == OP_SC
4679    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4680    offset <<= 1;    offset <<= 1;
4681    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4682    hotpath += 2;    hotpath += IMM2_SIZE;
4683    }    }
4684  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4685    {    {
4686    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4687    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4688    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4689    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4690    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4203  if (opcode == OP_COND || opcode == OP_SC Line 4843  if (opcode == OP_COND || opcode == OP_SC
4843      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
4844      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4845        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)));
4846      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4847      }      }
4848    else if (*hotpath == OP_NCREF)    else if (*hotpath == OP_NCREF)
4849      {      {
# Line 4214  if (opcode == OP_COND || opcode == OP_SC Line 4854  if (opcode == OP_COND || opcode == OP_SC
4854      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4855      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4856      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4857      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, (stacksize << 8) | (common->ovector_start / sizeof(sljit_w)));
4858      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4859      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4860      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));      sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
# Line 4222  if (opcode == OP_COND || opcode == OP_SC Line 4862  if (opcode == OP_COND || opcode == OP_SC
4862      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4863    
4864      JUMPHERE(jump);      JUMPHERE(jump);
4865      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4866      }      }
4867    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4868      {      {
# Line 4243  if (opcode == OP_COND || opcode == OP_SC Line 4883  if (opcode == OP_COND || opcode == OP_SC
4883        {        {
4884        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
4885        if (stacksize != 0)        if (stacksize != 0)
4886          hotpath += 3;          hotpath += 1 + IMM2_SIZE;
4887        else        else
4888          {          {
4889          if (*cc == OP_ALT)          if (*cc == OP_ALT)
# Line 4270  if (opcode == OP_COND || opcode == OP_SC Line 4910  if (opcode == OP_COND || opcode == OP_SC
4910        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4911        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4912        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4913        hotpath += 3;        hotpath += 1 + IMM2_SIZE;
4914        }        }
4915      }      }
4916    else    else
# Line 4378  if (bra == OP_BRAZERO) Line 5018  if (bra == OP_BRAZERO)
5018  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
5019    {    {
5020    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
5021    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
5022    if (braminzerojump != NULL)    if (braminzerojump != NULL)
5023      {      {
5024      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4406  cc += 1 + LINK_SIZE; Line 5046  cc += 1 + LINK_SIZE;
5046  return cc;  return cc;
5047  }  }
5048    
5049  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)
5050  {  {
5051  DEFINE_COMPILER;  DEFINE_COMPILER;
5052  fallback_common *fallback;  fallback_common *fallback;
5053  uschar opcode;  pcre_uchar opcode;
5054  int localptr;  int localptr;
5055  int cbraprivptr = 0;  int cbraprivptr = 0;
5056  int framesize;  int framesize;
5057  int stacksize;  int stacksize;
5058  int offset = 0;  int offset = 0;
5059  BOOL zero = FALSE;  BOOL zero = FALSE;
5060  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
5061  int stack;  int stack;
5062  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
5063  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4430  if (*cc == OP_BRAPOSZERO) Line 5070  if (*cc == OP_BRAPOSZERO)
5070    }    }
5071    
5072  opcode = *cc;  opcode = *cc;
5073  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
5074  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
5075  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
5076  switch(opcode)  switch(opcode)
# Line 4445  switch(opcode) Line 5085  switch(opcode)
5085    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
5086    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
5087    offset <<= 1;    offset <<= 1;
5088    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
5089    break;    break;
5090    
5091    default:    default:
# Line 4624  decrease_call_count(common); Line 5264  decrease_call_count(common);
5264  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5265  }  }
5266    
5267  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)
5268  {  {
5269  int class_len;  int class_len;
5270    
# Line 4663  else Line 5303  else
5303    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5304    *type = *opcode;    *type = *opcode;
5305    cc++;    cc++;
5306    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5307    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5308    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5309      {      {
# Line 4674  else Line 5314  else
5314    else    else
5315      {      {
5316      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
5317      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
5318      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
5319    
5320      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4686  else Line 5326  else
5326        *opcode = OP_EXACT;        *opcode = OP_EXACT;
5327    
5328      if (end != NULL)      if (end != NULL)
5329        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
5330      }      }
5331    return cc;    return cc;
5332    }    }
# Line 4694  else Line 5334  else
5334  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)
5335    {    {
5336    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
5337    cc += 2;    cc += IMM2_SIZE;
5338    }    }
5339    
5340  if (*type == 0)  if (*type == 0)
# Line 4709  if (*type == 0) Line 5349  if (*type == 0)
5349  if (end != NULL)  if (end != NULL)
5350    {    {
5351    *end = cc + 1;    *end = cc + 1;
5352  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5353    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
5354  #endif  #endif
5355    }    }
5356  return cc;  return cc;
5357  }  }
5358    
5359  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)
5360  {  {
5361  DEFINE_COMPILER;  DEFINE_COMPILER;
5362  fallback_common *fallback;  fallback_common *fallback;
5363  uschar opcode;  pcre_uchar opcode;
5364  uschar type;  pcre_uchar type;
5365  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5366  uschar* end;  pcre_uchar* end;
5367  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
5368  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5369  struct sljit_label *label;  struct sljit_label *label;
# Line 4885  decrease_call_count(common); Line 5525  decrease_call_count(common);
5525  return end;  return end;
5526  }  }
5527    
5528  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)
5529  {  {
5530  DEFINE_COMPILER;  DEFINE_COMPILER;
5531  fallback_common *fallback;  fallback_common *fallback;
# Line 4929  add_jump(compiler, &fallback->topfallbac Line 5569  add_jump(compiler, &fallback->topfallbac
5569  return cc + 1;  return cc + 1;
5570  }  }
5571    
5572  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)
5573  {  {
5574  DEFINE_COMPILER;  DEFINE_COMPILER;
5575  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5576    
5577  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5578  if (common->currententry != NULL)  if (common->currententry != NULL)
5579    return cc + 3;    return cc + 1 + IMM2_SIZE;
5580    
5581  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));
5582  offset <<= 1;  offset <<= 1;
5583  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);
5584  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5585  return cc + 3;  return cc + 1 + IMM2_SIZE;
5586  }  }
5587    
5588  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)
5589  {  {
5590  DEFINE_COMPILER;  DEFINE_COMPILER;
5591  fallback_common *fallback;  fallback_common *fallback;
# Line 4989  while (cc < ccend) Line 5629  while (cc < ccend)
5629    
5630      case OP_SET_SOM:      case OP_SET_SOM:
5631      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);      PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5632        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
5633      allocate_stack(common, 1);      allocate_stack(common, 1);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
5634      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);
5635      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5636      cc++;      cc++;
5637      break;      break;
5638    
5639      case OP_CHAR:      case OP_CHAR:
5640      case OP_CHARI:      case OP_CHARI:
5641      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5642          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5643        else
5644          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5645      break;      break;
5646    
5647      case OP_STAR:      case OP_STAR:
# Line 5071  while (cc < ccend) Line 5714  while (cc < ccend)
5714    
5715      case OP_CLASS:      case OP_CLASS:
5716      case OP_NCLASS:      case OP_NCLASS:
5717      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)
5718        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5719      else      else
5720        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);
5721      break;      break;
5722    
5723  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5724      case OP_XCLASS:      case OP_XCLASS:
5725      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)
5726        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 5088  while (cc < ccend) Line 5731  while (cc < ccend)
5731    
5732      case OP_REF:      case OP_REF:
5733      case OP_REFI:      case OP_REFI:
5734      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5735        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5736      else      else
5737        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 5154  while (cc < ccend) Line 5797  while (cc < ccend)
5797      cc = compile_bracketpos_hotpath(common, cc, parent);      cc = compile_bracketpos_hotpath(common, cc, parent);
5798      break;      break;
5799    
5800        case OP_MARK:
5801        PUSH_FALLBACK_NOVALUE(sizeof(fallback_common), cc);
5802        SLJIT_ASSERT(common->mark_ptr != 0);
5803        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr);
5804        allocate_stack(common, 1);
5805        OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
5806        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0);
5807        OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)(cc + 2));
5808        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP2, 0);
5809        OP1(SLJIT_MOV, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, mark_ptr), TMP2, 0);
5810        cc += 1 + 2 + cc[1];
5811        break;
5812    
5813      case OP_FAIL:      case OP_FAIL:
5814      case OP_ACCEPT:      case OP_ACCEPT:
5815      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 5191  SLJIT_ASSERT(cc == ccend); Line 5847  SLJIT_ASSERT(cc == ccend);
5847      } \      } \
5848    while (0)    while (0)
5849    
5850  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5851    
5852  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5853  {  {
5854  DEFINE_COMPILER;  DEFINE_COMPILER;
5855  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5856  uschar opcode;  pcre_uchar opcode;
5857  uschar type;  pcre_uchar type;
5858  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5859  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5860  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5323  switch(opcode) Line 5979  switch(opcode)
5979  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)
5980  {  {
5981  DEFINE_COMPILER;  DEFINE_COMPILER;
5982  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5983  uschar type;  pcre_uchar type;
5984    
5985  type = cc[3];  type = cc[1 + IMM2_SIZE];
5986  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5987    {    {
5988    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5347  static void compile_recurse_fallbackpath Line 6003  static void compile_recurse_fallbackpath
6003  DEFINE_COMPILER;  DEFINE_COMPILER;
6004    
6005  set_jumps(current->topfallbacks, LABEL());  set_jumps(current->topfallbacks, LABEL());
6006  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
6007  free_stack(common, 1);  if (common->has_set_som && common->mark_ptr != 0)
6008  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);    {
6009      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6010      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6011      free_stack(common, 2);
6012      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
6013      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6014      }
6015    else if (common->has_set_som || common->mark_ptr != 0)
6016      {
6017      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6018      free_stack(common, 1);
6019      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->has_set_som ? (OVECTOR(0)) : common->mark_ptr, TMP2, 0);
6020      }
6021  }  }
6022    
6023  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
6024  {  {
6025  DEFINE_COMPILER;  DEFINE_COMPILER;
6026  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
6027  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6028  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
6029    
6030  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5427  int offset = 0; Line 6095  int offset = 0;
6095  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
6096  int stacksize;  int stacksize;
6097  int count;  int count;
6098  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
6099  uschar *ccbegin;  pcre_uchar *ccbegin;
6100  uschar *ccprev;  pcre_uchar *ccprev;
6101  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
6102  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
6103  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
6104  uschar ket;  pcre_uchar ket;
6105  assert_fallback *assert;  assert_fallback *assert;
6106  BOOL has_alternatives;  BOOL has_alternatives;
6107  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
# Line 5933  while (current) Line 6601  while (current)
6601      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6602      case OP_CLASS:      case OP_CLASS:
6603      case OP_NCLASS:      case OP_NCLASS:
6604    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6605      case OP_XCLASS:      case OP_XCLASS:
6606    #endif
6607      compile_iterator_fallbackpath(common, current);      compile_iterator_fallbackpath(common, current);
6608      break;      break;
6609    
# Line 5983  while (current) Line 6653  while (current)
6653      compile_braminzero_fallbackpath(common, current);      compile_braminzero_fallbackpath(common, current);
6654      break;      break;
6655    
6656        case OP_MARK:
6657        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6658        free_stack(common, 1);
6659        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->mark_ptr, TMP1, 0);
6660        break;
6661    
6662      case OP_FAIL:      case OP_FAIL:
6663      case OP_ACCEPT:      case OP_ACCEPT:
6664      case OP_ASSERT_ACCEPT:      case OP_ASSERT_ACCEPT:
# Line 6000  while (current) Line 6676  while (current)
6676  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
6677  {  {
6678  DEFINE_COMPILER;  DEFINE_COMPILER;
6679  uschar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
6680  uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6681  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
6682  int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
6683  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6684  int alternativesize;  int alternativesize;
# Line 6016  if (!needsframe) Line 6692  if (!needsframe)
6692    framesize = 0;    framesize = 0;
6693  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6694    
6695  SLJIT_ASSERT(common->currententry->entry == NULL);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6696  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6697  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6698    
# Line 6024  sljit_emit_fast_enter(compiler, TMP2, 0, Line 6700  sljit_emit_fast_enter(compiler, TMP2, 0,
6700  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6701  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(localsize + framesize + alternativesize - 1), TMP2, 0);
6702  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6703  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, STACK_TOP, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, STACK_TOP, 0);
6704  if (needsframe)  if (needsframe)
6705    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, TRUE);
6706    
6707  if (alternativesize > 0)  if (alternativesize > 0)
6708    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 6066  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 6742  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6742  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6743    
6744  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
6745  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD);  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head);
6746  if (needsframe)  if (needsframe)
6747    {    {
   OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  
6748    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
6749    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
6750    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));    OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, (framesize + alternativesize) * sizeof(sljit_w));
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP3, 0);  
6751    }    }
6752  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 1);
6753    
# Line 6082  copy_locals(common, ccbegin, ccend, FALS Line 6756  copy_locals(common, ccbegin, ccend, FALS
6756  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, localsize + framesize + alternativesize);
6757  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6758  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6759  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), RECURSIVE_HEAD, TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->recursive_head, TMP2, 0);
6760  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6761  }  }
6762    
# Line 6090  sljit_emit_fast_return(compiler, SLJIT_M Line 6764  sljit_emit_fast_return(compiler, SLJIT_M
6764  #undef CURRENT_AS  #undef CURRENT_AS
6765    
6766  void  void
6767  _pcre_jit_compile(const real_pcre *re, pcre_extra *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)