/[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 924 by zherczeg, Wed Feb 22 10:23:56 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55  #define SLJIT_MALLOC(size) (pcre_malloc)(size)  #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56  #define SLJIT_FREE(ptr) (pcre_free)(ptr)  #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58  #define SLJIT_CONFIG_STATIC 1  #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
# Line 62  system files. */ Line 62  system files. */
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 148  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_functions {
166    void *executable_func;    void *executable_funcs[JIT_NUMBER_OF_COMPILE_MODES];
167    pcre_jit_callback callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169    sljit_uw executable_size;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170  } executable_function;  } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 198  typedef struct fallback_common { Line 198  typedef struct fallback_common {
198    struct fallback_common *top;    struct fallback_common *top;
199    jump_list *topfallbacks;    jump_list *topfallbacks;
200    /* Opcode pointer. */    /* Opcode pointer. */
201    uschar *cc;    pcre_uchar *cc;
202  } fallback_common;  } fallback_common;
203    
204  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 269  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
269    
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    uschar *start;    pcre_uchar *start;
273    
274      /* Local stack area size and variable pointers. */
275    int localsize;    int localsize;
276    int *localptrs;    int *localptrs;
   const uschar *fcc;  
   sljit_w lcc;  
277    int cbraptr;    int cbraptr;
278      /* OVector starting point. Must be divisible by 2. */
279      int ovector_start;
280      /* Last known position of the requested byte. */
281      int req_char_ptr;
282      /* Head of the last recursion. */
283      int recursive_head;
284      /* First inspected character for partial matching. */
285      int start_used_ptr;
286      /* Starting pointer for partial soft matches. */
287      int hit_start;
288      /* End pointer of the first line. */
289      int first_line_end;
290    
291      /* Other  */
292      const pcre_uint8 *fcc;
293      sljit_w lcc;
294      int mode;
295    int nltype;    int nltype;
296    int newline;    int newline;
297    int bsr_nltype;    int bsr_nltype;
# Line 283  typedef struct compiler_common { Line 300  typedef struct compiler_common {
300    sljit_uw name_table;    sljit_uw name_table;
301    sljit_w name_count;    sljit_w name_count;
302    sljit_w name_entry_size;    sljit_w name_entry_size;
303    
304      /* Labels and jump lists. */
305      struct sljit_label *partialmatchlabel;
306    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
307    stub_list *stubs;    stub_list *stubs;
308    recurse_entry *entries;    recurse_entry *entries;
309    recurse_entry *currententry;    recurse_entry *currententry;
310      jump_list *partialmatch;
311    jump_list *accept;    jump_list *accept;
312    jump_list *calllimit;    jump_list *calllimit;
313    jump_list *stackalloc;    jump_list *stackalloc;
# Line 298  typedef struct compiler_common { Line 319  typedef struct compiler_common {
319    jump_list *casefulcmp;    jump_list *casefulcmp;
320    jump_list *caselesscmp;    jump_list *caselesscmp;
321    BOOL jscript_compat;    BOOL jscript_compat;
322  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
323    BOOL utf8;    BOOL utf;
324  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
325    BOOL useucp;    BOOL use_ucp;
326  #endif  #endif
327    jump_list *utf8readchar;    jump_list *utfreadchar;
328    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
329      jump_list *utfreadtype8;
330  #endif  #endif
331    #endif /* SUPPORT_UTF */
332  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
333    jump_list *getucd;    jump_list *getucd;
334  #endif  #endif
# Line 317  typedef struct compare_context { Line 340  typedef struct compare_context {
340    int length;    int length;
341    int sourcereg;    int sourcereg;
342  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
343    int byteptr;    int ucharptr;
344    union {    union {
345      int asint;      sljit_i asint;
346      short asshort;      sljit_uh asushort;
347    #ifdef COMPILE_PCRE8
348      sljit_ub asbyte;      sljit_ub asbyte;
349      sljit_ub asbytes[4];      sljit_ub asuchars[4];
350    #else
351    #ifdef COMPILE_PCRE16
352        sljit_uh asuchars[2];
353    #endif
354    #endif
355    } c;    } c;
356    union {    union {
357      int asint;      sljit_i asint;
358      short asshort;      sljit_uh asushort;
359    #ifdef COMPILE_PCRE8
360      sljit_ub asbyte;      sljit_ub asbyte;
361      sljit_ub asbytes[4];      sljit_ub asuchars[4];
362    #else
363    #ifdef COMPILE_PCRE16
364        sljit_uh asuchars[2];
365    #endif
366    #endif
367    } oc;    } oc;
368  #endif  #endif
369  } compare_context;  } compare_context;
# Line 338  enum { Line 373  enum {
373    frame_setstrbegin = -1    frame_setstrbegin = -1
374  };  };
375    
376    /* Undefine sljit macros. */
377    #undef CMP
378    
379  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
380  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
381    
382  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
383  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
384  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
385  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
386  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
387  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
388  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
389  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
390  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
391  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
392    
393  /* Locals layout. */  /* Locals layout. */
# Line 359  enum { Line 397  enum {
397  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
398  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
399  #define POSSESSIVE1      (3 * sizeof(sljit_w))  #define POSSESSIVE1      (3 * sizeof(sljit_w))
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))  
400  /* Max limit of recursions. */  /* Max limit of recursions. */
401  #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))  
402  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
403  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
404  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
405  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. */
406  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (common->ovector_start)
407  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
408  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
409  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
410    
411    #ifdef COMPILE_PCRE8
412    #define MOV_UCHAR  SLJIT_MOV_UB
413    #define MOVU_UCHAR SLJIT_MOVU_UB
414    #else
415    #ifdef COMPILE_PCRE16
416    #define MOV_UCHAR  SLJIT_MOV_UH
417    #define MOVU_UCHAR SLJIT_MOVU_UH
418    #else
419    #error Unsupported compiling mode
420    #endif
421    #endif
422    
423  /* Shortcuts. */  /* Shortcuts. */
424  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 398  the start pointers when the end of the c Line 442  the start pointers when the end of the c
442  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
443    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
444    
445  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
446  {  {
447  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));
448  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 419  return cc; Line 463  return cc;
463   compile_fallbackpath   compile_fallbackpath
464  */  */
465    
466  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
467  {  {
468  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
469  switch(*cc)  switch(*cc)
# Line 475  switch(*cc) Line 519  switch(*cc)
519    return cc + 1;    return cc + 1;
520    
521    case OP_ANYBYTE:    case OP_ANYBYTE:
522  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
523    if (common->utf8) return NULL;    if (common->utf) return NULL;
524  #endif  #endif
525    return cc + 1;    return cc + 1;
526    
# Line 484  switch(*cc) Line 528  switch(*cc)
528    case OP_CHARI:    case OP_CHARI:
529    case OP_NOT:    case OP_NOT:
530    case OP_NOTI:    case OP_NOTI:
   
531    case OP_STAR:    case OP_STAR:
532    case OP_MINSTAR:    case OP_MINSTAR:
533    case OP_PLUS:    case OP_PLUS:
# Line 522  switch(*cc) Line 565  switch(*cc)
565    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
566    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
567    cc += 2;    cc += 2;
568  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
569    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]);
570  #endif  #endif
571    return cc;    return cc;
572    
# Line 543  switch(*cc) Line 586  switch(*cc)
586    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
587    case OP_NOTEXACTI:    case OP_NOTEXACTI:
588    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
589    cc += 4;    cc += 2 + IMM2_SIZE;
590  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
591    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]);
592  #endif  #endif
593    return cc;    return cc;
594    
595    case OP_NOTPROP:    case OP_NOTPROP:
596    case OP_PROP:    case OP_PROP:
597      return cc + 1 + 2;
598    
599    case OP_TYPEUPTO:    case OP_TYPEUPTO:
600    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
601    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 562  switch(*cc) Line 607  switch(*cc)
607    case OP_RREF:    case OP_RREF:
608    case OP_NRREF:    case OP_NRREF:
609    case OP_CLOSE:    case OP_CLOSE:
610    cc += 3;    cc += 1 + IMM2_SIZE;
611    return cc;    return cc;
612    
613    case OP_CRRANGE:    case OP_CRRANGE:
614    case OP_CRMINRANGE:    case OP_CRMINRANGE:
615    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
616    
617    case OP_CLASS:    case OP_CLASS:
618    case OP_NCLASS:    case OP_NCLASS:
619    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
620    
621  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
622    case OP_XCLASS:    case OP_XCLASS:
623    return cc + GET(cc, 1);    return cc + GET(cc, 1);
624  #endif  #endif
# Line 603  switch(*cc) Line 648  switch(*cc)
648    case OP_CBRAPOS:    case OP_CBRAPOS:
649    case OP_SCBRA:    case OP_SCBRA:
650    case OP_SCBRAPOS:    case OP_SCBRAPOS:
651    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
652    
653    default:    default:
654    return NULL;    return NULL;
655    }    }
656  }  }
657    
658  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
659  {  {
660  int localspace = 0;  int localspace = 0;
661  uschar *alternative;  pcre_uchar *alternative;
662  /* 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. */
663  while (cc < ccend)  while (cc < ccend)
664    {    {
# Line 636  while (cc < ccend) Line 681  while (cc < ccend)
681      case OP_CBRAPOS:      case OP_CBRAPOS:
682      case OP_SCBRAPOS:      case OP_SCBRAPOS:
683      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
684      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
685      break;      break;
686    
687      case OP_COND:      case OP_COND:
# Line 647  while (cc < ccend) Line 692  while (cc < ccend)
692      cc += 1 + LINK_SIZE;      cc += 1 + LINK_SIZE;
693      break;      break;
694    
695        case OP_RECURSE:
696        /* Set its value only once. */
697        if (common->recursive_head == 0)
698          {
699          common->recursive_head = common->ovector_start;
700          common->ovector_start += sizeof(sljit_w);
701          }
702        cc += 1 + LINK_SIZE;
703        break;
704    
705      default:      default:
706      cc = next_opcode(common, cc);      cc = next_opcode(common, cc);
707      if (cc == NULL)      if (cc == NULL)
# Line 657  while (cc < ccend) Line 712  while (cc < ccend)
712  return localspace;  return localspace;
713  }  }
714    
715  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
716  {  {
717  uschar *cc = common->start;  pcre_uchar *cc = common->start;
718  uschar *alternative;  pcre_uchar *alternative;
719  while (cc < ccend)  while (cc < ccend)
720    {    {
721    switch(*cc)    switch(*cc)
# Line 684  while (cc < ccend) Line 739  while (cc < ccend)
739      case OP_SCBRAPOS:      case OP_SCBRAPOS:
740      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
741      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
742      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
743      break;      break;
744    
745      case OP_COND:      case OP_COND:
# Line 707  while (cc < ccend) Line 762  while (cc < ccend)
762  }  }
763    
764  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
765  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
766  {  {
767  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
768  int length = 0;  int length = 0;
769  BOOL possessive = FALSE;  BOOL possessive = FALSE;
770  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
# Line 740  while (cc < ccend) Line 795  while (cc < ccend)
795      case OP_SCBRA:      case OP_SCBRA:
796      case OP_SCBRAPOS:      case OP_SCBRAPOS:
797      length += 3;      length += 3;
798      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
799      break;      break;
800    
801      default:      default:
# Line 758  if (length > 0) Line 813  if (length > 0)
813  return -1;  return -1;
814  }  }
815    
816  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)
817  {  {
818  DEFINE_COMPILER;  DEFINE_COMPILER;
819  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
820  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
821  int offset;  int offset;
822    
823  /* >= 1 + shortest item size (2) */  /* >= 1 + shortest item size (2) */
824    SLJIT_UNUSED_ARG(stacktop);
825  SLJIT_ASSERT(stackpos >= stacktop + 2);  SLJIT_ASSERT(stackpos >= stacktop + 2);
826    
827  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
# Line 803  while (cc < ccend) Line 859  while (cc < ccend)
859      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
860      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
861    
862      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
863      break;      break;
864    
865      default:      default:
# Line 816  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st Line 872  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), st
872  SLJIT_ASSERT(stackpos == STACK(stacktop));  SLJIT_ASSERT(stackpos == STACK(stacktop));
873  }  }
874    
875  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)
876  {  {
877  int localsize = 2;  int localsize = 2;
878  uschar *alternative;  pcre_uchar *alternative;
879  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
880  while (cc < ccend)  while (cc < ccend)
881    {    {
# Line 842  while (cc < ccend) Line 898  while (cc < ccend)
898      case OP_CBRA:      case OP_CBRA:
899      case OP_SCBRA:      case OP_SCBRA:
900      localsize++;      localsize++;
901      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
902      break;      break;
903    
904      case OP_CBRAPOS:      case OP_CBRAPOS:
905      case OP_SCBRAPOS:      case OP_SCBRAPOS:
906      localsize += 2;      localsize += 2;
907      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
908      break;      break;
909    
910      case OP_COND:      case OP_COND:
# Line 869  SLJIT_ASSERT(cc == ccend); Line 925  SLJIT_ASSERT(cc == ccend);
925  return localsize;  return localsize;
926  }  }
927    
928  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
929    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
930  {  {
931  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 878  int count; Line 934  int count;
934  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
935  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
936  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
937  uschar *alternative;  pcre_uchar *alternative;
938  enum {  enum {
939    start,    start,
940    loop,    loop,
# Line 913  while (status != end) Line 969  while (status != end)
969    switch(status)    switch(status)
970      {      {
971      case start:      case start:
972      SLJIT_ASSERT(save);      SLJIT_ASSERT(save && common->recursive_head != 0);
973      count = 1;      count = 1;
974      srcw[0] = RECURSIVE_HEAD;      srcw[0] = common->recursive_head;
975      status = loop;      status = loop;
976      break;      break;
977    
# Line 939  while (status != end) Line 995  while (status != end)
995        case OP_SBRAPOS:        case OP_SBRAPOS:
996        case OP_SCOND:        case OP_SCOND:
997        count = 1;        count = 1;
998        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
999        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1000        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
1001        break;        break;
# Line 948  while (status != end) Line 1004  while (status != end)
1004        case OP_SCBRA:        case OP_SCBRA:
1005        count = 1;        count = 1;
1006        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1007        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1008        break;        break;
1009    
1010        case OP_CBRAPOS:        case OP_CBRAPOS:
1011        case OP_SCBRAPOS:        case OP_SCBRAPOS:
1012        count = 2;        count = 2;
1013        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
1014        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
1015        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
1016        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
1017        break;        break;
1018    
1019        case OP_COND:        case OP_COND:
# Line 966  while (status != end) Line 1022  while (status != end)
1022        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
1023          {          {
1024          count = 1;          count = 1;
1025          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1026          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1027          }          }
1028        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1174  struct sljit_label *loop; Line 1230  struct sljit_label *loop;
1230  int i;  int i;
1231  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1232  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1233  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));
1234  if (length < 8)  if (length < 8)
1235    {    {
1236    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1198  struct sljit_label *loop; Line 1254  struct sljit_label *loop;
1254  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1255    
1256  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1257  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));
1258  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);
1259    
1260  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1261  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));
1262  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));
1263  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));
1264  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);
1265  /* Unlikely, but possible */  /* Unlikely, but possible */
1266  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1267  loop = LABEL();  loop = LABEL();
1268  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);
1269  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));
1270  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1271  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1272    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1273    #endif
1274    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1275  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);
1276  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1277  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
# Line 1223  if (topbracket > 1) Line 1282  if (topbracket > 1)
1282    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));
1283    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1284    
1285    /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */    /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1286    loop = LABEL();    loop = LABEL();
1287    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)));
1288    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);
1289    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);
1290    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1291    }    }
1292  else  else
1293    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1294  }  }
1295    
1296  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)
1297    {
1298    DEFINE_COMPILER;
1299    
1300    SLJIT_COMPILE_ASSERT(STR_END == SLJIT_SAVED_REG2, str_end_must_be_saved_reg2);
1301    SLJIT_ASSERT(common->start_used_ptr != 0 && (common->mode == JIT_PARTIAL_SOFT_COMPILE ? common->hit_start != 0 : common->hit_start == 0));
1302    
1303    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
1304    OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, PCRE_ERROR_PARTIAL);
1305    OP1(SLJIT_MOV_SI, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsetcount));
1306    CMPTO(SLJIT_C_LESS, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 2, leave);
1307    
1308    /* Store match begin and end. */
1309    OP1(SLJIT_MOV, SLJIT_SAVED_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, begin));
1310    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, offsets));
1311    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);
1312    OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, STR_END, 0, SLJIT_SAVED_REG1, 0);
1313    #ifdef COMPILE_PCRE16
1314    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1315    #endif
1316    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), sizeof(int), SLJIT_SAVED_REG2, 0);
1317    
1318    OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG1, 0);
1319    #ifdef COMPILE_PCRE16
1320    OP2(SLJIT_ASHR, SLJIT_TEMPORARY_REG3, 0, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, 1);
1321    #endif
1322    OP1(SLJIT_MOV_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), 0, SLJIT_TEMPORARY_REG3, 0);
1323    
1324    JUMPTO(SLJIT_JUMP, leave);
1325    }
1326    
1327    static SLJIT_INLINE void check_start_used_ptr(compiler_common *common)
1328    {
1329    /* May destroy TMP1. */
1330    DEFINE_COMPILER;
1331    struct sljit_jump *jump;
1332    
1333    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1334      {
1335      /* The value of -1 must be kept for start_used_ptr! */
1336      OP2(SLJIT_ADD, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, 1);
1337      /* Jumps if start_used_ptr < STR_PTR, or start_used_ptr == -1. Although overwriting
1338      is not necessary if start_used_ptr == STR_PTR, it does not hurt as well. */
1339      jump = CMP(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_PTR, 0);
1340      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1341      JUMPHERE(jump);
1342      }
1343    else if (common->mode == JIT_PARTIAL_HARD_COMPILE)
1344      {
1345      jump = CMP(SLJIT_C_LESS_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1346      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1347      JUMPHERE(jump);
1348      }
1349    }
1350    
1351    static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1352  {  {
1353  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1354  unsigned int c;  unsigned int c;
1355    
1356  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1357  if (common->utf8)  if (common->utf)
1358    {    {
1359    GETCHAR(c, cc);    GETCHAR(c, cc);
1360    if (c > 127)    if (c > 127)
# Line 1251  if (common->utf8) Line 1365  if (common->utf8)
1365      return FALSE;      return FALSE;
1366  #endif  #endif
1367      }      }
1368    #ifndef COMPILE_PCRE8
1369      return common->fcc[c] != c;
1370    #endif
1371    }    }
1372  else  else
1373  #endif  #endif
1374    c = *cc;    c = *cc;
1375  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1376  }  }
1377    
1378  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)
1379  {  {
1380  /* Returns with the othercase. */  /* Returns with the othercase. */
1381  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1382  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1383    {    {
1384  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1385    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1271  if (common->utf8 && c > 127) Line 1388  if (common->utf8 && c > 127)
1388  #endif  #endif
1389    }    }
1390  #endif  #endif
1391  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1392  }  }
1393    
1394  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)
1395  {  {
1396  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1397  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1398  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1399  int n;  int n;
1400  #endif  #endif
1401    
1402  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1403  if (common->utf8)  if (common->utf)
1404    {    {
1405    GETCHAR(c, cc);    GETCHAR(c, cc);
1406    if (c <= 127)    if (c <= 127)
# Line 1300  if (common->utf8) Line 1417  if (common->utf8)
1417  else  else
1418    {    {
1419    c = *cc;    c = *cc;
1420    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1421    }    }
1422  #else  #else
1423  c = *cc;  c = *cc;
1424  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1425  #endif  #endif
1426    
1427  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1318  if (c <= 127 && bit == 0x20) Line 1435  if (c <= 127 && bit == 0x20)
1435  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1436    return 0;    return 0;
1437    
1438  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1439  if (common->utf8 && c > 127)  
1440    #ifdef SUPPORT_UTF
1441    if (common->utf && c > 127)
1442    {    {
1443    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1444    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1445      {      {
1446      n--;      n--;
# Line 1329  if (common->utf8 && c > 127) Line 1448  if (common->utf8 && c > 127)
1448      }      }
1449    return (n << 8) | bit;    return (n << 8) | bit;
1450    }    }
1451  #endif  #endif /* SUPPORT_UTF */
1452  return (0 << 8) | bit;  return (0 << 8) | bit;
1453    
1454    #else /* COMPILE_PCRE8 */
1455    
1456    #ifdef COMPILE_PCRE16
1457    #ifdef SUPPORT_UTF
1458    if (common->utf && c > 65535)
1459      {
1460      if (bit >= (1 << 10))
1461        bit >>= 10;
1462      else
1463        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1464      }
1465    #endif /* SUPPORT_UTF */
1466    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1467    #endif /* COMPILE_PCRE16 */
1468    
1469    #endif /* COMPILE_PCRE8 */
1470    }
1471    
1472    static void check_partial(compiler_common *common, BOOL force)
1473    {
1474    /* Checks whether a partial matching is occured. Does not modify registers. */
1475    DEFINE_COMPILER;
1476    struct sljit_jump *jump = NULL;
1477    
1478    SLJIT_ASSERT(!force || common->mode != JIT_COMPILE);
1479    
1480    if (common->mode == JIT_COMPILE)
1481      return;
1482    
1483    if (!force)
1484      jump = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1485    else if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1486      jump = CMP(SLJIT_C_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
1487    
1488    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1489      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1490    else
1491      {
1492      if (common->partialmatchlabel != NULL)
1493        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1494      else
1495        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1496      }
1497    
1498    if (jump != NULL)
1499      JUMPHERE(jump);
1500    }
1501    
1502    static struct sljit_jump *check_str_end(compiler_common *common)
1503    {
1504    /* Does not affect registers. Usually used in a tight spot. */
1505    DEFINE_COMPILER;
1506    struct sljit_jump *jump;
1507    struct sljit_jump *nohit;
1508    struct sljit_jump *return_value;
1509    
1510    if (common->mode == JIT_COMPILE)
1511      return CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1512    
1513    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1514    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1515      {
1516      nohit = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1517      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1518      JUMPHERE(nohit);
1519      return_value = JUMP(SLJIT_JUMP);
1520      }
1521    else
1522      {
1523      return_value = CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
1524      if (common->partialmatchlabel != NULL)
1525        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1526      else
1527        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1528      }
1529    JUMPHERE(jump);
1530    return return_value;
1531  }  }
1532    
1533  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)
1534  {  {
1535  DEFINE_COMPILER;  DEFINE_COMPILER;
1536  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  struct sljit_jump *jump;
1537    
1538    if (common->mode == JIT_COMPILE)
1539      {
1540      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));
1541      return;
1542      }
1543    
1544    /* Partial matching mode. */
1545    jump = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
1546    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0));
1547    if (common->mode == JIT_PARTIAL_SOFT_COMPILE)
1548      {
1549      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
1550      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
1551      }
1552    else
1553      {
1554      if (common->partialmatchlabel != NULL)
1555        JUMPTO(SLJIT_JUMP, common->partialmatchlabel);
1556      else
1557        add_jump(compiler, &common->partialmatch, JUMP(SLJIT_JUMP));
1558      }
1559    JUMPHERE(jump);
1560  }  }
1561    
1562  static void read_char(compiler_common *common)  static void read_char(compiler_common *common)
# Line 1344  static void read_char(compiler_common *c Line 1564  static void read_char(compiler_common *c
1564  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1565  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1566  DEFINE_COMPILER;  DEFINE_COMPILER;
1567  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1568  struct sljit_jump *jump;  struct sljit_jump *jump;
1569  #endif  #endif
1570    
1571  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1572  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1573  if (common->utf8)  if (common->utf)
1574    {    {
1575    #ifdef COMPILE_PCRE8
1576    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1577    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1578    #ifdef COMPILE_PCRE16
1579      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1580    #endif
1581    #endif /* COMPILE_PCRE8 */
1582      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1583    JUMPHERE(jump);    JUMPHERE(jump);
1584    }    }
1585  #endif  #endif
1586  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));
1587  }  }
1588    
1589  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1365  static void peek_char(compiler_common *c Line 1591  static void peek_char(compiler_common *c
1591  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1592  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1593  DEFINE_COMPILER;  DEFINE_COMPILER;
1594  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1595  struct sljit_jump *jump;  struct sljit_jump *jump;
1596  #endif  #endif
1597    
1598  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1599  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1600  if (common->utf8)  if (common->utf)
1601    {    {
1602    #ifdef COMPILE_PCRE8
1603    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1604    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1605    #ifdef COMPILE_PCRE16
1606      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1607    #endif
1608    #endif /* COMPILE_PCRE8 */
1609      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1610    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1611    JUMPHERE(jump);    JUMPHERE(jump);
1612    }    }
# Line 1385  static void read_char8_type(compiler_com Line 1617  static void read_char8_type(compiler_com
1617  {  {
1618  /* 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. */
1619  DEFINE_COMPILER;  DEFINE_COMPILER;
1620  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1621  struct sljit_jump *jump;  struct sljit_jump *jump;
1622  #endif  #endif
1623    
1624  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1625  if (common->utf8)  if (common->utf)
1626    {    {
1627    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1628    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1629    #ifdef COMPILE_PCRE8
1630    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1631    it is a clever early read in most cases. */    it is needed in most cases. */
1632    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1633    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1634    add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
1635      JUMPHERE(jump);
1636    #else
1637    #ifdef COMPILE_PCRE16
1638      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1639      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1640      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1641    JUMPHERE(jump);    JUMPHERE(jump);
1642      /* Skip low surrogate if necessary. */
1643      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1644      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1645      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1646      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1647      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1648    #endif
1649    #endif /* COMPILE_PCRE8 */
1650    return;    return;
1651    }    }
1652  #endif  #endif
1653  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1654  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));
1655  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1656    /* The ctypes array contains only 256 values. */
1657    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1658    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1659    #endif
1660    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1661    #ifdef COMPILE_PCRE16
1662    JUMPHERE(jump);
1663    #endif
1664  }  }
1665    
1666  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1667  {  {
1668  /* 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. */
1669  DEFINE_COMPILER;  DEFINE_COMPILER;
1670  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1671  struct sljit_label *label;  struct sljit_label *label;
1672    
1673  if (common->utf8)  if (common->utf)
1674    {    {
1675    label = LABEL();    label = LABEL();
1676    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1677    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));
1678    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1679    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1680    return;    return;
1681    }    }
1682  #endif  #endif
1683  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1684    if (common->utf)
1685      {
1686      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1687      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1688      /* Skip low surrogate if necessary. */
1689      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1690      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1691      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1692      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1693      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1694      return;
1695      }
1696    #endif
1697    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1698  }  }
1699    
1700  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 1717  else if (nltype == NLTYPE_ANYCRLF)
1717    }    }
1718  else  else
1719    {    {
1720    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1721    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));
1722    }    }
1723  }  }
1724    
1725  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1726  static void do_utf8readchar(compiler_common *common)  
1727    #ifdef COMPILE_PCRE8
1728    static void do_utfreadchar(compiler_common *common)
1729  {  {
1730  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1731  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. */
1732  DEFINE_COMPILER;  DEFINE_COMPILER;
1733  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 1465  sljit_emit_fast_enter(compiler, RETURN_A Line 1736  sljit_emit_fast_enter(compiler, RETURN_A
1736  /* Searching for the first zero. */  /* Searching for the first zero. */
1737  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);
1738  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1739  /* 2 byte sequence */  /* Two byte sequence. */
1740  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1741  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));
1742  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1743  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1744  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1745  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1746  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1747  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1748  JUMPHERE(jump);  JUMPHERE(jump);
1749    
1750  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);
1751  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1752  /* 3 byte sequence */  /* Three byte sequence. */
1753  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1754  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1755  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1756  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1757  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1758  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1759  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1760  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));
1761  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1762  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1763  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1764  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1765  JUMPHERE(jump);  JUMPHERE(jump);
1766    
1767  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1768  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);  
1769  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1770  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1771  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1772  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1773  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1774  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1775  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1776  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1777  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1778  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1779  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1780  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1781  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1782  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  
1783  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1784  }  }
1785    
1786  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1787  {  {
1788  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1789  of the character (>= 0xc0) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1790  DEFINE_COMPILER;  DEFINE_COMPILER;
1791  struct sljit_jump *jump;  struct sljit_jump *jump;
1792  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1549  sljit_emit_fast_enter(compiler, RETURN_A Line 1795  sljit_emit_fast_enter(compiler, RETURN_A
1795    
1796  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);
1797  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1798  /* 2 byte sequence */  /* Two byte sequence. */
1799  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1800  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));
1801  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1802  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1803  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 1812  sljit_emit_fast_return(compiler, RETURN_
1812  JUMPHERE(jump);  JUMPHERE(jump);
1813    
1814  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1815  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);
1816  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1817  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1818  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1819  }  }
1820    
1821  #endif  #else /* COMPILE_PCRE8 */
1822    
1823    #ifdef COMPILE_PCRE16
1824    static void do_utfreadchar(compiler_common *common)
1825    {
1826    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1827    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1828    DEFINE_COMPILER;
1829    struct sljit_jump *jump;
1830    
1831    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1832    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1833    /* Do nothing, only return. */
1834    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1835    
1836    JUMPHERE(jump);
1837    /* Combine two 16 bit characters. */
1838    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1839    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1840    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1841    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1842    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1843    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1844    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1845    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1846    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1847    }
1848    #endif /* COMPILE_PCRE16 */
1849    
1850    #endif /* COMPILE_PCRE8 */
1851    
1852    #endif /* SUPPORT_UTF */
1853    
1854  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1855    
# Line 1590  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1867  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1867    
1868  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);
1869  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1870  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));
1871  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1872  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1873  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1874  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1875  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1876  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));
1877  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1878  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1879  }  }
# Line 1610  struct sljit_label *newlinelabel = NULL; Line 1887  struct sljit_label *newlinelabel = NULL;
1887  struct sljit_jump *start;  struct sljit_jump *start;
1888  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1889  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1890  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1891  struct sljit_jump *singlebyte;  struct sljit_jump *singlechar;
1892  #endif  #endif
1893  jump_list *newline = NULL;  jump_list *newline = NULL;
1894  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1895  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1896    
1897  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1898      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1624  if (!(hascrorlf || firstline) && (common Line 1901  if (!(hascrorlf || firstline) && (common
1901  if (firstline)  if (firstline)
1902    {    {
1903    /* Search for the end of the first line. */    /* Search for the end of the first line. */
1904      SLJIT_ASSERT(common->first_line_end != 0);
1905    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STR_PTR, 0);
1906    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);
1907    
1908    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1909      {      {
1910      mainloop = LABEL();      mainloop = LABEL();
1911      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));
1912      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1913      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1914      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1915      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);
1916      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);
1917      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));
1918      }      }
1919    else    else
1920      {      {
1921      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1922      mainloop = LABEL();      mainloop = LABEL();
1923      /* Continual stores does not cause data dependency. */      /* Continual stores does not cause data dependency. */
1924      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);
1925      read_char(common);      read_char(common);
1926      check_newlinechar(common, common->nltype, &newline, TRUE);      check_newlinechar(common, common->nltype, &newline, TRUE);
1927      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);      CMPTO(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0, mainloop);
1928      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);
1929      set_jumps(newline, LABEL());      set_jumps(newline, LABEL());
1930      }      }
1931    
# Line 1660  start = JUMP(SLJIT_JUMP); Line 1938  start = JUMP(SLJIT_JUMP);
1938  if (newlinecheck)  if (newlinecheck)
1939    {    {
1940    newlinelabel = LABEL();    newlinelabel = LABEL();
1941    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));
1942    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1943    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1944    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);
1945    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1946    #ifdef COMPILE_PCRE16
1947      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1948    #endif
1949    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1950    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1951    }    }
# Line 1672  if (newlinecheck) Line 1953  if (newlinecheck)
1953  mainloop = LABEL();  mainloop = LABEL();
1954    
1955  /* 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. */
1956  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1957  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1958  #endif  #endif
1959  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1960    
1961  if (readbyte)  if (readuchar)
1962    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1963    
1964  if (newlinecheck)  if (newlinecheck)
1965    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);
1966    
1967  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));
1968  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1969  if (common->utf8)  if (common->utf)
1970    {    {
1971    singlebyte = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1972    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);
1973    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1974    JUMPHERE(singlebyte);    JUMPHERE(singlechar);
1975      }
1976    #endif
1977    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1978    if (common->utf)
1979      {
1980      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1981      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1982      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1983      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1984      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1985      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1986      JUMPHERE(singlechar);
1987    }    }
1988  #endif  #endif
1989  JUMPHERE(start);  JUMPHERE(start);
# Line 1704  if (newlinecheck) Line 1997  if (newlinecheck)
1997  return mainloop;  return mainloop;
1998  }  }
1999    
2000  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)
2001  {  {
2002  DEFINE_COMPILER;  DEFINE_COMPILER;
2003  struct sljit_label *start;  struct sljit_label *start;
2004  struct sljit_jump *leave;  struct sljit_jump *leave;
2005  struct sljit_jump *found;  struct sljit_jump *found;
2006  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2007    
2008  if (firstline)  if (firstline)
2009    {    {
2010    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2011    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);
2012    }    }
2013    
2014  start = LABEL();  start = LABEL();
2015  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2016  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2017    
2018  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
2019    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
2020      {
2021      oc = TABLE_GET(first_char, common->fcc, first_char);
2022    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2023      if (first_char > 127 && common->utf)
2024        oc = UCD_OTHERCASE(first_char);
2025    #endif
2026      }
2027    if (first_char == oc)
2028      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
2029  else  else
2030    {    {
2031    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
2032    if (ispowerof2(bit))    if (ispowerof2(bit))
2033      {      {
2034      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
2035      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
2036      }      }
2037    else    else
2038      {      {
2039      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);
2040      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
2041      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);
2042      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 2044  else
2044      }      }
2045    }    }
2046    
2047  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));
2048  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2049  if (common->utf8)  if (common->utf)
2050    {    {
2051    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2052    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);
2053      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2054      }
2055    #endif
2056    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2057    if (common->utf)
2058      {
2059      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2060      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2061      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2062      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2063      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2064    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2065    }    }
2066  #endif  #endif
# Line 1775  jump_list *newline = NULL; Line 2086  jump_list *newline = NULL;
2086  if (firstline)  if (firstline)
2087    {    {
2088    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2089    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);
2090    }    }
2091    
2092  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 2097  if (common->nltype == NLTYPE_FIXED && co
2097    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));
2098    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
2099    
2100    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
2101    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);
2102    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
2103    #ifdef COMPILE_PCRE16
2104      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2105    #endif
2106    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2107    
2108    loop = LABEL();    loop = LABEL();
2109    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));
2110    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2111    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
2112    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
2113    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);
2114    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);
2115    
# Line 1826  if (common->nltype == NLTYPE_ANY || comm Line 2140  if (common->nltype == NLTYPE_ANY || comm
2140    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
2141    JUMPHERE(foundcr);    JUMPHERE(foundcr);
2142    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2143    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2144    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);
2145    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2146    #ifdef COMPILE_PCRE16
2147      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2148    #endif
2149    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2150    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
2151    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1846  DEFINE_COMPILER; Line 2163  DEFINE_COMPILER;
2163  struct sljit_label *start;  struct sljit_label *start;
2164  struct sljit_jump *leave;  struct sljit_jump *leave;
2165  struct sljit_jump *found;  struct sljit_jump *found;
2166    #ifndef COMPILE_PCRE8
2167    struct sljit_jump *jump;
2168    #endif
2169    
2170  if (firstline)  if (firstline)
2171    {    {
2172    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, STR_END, 0);
2173    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);
2174    }    }
2175    
2176  start = LABEL();  start = LABEL();
2177  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2178  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2179  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2180  if (common->utf8)  if (common->utf)
2181    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2182  #endif  #endif
2183    #ifndef COMPILE_PCRE8
2184    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2185    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2186    JUMPHERE(jump);
2187    #endif
2188  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2189  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
2190  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 2192  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2192  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);
2193  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2194    
2195  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2196  if (common->utf8)  if (common->utf)
2197    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2198  #endif  #endif
2199  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));
2200  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2201  if (common->utf8)  if (common->utf)
2202    {    {
2203    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2204    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);
2205      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2206      }
2207    #endif
2208    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2209    if (common->utf)
2210      {
2211      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2212      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2213      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2214      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2215      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2216    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2217    }    }
2218  #endif  #endif
# Line 1888  if (firstline) Line 2224  if (firstline)
2224    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2225  }  }
2226    
2227  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)
2228  {  {
2229  DEFINE_COMPILER;  DEFINE_COMPILER;
2230  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1897  struct sljit_jump *alreadyfound; Line 2233  struct sljit_jump *alreadyfound;
2233  struct sljit_jump *found;  struct sljit_jump *found;
2234  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2235  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2236  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2237    
2238  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  SLJIT_ASSERT(common->req_char_ptr != 0);
2239    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr);
2240  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);
2241  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2242  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2243    
2244  if (has_firstbyte)  if (has_firstchar)
2245    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2246  else  else
2247    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2248    
2249  loop = LABEL();  loop = LABEL();
2250  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2251    
2252  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2253  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2254    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2255      {
2256      oc = TABLE_GET(req_char, common->fcc, req_char);
2257    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2258      if (req_char > 127 && common->utf)
2259        oc = UCD_OTHERCASE(req_char);
2260    #endif
2261      }
2262    if (req_char == oc)
2263      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2264  else  else
2265    {    {
2266    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2267    if (ispowerof2(bit))    if (ispowerof2(bit))
2268      {      {
2269      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2270      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2271      }      }
2272    else    else
2273      {      {
2274      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2275      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2276      }      }
2277    }    }
2278  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2279  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2280    
2281  JUMPHERE(found);  JUMPHERE(found);
2282  if (foundoc)  if (foundoc)
2283    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2284  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);
2285  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2286  JUMPHERE(toolong);  JUMPHERE(toolong);
2287  return notfound;  return notfound;
# Line 1984  JUMPTO(SLJIT_JUMP, mainloop); Line 2328  JUMPTO(SLJIT_JUMP, mainloop);
2328  static void check_wordboundary(compiler_common *common)  static void check_wordboundary(compiler_common *common)
2329  {  {
2330  DEFINE_COMPILER;  DEFINE_COMPILER;
2331  struct sljit_jump *beginend;  struct sljit_jump *skipread;
2332  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2333  struct sljit_jump *jump;  struct sljit_jump *jump;
2334  #endif  #endif
2335    
# Line 1996  sljit_emit_fast_enter(compiler, SLJIT_ME Line 2340  sljit_emit_fast_enter(compiler, SLJIT_ME
2340  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
2341  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));
2342  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, 0);
2343  beginend = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);  skipread = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP1, 0);
2344  skip_char_back(common);  skip_char_back(common);
2345    check_start_used_ptr(common);
2346  read_char(common);  read_char(common);
2347    
2348  /* Testing char type. */  /* Testing char type. */
2349  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2350  if (common->useucp)  if (common->use_ucp)
2351    {    {
2352    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2353    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 2364  if (common->useucp)
2364  else  else
2365  #endif  #endif
2366    {    {
2367  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2368      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2369    #elif defined SUPPORT_UTF
2370    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2371    jump = NULL;    jump = NULL;
2372    if (common->utf8)    if (common->utf)
2373      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2374  #endif  #endif /* COMPILE_PCRE8 */
2375    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2376    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2377    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2378    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2379  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2380      JUMPHERE(jump);
2381    #elif defined SUPPORT_UTF
2382    if (jump != NULL)    if (jump != NULL)
2383      JUMPHERE(jump);      JUMPHERE(jump);
2384  #endif  #endif /* COMPILE_PCRE8 */
2385    }    }
2386  JUMPHERE(beginend);  JUMPHERE(skipread);
2387    
2388  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2389  beginend = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  skipread = check_str_end(common);
2390  peek_char(common);  peek_char(common);
2391    
2392  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2393  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2394  if (common->useucp)  if (common->use_ucp)
2395    {    {
2396    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2397    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 2407  if (common->useucp)
2407  else  else
2408  #endif  #endif
2409    {    {
2410  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2411      /* TMP2 may be destroyed by peek_char. */
2412      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2413      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2414    #elif defined SUPPORT_UTF
2415    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2416    jump = NULL;    jump = NULL;
2417    if (common->utf8)    if (common->utf)
2418      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2419  #endif  #endif
2420    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2421    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2422    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2423  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2424      JUMPHERE(jump);
2425    #elif defined SUPPORT_UTF
2426    if (jump != NULL)    if (jump != NULL)
2427      JUMPHERE(jump);      JUMPHERE(jump);
2428  #endif  #endif /* COMPILE_PCRE8 */
2429    }    }
2430  JUMPHERE(beginend);  JUMPHERE(skipread);
2431    
2432  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);
2433  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 2444  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2444  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);
2445  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2446  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);
2447  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2448  if (common->utf8)  #ifdef COMPILE_PCRE8
2449    if (common->utf)
2450    {    {
2451    #endif
2452    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2453    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2454    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);
2455    #ifdef COMPILE_PCRE8
2456    }    }
2457  #endif  #endif
2458    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2459  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2460  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2461  }  }
# Line 2113  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2472  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2472  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);
2473  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2474  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);
2475  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2476  if (common->utf8)  #ifdef COMPILE_PCRE8
2477    if (common->utf)
2478    {    {
2479    #endif
2480    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2481    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);
2482    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2129  if (common->utf8) Line 2490  if (common->utf8)
2490    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);
2491    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2492    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);
2493    #ifdef COMPILE_PCRE8
2494    }    }
2495  #endif  #endif
2496    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2497  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2498    
2499  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2147  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2510  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2510  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);
2511  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2512  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);
2513  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2514  if (common->utf8)  #ifdef COMPILE_PCRE8
2515    if (common->utf)
2516    {    {
2517    #endif
2518    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2519    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2520    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);
2521    #ifdef COMPILE_PCRE8
2522    }    }
2523  #endif  #endif
2524    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2525  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2526    
2527  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 2540  sljit_emit_fast_enter(compiler, RETURN_A
2540  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2541  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2542  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2543  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2544  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));
2545    
2546  label = LABEL();  label = LABEL();
2547  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2548  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2549  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2550  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));
2551  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2552    
2553  JUMPHERE(jump);  JUMPHERE(jump);
2554  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));
2555  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2556  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2557  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 2572  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2572  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2573  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2574  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2575  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2576  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));
2577    
2578  label = LABEL();  label = LABEL();
2579  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2580  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2581    #ifndef COMPILE_PCRE8
2582    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2583    #endif
2584  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2585    #ifndef COMPILE_PCRE8
2586    JUMPHERE(jump);
2587    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2588    #endif
2589  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2590    #ifndef COMPILE_PCRE8
2591    JUMPHERE(jump);
2592    #endif
2593  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2594  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));
2595  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2596    
2597  JUMPHERE(jump);  JUMPHERE(jump);
2598  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));
2599  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2600  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2601  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 2606  sljit_emit_fast_return(compiler, RETURN_
2606  #undef CHAR1  #undef CHAR1
2607  #undef CHAR2  #undef CHAR2
2608    
2609  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2610    
2611  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)
2612  {  {
2613  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2614  int c1, c2;  int c1, c2;
2615  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2616  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2617    
2618  while (src1 < end1)  while (src1 < end1)
2619    {    {
2620    if (src2 >= end2)    if (src2 >= end2)
2621      return 0;      return (pcre_uchar*)1;
2622    GETCHARINC(c1, src1);    GETCHARINC(c1, src1);
2623    GETCHARINC(c2, src2);    GETCHARINC(c2, src2);
2624    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return 0;    if (c1 != c2 && c1 != UCD_OTHERCASE(c2)) return NULL;
2625    }    }
2626  return src2;  return src2;
2627  }  }
2628    
2629  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2630    
2631  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,
2632      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2633  {  {
2634  DEFINE_COMPILER;  DEFINE_COMPILER;
2635  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2636  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2637  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2638  int utf8length;  int utflength;
2639  #endif  #endif
2640    
2641  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2268  if (caseless && char_has_othercase(commo Line 2643  if (caseless && char_has_othercase(commo
2643    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2644    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2645    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2646    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2647      othercasechar = cc + (othercasebit >> 8);
2648    othercasebit &= 0xff;    othercasebit &= 0xff;
2649    #else
2650    #ifdef COMPILE_PCRE16
2651      othercasechar = cc + (othercasebit >> 9);
2652      if ((othercasebit & 0x100) != 0)
2653        othercasebit = (othercasebit & 0xff) << 8;
2654      else
2655        othercasebit &= 0xff;
2656    #endif
2657    #endif
2658    }    }
2659    
2660  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2661    {    {
2662    #ifdef COMPILE_PCRE8
2663  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2664    if (context->length >= 4)    if (context->length >= 4)
2665      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2666    else if (context->length >= 2)    else if (context->length >= 2)
2667      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2668    else    else
2669  #endif  #endif
2670      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2671    #else
2672    #ifdef COMPILE_PCRE16
2673    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2674      if (context->length >= 4)
2675        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2676      else
2677    #endif
2678        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2679    #endif
2680    #endif /* COMPILE_PCRE8 */
2681    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2682    }    }
2683    
2684  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2685  utf8length = 1;  utflength = 1;
2686  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2687    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2688    
2689  do  do
2690    {    {
2691  #endif  #endif
2692    
2693    context->length--;    context->length -= IN_UCHARS(1);
2694  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2695    
2696    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2697    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2698      {      {
2699      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2700      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2701      }      }
2702    else    else
2703      {      {
2704      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2705      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2706      }      }
2707    context->byteptr++;    context->ucharptr++;
2708    
2709    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2710      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2711    #else
2712      if (context->ucharptr >= 2 || context->length == 0)
2713    #endif
2714      {      {
2715      if (context->length >= 4)      if (context->length >= 4)
2716        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);
2717    #ifdef COMPILE_PCRE8
2718      else if (context->length >= 2)      else if (context->length >= 2)
2719        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);
2720      else if (context->length >= 1)      else if (context->length >= 1)
2721        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);
2722    #else
2723        else if (context->length >= 2)
2724          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2725    #endif
2726      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2727    
2728      switch(context->byteptr)      switch(context->ucharptr)
2729        {        {
2730        case 4:        case 4 / sizeof(pcre_uchar):
2731        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2732          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);
2733        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));
2734        break;        break;
2735    
2736        case 2:        case 2 / sizeof(pcre_uchar):
2737        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2738          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);
2739        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));
2740        break;        break;
2741    
2742    #ifdef COMPILE_PCRE8
2743        case 1:        case 1:
2744        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2745          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);
2746        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));
2747        break;        break;
2748    #endif
2749    
2750        default:        default:
2751        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2752        break;        break;
2753        }        }
2754      context->byteptr = 0;      context->ucharptr = 0;
2755      }      }
2756    
2757  #else  #else
2758    
2759    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2760    #ifdef COMPILE_PCRE8
2761    if (context->length > 0)    if (context->length > 0)
2762      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);
2763    #else
2764      if (context->length > 0)
2765        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2766    #endif
2767    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2768    
2769    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2770      {      {
2771      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2772      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 2777  do
2777  #endif  #endif
2778    
2779    cc++;    cc++;
2780  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2781    utf8length--;    utflength--;
2782    }    }
2783  while (utf8length > 0);  while (utflength > 0);
2784  #endif  #endif
2785    
2786  return cc;  return cc;
2787  }  }
2788    
2789  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2790    
2791  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2792    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2396  return cc; Line 2808  return cc;
2808      } \      } \
2809    charoffset = (value);    charoffset = (value);
2810    
2811  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)
2812  {  {
2813  DEFINE_COMPILER;  DEFINE_COMPILER;
2814  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2404  jump_list **list = (*cc & XCL_NOT) == 0 Line 2816  jump_list **list = (*cc & XCL_NOT) == 0
2816  unsigned int c;  unsigned int c;
2817  int compares;  int compares;
2818  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2819  uschar *ccbegin;  pcre_uchar *ccbegin;
2820  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2821  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2822  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
# Line 2414  unsigned int typeoffset; Line 2826  unsigned int typeoffset;
2826  int invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2827  unsigned int charoffset;  unsigned int charoffset;
2828    
2829  /* 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. */
2830  check_input_end(common, fallbacks);  fallback_at_str_end(common, fallbacks);
2831  read_char(common);  read_char(common);
2832    
2833  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2834    {    {
2835    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2836    if (common->utf8)  #ifndef COMPILE_PCRE8
2837      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2838    #elif defined SUPPORT_UTF
2839      if (common->utf)
2840      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2841    #endif
2842    
2843    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2844    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 2847  if ((*cc++ & XCL_MAP) != 0)
2847    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);
2848    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2849    
2850    if (common->utf8)  #ifndef COMPILE_PCRE8
2851      JUMPHERE(jump);
2852    #elif defined SUPPORT_UTF
2853      if (common->utf)
2854      JUMPHERE(jump);      JUMPHERE(jump);
2855    #endif
2856    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2857  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2858    charsaved = TRUE;    charsaved = TRUE;
2859  #endif  #endif
2860    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2861    }    }
2862    
2863  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2449  while (*cc != XCL_END) Line 2869  while (*cc != XCL_END)
2869    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2870      {      {
2871      cc += 2;      cc += 2;
2872  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2873      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]);
2874  #endif  #endif
2875  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2876      needschar = TRUE;      needschar = TRUE;
# Line 2459  while (*cc != XCL_END) Line 2879  while (*cc != XCL_END)
2879    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2880      {      {
2881      cc += 2;      cc += 2;
2882  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2883      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]);
2884  #endif  #endif
2885      cc++;      cc++;
2886  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2887      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]);
2888  #endif  #endif
2889  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2890      needschar = TRUE;      needschar = TRUE;
# Line 2534  if (needstype || needsscript) Line 2954  if (needstype || needsscript)
2954      {      {
2955      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2956        {        {
2957        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));
2958        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2959        }        }
2960      else      else
2961        {        {
2962        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2963        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));
2964        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2965        }        }
2966      }      }
# Line 2564  while (*cc != XCL_END) Line 2984  while (*cc != XCL_END)
2984    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2985      {      {
2986      cc ++;      cc ++;
2987  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2988      if (common->utf8)      if (common->utf)
2989        {        {
2990        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2991        }        }
# Line 2595  while (*cc != XCL_END) Line 3015  while (*cc != XCL_END)
3015    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
3016      {      {
3017      cc ++;      cc ++;
3018  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3019      if (common->utf8)      if (common->utf)
3020        {        {
3021        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3022        }        }
# Line 2604  while (*cc != XCL_END) Line 3024  while (*cc != XCL_END)
3024  #endif  #endif
3025        c = *cc++;        c = *cc++;
3026      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
3027  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3028      if (common->utf8)      if (common->utf)
3029        {        {
3030        GETCHARINC(c, cc);        GETCHARINC(c, cc);
3031        }        }
# Line 2661  while (*cc != XCL_END) Line 3081  while (*cc != XCL_END)
3081        break;        break;
3082    
3083        case PT_GC:        case PT_GC:
3084        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
3085        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
3086        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);
3087        break;        break;
3088    
3089        case PT_PC:        case PT_PC:
# Line 2725  if (found != NULL) Line 3145  if (found != NULL)
3145    
3146  #endif  #endif
3147    
3148  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)
3149  {  {
3150  DEFINE_COMPILER;  DEFINE_COMPILER;
3151  int length;  int length;
3152  unsigned int c, oc, bit;  unsigned int c, oc, bit;
3153  compare_context context;  compare_context context;
3154  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
3155  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3156  struct sljit_label *label;  struct sljit_label *label;
3157  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3158  uschar propdata[5];  pcre_uchar propdata[5];
3159  #endif  #endif
3160  #endif  #endif
3161    
# Line 2761  switch(type) Line 3181  switch(type)
3181    
3182    case OP_NOT_DIGIT:    case OP_NOT_DIGIT:
3183    case OP_DIGIT:    case OP_DIGIT:
3184    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3185    read_char8_type(common);    read_char8_type(common);
3186    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);
3187    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 3189  switch(type)
3189    
3190    case OP_NOT_WHITESPACE:    case OP_NOT_WHITESPACE:
3191    case OP_WHITESPACE:    case OP_WHITESPACE:
3192    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3193    read_char8_type(common);    read_char8_type(common);
3194    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);
3195    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 3197  switch(type)
3197    
3198    case OP_NOT_WORDCHAR:    case OP_NOT_WORDCHAR:
3199    case OP_WORDCHAR:    case OP_WORDCHAR:
3200    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3201    read_char8_type(common);    read_char8_type(common);
3202    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);
3203    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));
3204    return cc;    return cc;
3205    
3206    case OP_ANY:    case OP_ANY:
3207    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3208    read_char(common);    read_char(common);
3209    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3210      {      {
3211      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);
3212      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3213      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3214        else
3215          jump[1] = check_str_end(common);
3216    
3217        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3218      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));
3219      JUMPHERE(jump[1]);      if (jump[1] != NULL)
3220          JUMPHERE(jump[1]);
3221      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3222      }      }
3223    else    else
# Line 2800  switch(type) Line 3225  switch(type)
3225    return cc;    return cc;
3226    
3227    case OP_ALLANY:    case OP_ALLANY:
3228    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3229  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3230    if (common->utf8)    if (common->utf)
3231      {      {
3232      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3233      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));
3234    #ifdef COMPILE_PCRE8
3235      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);      jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3236      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);
3237        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3238    #else /* COMPILE_PCRE8 */
3239    #ifdef COMPILE_PCRE16
3240        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3241        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3242        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3243        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3244        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3245      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3246    #endif /* COMPILE_PCRE16 */
3247    #endif /* COMPILE_PCRE8 */
3248      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3249      return cc;      return cc;
3250      }      }
3251  #endif  #endif
3252    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));
3253    return cc;    return cc;
3254    
3255    case OP_ANYBYTE:    case OP_ANYBYTE:
3256    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3257    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));
3258    return cc;    return cc;
3259    
3260  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3261  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3262    case OP_NOTPROP:    case OP_NOTPROP:
3263    case OP_PROP:    case OP_PROP:
# Line 2836  switch(type) Line 3272  switch(type)
3272  #endif  #endif
3273    
3274    case OP_ANYNL:    case OP_ANYNL:
3275    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3276    read_char(common);    read_char(common);
3277    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);
3278    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    /* We don't need to handle soft partial matching case. */
3279    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    if (common->mode != JIT_PARTIAL_HARD_COMPILE)
3280        jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3281      else
3282        jump[1] = check_str_end(common);
3283      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3284    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);
3285    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));
3286    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3287    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3288    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2853  switch(type) Line 3293  switch(type)
3293    
3294    case OP_NOT_HSPACE:    case OP_NOT_HSPACE:
3295    case OP_HSPACE:    case OP_HSPACE:
3296    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3297    read_char(common);    read_char(common);
3298    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL));
3299    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 3301  switch(type)
3301    
3302    case OP_NOT_VSPACE:    case OP_NOT_VSPACE:
3303    case OP_VSPACE:    case OP_VSPACE:
3304    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3305    read_char(common);    read_char(common);
3306    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL));
3307    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 3309  switch(type)
3309    
3310  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3311    case OP_EXTUNI:    case OP_EXTUNI:
3312    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3313    read_char(common);    read_char(common);
3314    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL));
3315    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 3325  switch(type)
3325    
3326    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0);
3327    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3328      if (common->mode == JIT_PARTIAL_HARD_COMPILE)
3329        {
3330        jump[0] = CMP(SLJIT_C_LESS, STR_PTR, 0, STR_END, 0);
3331        /* Since we successfully read a char above, partial matching must occure. */
3332        check_partial(common, TRUE);
3333        JUMPHERE(jump[0]);
3334        }
3335    return cc;    return cc;
3336  #endif  #endif
3337    
3338    case OP_EODN:    case OP_EODN:
3339      /* Requires rather complex checks. */
3340    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);
3341    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3342      {      {
3343      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3344      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3345      add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, STR_END, 0));      if (common->mode == JIT_COMPILE)
3346      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));
3347        else
3348          {
3349          jump[1] = CMP(SLJIT_C_EQUAL, TMP2, 0, STR_END, 0);
3350          OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP2, 0, STR_END, 0);
3351          COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS);
3352          OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff);
3353          COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_NOT_EQUAL);
3354          add_jump(compiler, fallbacks, JUMP(SLJIT_C_NOT_EQUAL));
3355          check_partial(common, TRUE);
3356          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3357          JUMPHERE(jump[1]);
3358          }
3359        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3360      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));
3361      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));
3362      }      }
3363    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3364      {      {
3365      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3366      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3367      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));
3368      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));
3369      }      }
3370    else    else
3371      {      {
3372      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3373      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);
3374      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3375      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);
3376      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3377      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3378      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3379        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3380      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3381      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3382    
3383      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3384      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3385        {        {
3386        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3387        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));
3388        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));
3389        }        }
# Line 2938  switch(type) Line 3400  switch(type)
3400      JUMPHERE(jump[3]);      JUMPHERE(jump[3]);
3401      }      }
3402    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3403      check_partial(common, FALSE);
3404    return cc;    return cc;
3405    
3406    case OP_EOD:    case OP_EOD:
3407    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));
3408      check_partial(common, FALSE);
3409    return cc;    return cc;
3410    
3411    case OP_CIRC:    case OP_CIRC:
# Line 2961  switch(type) Line 3425  switch(type)
3425    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3426    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3427    
3428    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));  
   
3429    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3430      {      {
3431      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3432      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3433      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3434      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3435      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));
3436      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));
3437      }      }
# Line 2990  switch(type) Line 3452  switch(type)
3452    if (!common->endonly)    if (!common->endonly)
3453      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);      compile_char1_hotpath(common, OP_EODN, cc, fallbacks);
3454    else    else
3455        {
3456      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));
3457        check_partial(common, FALSE);
3458        }
3459    return cc;    return cc;
3460    
3461    case OP_DOLLM:    case OP_DOLLM:
# Line 2998  switch(type) Line 3463  switch(type)
3463    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0);
3464    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));
3465    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));
3466      check_partial(common, FALSE);
3467    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3468    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3469    
3470    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3471      {      {
3472      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3473      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));
3474      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      if (common->mode == JIT_COMPILE)
3475      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);        add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3476        else
3477          {
3478          jump[1] = CMP(SLJIT_C_LESS_EQUAL, TMP2, 0, STR_END, 0);
3479          /* STR_PTR = STR_END - IN_UCHARS(1) */
3480          add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff));
3481          check_partial(common, TRUE);
3482          add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3483          JUMPHERE(jump[1]);
3484          }
3485    
3486        OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3487      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));
3488      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));
3489      }      }
# Line 3021  switch(type) Line 3498  switch(type)
3498    case OP_CHAR:    case OP_CHAR:
3499    case OP_CHARI:    case OP_CHARI:
3500    length = 1;    length = 1;
3501  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3502    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3503  #endif  #endif
3504    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))
3505      {      {
3506      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));
3507      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));
3508    
3509      context.length = length;      context.length = IN_UCHARS(length);
3510      context.sourcereg = -1;      context.sourcereg = -1;
3511  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3512      context.byteptr = 0;      context.ucharptr = 0;
3513  #endif  #endif
3514      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3515      }      }
3516    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    fallback_at_str_end(common, fallbacks);
3517    read_char(common);    read_char(common);
3518  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3519    if (common->utf8)    if (common->utf)
3520      {      {
3521      GETCHAR(c, cc);      GETCHAR(c, cc);
3522      }      }
3523    else    else
3524  #endif  #endif
3525      c = *cc;      c = *cc;
3526      if (type == OP_CHAR || !char_has_othercase(common, cc))
3527        {
3528        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c));
3529        return cc + length;
3530        }
3531      oc = char_othercase(common, c);
3532      bit = c ^ oc;
3533      if (ispowerof2(bit))
3534        {
3535        OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit);
3536        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit));
3537        return cc + length;
3538        }
3539    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);
3540    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3541    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 3545  switch(type)
3545    
3546    case OP_NOT:    case OP_NOT:
3547    case OP_NOTI:    case OP_NOTI:
3548      fallback_at_str_end(common, fallbacks);
3549    length = 1;    length = 1;
3550  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3551    if (common->utf8)    if (common->utf)
3552      {      {
3553      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3554        c = *cc;
3555      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3556        {        {
3557        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3558        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
# Line 3076  switch(type) Line 3564  switch(type)
3564          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));
3565          }          }
3566        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3567        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));
3568        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3569        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);
3570        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3571        JUMPHERE(jump[0]);        JUMPHERE(jump[0]);
3572        return cc + length;        return cc + 1;
3573        }        }
3574      else      else
3575    #endif /* COMPILE_PCRE8 */
3576          {
3577          GETCHARLEN(c, cc, length);
3578        read_char(common);        read_char(common);
3579          }
3580      }      }
3581    else    else
3582  #endif  #endif /* SUPPORT_UTF */
3583      {      {
3584      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);  
3585      c = *cc;      c = *cc;
3586      }      }
3587    
# Line 3116  switch(type) Line 3606  switch(type)
3606    
3607    case OP_CLASS:    case OP_CLASS:
3608    case OP_NCLASS:    case OP_NCLASS:
3609    check_input_end(common, fallbacks);    fallback_at_str_end(common, fallbacks);
3610    read_char(common);    read_char(common);
3611  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3612    jump[0] = NULL;    jump[0] = NULL;
3613    if (common->utf8)  #ifdef COMPILE_PCRE8
3614      /* This check only affects 8 bit mode. In other modes, we
3615      always need to compare the value with 255. */
3616      if (common->utf)
3617    #endif /* COMPILE_PCRE8 */
3618      {      {
3619      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3620      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3129  switch(type) Line 3623  switch(type)
3623        jump[0] = NULL;        jump[0] = NULL;
3624        }        }
3625      }      }
3626  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3627    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3628    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3629    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3630    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3631    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);
3632    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3633  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3634    if (jump[0] != NULL)    if (jump[0] != NULL)
3635      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3636  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3637    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3638    
3639  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3640    case OP_XCLASS:    case OP_XCLASS:
3641    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3642    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3152  switch(type) Line 3646  switch(type)
3646    length = GET(cc, 0);    length = GET(cc, 0);
3647    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3648    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3649    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3650  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3651      {      {
3652        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3653      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3654      label = LABEL();      label = LABEL();
3655      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));
3656      skip_char_back(common);      skip_char_back(common);
3657      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);
3658      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
     return cc + LINK_SIZE;  
3659      }      }
3660      else
3661  #endif  #endif
3662    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);      {
3663    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));
3664        OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3665        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3666        }
3667      check_start_used_ptr(common);
3668    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3669    }    }
3670  SLJIT_ASSERT_STOP();  SLJIT_ASSERT_STOP();
3671  return cc;  return cc;
3672  }  }
3673    
3674  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)
3675  {  {
3676  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3677  /* 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. */
3678  DEFINE_COMPILER;  DEFINE_COMPILER;
3679  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3680  compare_context context;  compare_context context;
3681  int size;  int size;
3682    
# Line 3191  do Line 3689  do
3689    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3690      {      {
3691      size = 1;      size = 1;
3692  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3693      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3694        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3695  #endif  #endif
3696      }      }
3697    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3698      {      {
3699      size = 1;      size = 1;
3700  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3701      if (common->utf8)      if (common->utf)
3702        {        {
3703        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)
3704          size = 0;          size = 0;
3705        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3706          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3707        }        }
3708      else      else
3709  #endif  #endif
# Line 3216  do Line 3714  do
3714      size = 0;      size = 0;
3715    
3716    cc += 1 + size;    cc += 1 + size;
3717    context.length += size;    context.length += IN_UCHARS(size);
3718    }    }
3719  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3720    
# Line 3229  if (context.length > 0) Line 3727  if (context.length > 0)
3727    
3728    context.sourcereg = -1;    context.sourcereg = -1;
3729  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3730    context.byteptr = 0;    context.ucharptr = 0;
3731  #endif  #endif
3732    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);
3733    return cc;    return cc;
# Line 3239  if (context.length > 0) Line 3737  if (context.length > 0)
3737  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3738  }  }
3739    
3740  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)
3741  {  {
3742  DEFINE_COMPILER;  DEFINE_COMPILER;
3743  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3249  if (!common->jscript_compat) Line 3747  if (!common->jscript_compat)
3747    {    {
3748    if (fallbacks == NULL)    if (fallbacks == NULL)
3749      {      {
3750        /* OVECTOR(1) contains the "string begin - 1" constant. */
3751      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));
3752      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
3753      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 3760  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3760  }  }
3761    
3762  /* Forward definitions. */  /* Forward definitions. */
3763  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3764  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3765    
3766  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3290  static void compile_fallbackpath(compile Line 3789  static void compile_fallbackpath(compile
3789      } \      } \
3790    while (0)    while (0)
3791    
3792  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type *)fallback)
3793    
3794  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)
3795  {  {
3796  DEFINE_COMPILER;  DEFINE_COMPILER;
3797  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
3798  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3799    struct sljit_jump *partial;
3800    struct sljit_jump *nopartial;
3801    
3802  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
3803    /* OVECTOR(1) contains the "string begin - 1" constant. */
3804  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3805    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)));
3806    
3807  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3808  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3809    {    {
3810    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);
3811    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1));
# Line 3315  if (common->utf8 && *cc == OP_REFI) Line 3816  if (common->utf8 && *cc == OP_REFI)
3816    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3817    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3818    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_TEMPORARY_REG2), SLJIT_OFFSETOF(jit_arguments, ptr), STR_PTR, 0);
3819    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));
3820    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3821    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    if (common->mode == JIT_COMPILE)
3822        add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1));
3823      else
3824        {
3825        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3826        nopartial = CMP(SLJIT_C_NOT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
3827        check_partial(common, FALSE);
3828        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3829        JUMPHERE(nopartial);
3830        }
3831    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3832    }    }
3833  else  else
3834  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3835    {    {
3836    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);
3837    if (withchecks)    if (withchecks)
3838      jump = JUMP(SLJIT_C_ZERO);      jump = JUMP(SLJIT_C_ZERO);
3839    
3840    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
3841      partial = CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0);
3842      if (common->mode == JIT_COMPILE)
3843        add_jump(compiler, fallbacks, partial);
3844    
   add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, STR_PTR, 0, STR_END, 0));  
3845    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));
3846    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));
3847    
3848      if (common->mode != JIT_COMPILE)
3849        {
3850        nopartial = JUMP(SLJIT_JUMP);
3851        JUMPHERE(partial);
3852        /* TMP2 -= STR_END - STR_PTR */
3853        OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, STR_PTR, 0);
3854        OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, STR_END, 0);
3855        partial = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, 0);
3856        OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0);
3857        add_jump(compiler, *cc == OP_REF ? &common->casefulcmp : &common->caselesscmp, JUMP(SLJIT_FAST_CALL));
3858        add_jump(compiler, fallbacks, CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0));
3859        JUMPHERE(partial);
3860        check_partial(common, FALSE);
3861        add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3862        JUMPHERE(nopartial);
3863        }
3864    }    }
3865    
3866  if (jump != NULL)  if (jump != NULL)
# Line 3341  if (jump != NULL) Line 3870  if (jump != NULL)
3870    else    else
3871      JUMPHERE(jump);      JUMPHERE(jump);
3872    }    }
3873  return cc + 3;  return cc + 1 + IMM2_SIZE;
3874  }  }
3875    
3876  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)
3877  {  {
3878  DEFINE_COMPILER;  DEFINE_COMPILER;
3879  fallback_common *fallback;  fallback_common *fallback;
3880  uschar type;  pcre_uchar type;
3881  struct sljit_label *label;  struct sljit_label *label;
3882  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3883  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3884  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3885  int min = 0, max = 0;  int min = 0, max = 0;
3886  BOOL minimize;  BOOL minimize;
3887    
3888  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3889    
3890  type = cc[3];  type = cc[1 + IMM2_SIZE];
3891  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3892  switch(type)  switch(type)
3893    {    {
# Line 3366  switch(type) Line 3895  switch(type)
3895    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3896    min = 0;    min = 0;
3897    max = 0;    max = 0;
3898    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3899    break;    break;
3900    case OP_CRPLUS:    case OP_CRPLUS:
3901    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3902    min = 1;    min = 1;
3903    max = 0;    max = 0;
3904    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3905    break;    break;
3906    case OP_CRQUERY:    case OP_CRQUERY:
3907    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3908    min = 0;    min = 0;
3909    max = 1;    max = 1;
3910    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3911    break;    break;
3912    case OP_CRRANGE:    case OP_CRRANGE:
3913    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3914    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3915    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3916    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3917    break;    break;
3918    default:    default:
3919    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3488  decrease_call_count(common); Line 4017  decrease_call_count(common);
4017  return cc;  return cc;
4018  }  }
4019    
4020  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)
4021  {  {
4022  DEFINE_COMPILER;  DEFINE_COMPILER;
4023  fallback_common *fallback;  fallback_common *fallback;
# Line 3534  add_jump(compiler, &fallback->topfallbac Line 4063  add_jump(compiler, &fallback->topfallbac
4063  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4064  }  }
4065    
4066  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)
4067  {  {
4068  DEFINE_COMPILER;  DEFINE_COMPILER;
4069  int framesize;  int framesize;
4070  int localptr;  int localptr;
4071  fallback_common altfallback;  fallback_common altfallback;
4072  uschar *ccbegin;  pcre_uchar *ccbegin;
4073  uschar opcode;  pcre_uchar opcode;
4074  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4075  jump_list *tmp = NULL;  jump_list *tmp = NULL;
4076  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
4077  jump_list **found;  jump_list **found;
# Line 3558  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4087  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4087    bra = *cc;    bra = *cc;
4088    cc++;    cc++;
4089    }    }
4090  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4091  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4092  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
4093  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3804  common->accept = save_accept; Line 4333  common->accept = save_accept;
4333  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4334  }  }
4335    
4336  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)
4337  {  {
4338  int condition = FALSE;  int condition = FALSE;
4339  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4340  uschar *slotB;  pcre_uchar *slotB;
4341  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4342  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4343  sljit_w no_capture;  sljit_w no_capture;
4344  int i;  int i;
4345    
4346  locals += OVECTOR_START / sizeof(sljit_w);  locals += refno & 0xff;
4347    refno >>= 8;
4348  no_capture = locals[1];  no_capture = locals[1];
4349    
4350  for (i = 0; i < name_count; i++)  for (i = 0; i < name_count; i++)
# Line 3833  if (i < name_count) Line 4363  if (i < name_count)
4363    while (slotB > name_table)    while (slotB > name_table)
4364      {      {
4365      slotB -= name_entry_size;      slotB -= name_entry_size;
4366      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4367        {        {
4368        condition = locals[GET2(slotB, 0) << 1] != no_capture;        condition = locals[GET2(slotB, 0) << 1] != no_capture;
4369        if (condition) break;        if (condition) break;
# Line 3848  if (i < name_count) Line 4378  if (i < name_count)
4378      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4379        {        {
4380        slotB += name_entry_size;        slotB += name_entry_size;
4381        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4382          {          {
4383          condition = locals[GET2(slotB, 0) << 1] != no_capture;          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4384          if (condition) break;          if (condition) break;
# Line 3860  if (i < name_count) Line 4390  if (i < name_count)
4390  return condition;  return condition;
4391  }  }
4392    
4393  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)
4394  {  {
4395  int condition = FALSE;  int condition = FALSE;
4396  uschar *slotA = name_table;  pcre_uchar *slotA = name_table;
4397  uschar *slotB;  pcre_uchar *slotB;
4398  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];  sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4399  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];  sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4400  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 4416  if (i < name_count)
4416    while (slotB > name_table)    while (slotB > name_table)
4417      {      {
4418      slotB -= name_entry_size;      slotB -= name_entry_size;
4419      if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)      if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4420        {        {
4421        condition = GET2(slotB, 0) == group_num;        condition = GET2(slotB, 0) == group_num;
4422        if (condition) break;        if (condition) break;
# Line 3901  if (i < name_count) Line 4431  if (i < name_count)
4431      for (i++; i < name_count; i++)      for (i++; i < name_count; i++)
4432        {        {
4433        slotB += name_entry_size;        slotB += name_entry_size;
4434        if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4435          {          {
4436          condition = GET2(slotB, 0) == group_num;          condition = GET2(slotB, 0) == group_num;
4437          if (condition) break;          if (condition) break;
# Line 3967  return condition; Line 4497  return condition;
4497                                            Or nothing, if trace is unnecessary                                            Or nothing, if trace is unnecessary
4498  */  */
4499    
4500  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)
4501  {  {
4502  DEFINE_COMPILER;  DEFINE_COMPILER;
4503  fallback_common *fallback;  fallback_common *fallback;
4504  uschar opcode;  pcre_uchar opcode;
4505  int localptr = 0;  int localptr = 0;
4506  int offset = 0;  int offset = 0;
4507  int stacksize;  int stacksize;
4508  uschar *ccbegin;  pcre_uchar *ccbegin;
4509  uschar *hotpath;  pcre_uchar *hotpath;
4510  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4511  uschar ket;  pcre_uchar ket;
4512  assert_fallback *assert;  assert_fallback *assert;
4513  BOOL has_alternatives;  BOOL has_alternatives;
4514  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 4039  if (opcode == OP_CBRA || opcode == OP_SC Line 4569  if (opcode == OP_CBRA || opcode == OP_SC
4569    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4570    offset <<= 1;    offset <<= 1;
4571    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4572    hotpath += 2;    hotpath += IMM2_SIZE;
4573    }    }
4574  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4575    {    {
4576    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4577    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4578    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4579    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4580    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4203  if (opcode == OP_COND || opcode == OP_SC Line 4733  if (opcode == OP_COND || opcode == OP_SC
4733      SLJIT_ASSERT(has_alternatives);      SLJIT_ASSERT(has_alternatives);
4734      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4735        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)));
4736      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4737      }      }
4738    else if (*hotpath == OP_NCREF)    else if (*hotpath == OP_NCREF)
4739      {      {
# Line 4214  if (opcode == OP_COND || opcode == OP_SC Line 4744  if (opcode == OP_COND || opcode == OP_SC
4744      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4745      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);
4746      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);
4747      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)));
4748      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4749      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4750      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 4752  if (opcode == OP_COND || opcode == OP_SC
4752      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));
4753    
4754      JUMPHERE(jump);      JUMPHERE(jump);
4755      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4756      }      }
4757    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)    else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4758      {      {
# Line 4243  if (opcode == OP_COND || opcode == OP_SC Line 4773  if (opcode == OP_COND || opcode == OP_SC
4773        {        {
4774        SLJIT_ASSERT(!has_alternatives);        SLJIT_ASSERT(!has_alternatives);
4775        if (stacksize != 0)        if (stacksize != 0)
4776          hotpath += 3;          hotpath += 1 + IMM2_SIZE;
4777        else        else
4778          {          {
4779          if (*cc == OP_ALT)          if (*cc == OP_ALT)
# Line 4270  if (opcode == OP_COND || opcode == OP_SC Line 4800  if (opcode == OP_COND || opcode == OP_SC
4800        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));
4801        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4802        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));
4803        hotpath += 3;        hotpath += 1 + IMM2_SIZE;
4804        }        }
4805      }      }
4806    else    else
# Line 4378  if (bra == OP_BRAZERO) Line 4908  if (bra == OP_BRAZERO)
4908  if (bra == OP_BRAMINZERO)  if (bra == OP_BRAMINZERO)
4909    {    {
4910    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */    /* This is a fallback path! (From the viewpoint of OP_BRAMINZERO) */
4911    JUMPTO(SLJIT_JUMP, ((braminzero_fallback*)parent)->hotpath);    JUMPTO(SLJIT_JUMP, ((braminzero_fallback *)parent)->hotpath);
4912    if (braminzerojump != NULL)    if (braminzerojump != NULL)
4913      {      {
4914      JUMPHERE(braminzerojump);      JUMPHERE(braminzerojump);
# Line 4406  cc += 1 + LINK_SIZE; Line 4936  cc += 1 + LINK_SIZE;
4936  return cc;  return cc;
4937  }  }
4938    
4939  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)
4940  {  {
4941  DEFINE_COMPILER;  DEFINE_COMPILER;
4942  fallback_common *fallback;  fallback_common *fallback;
4943  uschar opcode;  pcre_uchar opcode;
4944  int localptr;  int localptr;
4945  int cbraprivptr = 0;  int cbraprivptr = 0;
4946  int framesize;  int framesize;
4947  int stacksize;  int stacksize;
4948  int offset = 0;  int offset = 0;
4949  BOOL zero = FALSE;  BOOL zero = FALSE;
4950  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4951  int stack;  int stack;
4952  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4953  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4430  if (*cc == OP_BRAPOSZERO) Line 4960  if (*cc == OP_BRAPOSZERO)
4960    }    }
4961    
4962  opcode = *cc;  opcode = *cc;
4963  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4964  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4965  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4966  switch(opcode)  switch(opcode)
# Line 4445  switch(opcode) Line 4975  switch(opcode)
4975    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4976    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4977    offset <<= 1;    offset <<= 1;
4978    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4979    break;    break;
4980    
4981    default:    default:
# Line 4624  decrease_call_count(common); Line 5154  decrease_call_count(common);
5154  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
5155  }  }
5156    
5157  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)
5158  {  {
5159  int class_len;  int class_len;
5160    
# Line 4663  else Line 5193  else
5193    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
5194    *type = *opcode;    *type = *opcode;
5195    cc++;    cc++;
5196    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (int)(1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
5197    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
5198    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
5199      {      {
# Line 4674  else Line 5204  else
5204    else    else
5205      {      {
5206      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
5207      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
5208      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
5209    
5210      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4686  else Line 5216  else
5216        *opcode = OP_EXACT;        *opcode = OP_EXACT;
5217    
5218      if (end != NULL)      if (end != NULL)
5219        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
5220      }      }
5221    return cc;    return cc;
5222    }    }
# Line 4694  else Line 5224  else
5224  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)
5225    {    {
5226    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
5227    cc += 2;    cc += IMM2_SIZE;
5228    }    }
5229    
5230  if (*type == 0)  if (*type == 0)
# Line 4709  if (*type == 0) Line 5239  if (*type == 0)
5239  if (end != NULL)  if (end != NULL)
5240    {    {
5241    *end = cc + 1;    *end = cc + 1;
5242  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
5243    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
5244  #endif  #endif
5245    }    }
5246  return cc;  return cc;
5247  }  }
5248    
5249  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)
5250  {  {
5251  DEFINE_COMPILER;  DEFINE_COMPILER;
5252  fallback_common *fallback;  fallback_common *fallback;
5253  uschar opcode;  pcre_uchar opcode;
5254  uschar type;  pcre_uchar type;
5255  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5256  uschar* end;  pcre_uchar* end;
5257  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
5258  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
5259  struct sljit_label *label;  struct sljit_label *label;
# Line 4885  decrease_call_count(common); Line 5415  decrease_call_count(common);
5415  return end;  return end;
5416  }  }
5417    
5418  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)
5419  {  {
5420  DEFINE_COMPILER;  DEFINE_COMPILER;
5421  fallback_common *fallback;  fallback_common *fallback;
# Line 4929  add_jump(compiler, &fallback->topfallbac Line 5459  add_jump(compiler, &fallback->topfallbac
5459  return cc + 1;  return cc + 1;
5460  }  }
5461    
5462  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)
5463  {  {
5464  DEFINE_COMPILER;  DEFINE_COMPILER;
5465  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5466    
5467  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5468  if (common->currententry != NULL)  if (common->currententry != NULL)
5469    return cc + 3;    return cc + 1 + IMM2_SIZE;
5470    
5471  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));
5472  offset <<= 1;  offset <<= 1;
5473  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);
5474  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5475  return cc + 3;  return cc + 1 + IMM2_SIZE;
5476  }  }
5477    
5478  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)
5479  {  {
5480  DEFINE_COMPILER;  DEFINE_COMPILER;
5481  fallback_common *fallback;  fallback_common *fallback;
# Line 4998  while (cc < ccend) Line 5528  while (cc < ccend)
5528    
5529      case OP_CHAR:      case OP_CHAR:
5530      case OP_CHARI:      case OP_CHARI:
5531      cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);      if (common->mode == JIT_COMPILE)
5532          cc = compile_charn_hotpath(common, cc, ccend, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5533        else
5534          cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5535      break;      break;
5536    
5537      case OP_STAR:      case OP_STAR:
# Line 5071  while (cc < ccend) Line 5604  while (cc < ccend)
5604    
5605      case OP_CLASS:      case OP_CLASS:
5606      case OP_NCLASS:      case OP_NCLASS:
5607      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)
5608        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5609      else      else
5610        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);
5611      break;      break;
5612    
5613  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5614      case OP_XCLASS:      case OP_XCLASS:
5615      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)
5616        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 5088  while (cc < ccend) Line 5621  while (cc < ccend)
5621    
5622      case OP_REF:      case OP_REF:
5623      case OP_REFI:      case OP_REFI:
5624      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5625        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5626      else      else
5627        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);
# Line 5191  SLJIT_ASSERT(cc == ccend); Line 5724  SLJIT_ASSERT(cc == ccend);
5724      } \      } \
5725    while (0)    while (0)
5726    
5727  #define CURRENT_AS(type) ((type*)current)  #define CURRENT_AS(type) ((type *)current)
5728    
5729  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5730  {  {
5731  DEFINE_COMPILER;  DEFINE_COMPILER;
5732  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5733  uschar opcode;  pcre_uchar opcode;
5734  uschar type;  pcre_uchar type;
5735  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5736  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5737  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5323  switch(opcode) Line 5856  switch(opcode)
5856  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)
5857  {  {
5858  DEFINE_COMPILER;  DEFINE_COMPILER;
5859  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5860  uschar type;  pcre_uchar type;
5861    
5862  type = cc[3];  type = cc[1 + IMM2_SIZE];
5863  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5864    {    {
5865    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5355  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5888  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5888  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5889  {  {
5890  DEFINE_COMPILER;  DEFINE_COMPILER;
5891  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5892  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5893  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5894    
5895  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5427  int offset = 0; Line 5960  int offset = 0;
5960  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5961  int stacksize;  int stacksize;
5962  int count;  int count;
5963  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5964  uschar *ccbegin;  pcre_uchar *ccbegin;
5965  uschar *ccprev;  pcre_uchar *ccprev;
5966  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5967  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5968  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5969  uschar ket;  pcre_uchar ket;
5970  assert_fallback *assert;  assert_fallback *assert;
5971  BOOL has_alternatives;  BOOL has_alternatives;
5972  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
# Line 5933  while (current) Line 6466  while (current)
6466      case OP_TYPEPOSUPTO:      case OP_TYPEPOSUPTO:
6467      case OP_CLASS:      case OP_CLASS:
6468      case OP_NCLASS:      case OP_NCLASS:
6469    #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
6470      case OP_XCLASS:      case OP_XCLASS:
6471    #endif
6472      compile_iterator_fallbackpath(common, current);      compile_iterator_fallbackpath(common, current);
6473      break;      break;
6474    
# Line 6000  while (current) Line 6535  while (current)
6535  static SLJIT_INLINE void compile_recurse(compiler_common *common)  static SLJIT_INLINE void compile_recurse(compiler_common *common)
6536  {  {
6537  DEFINE_COMPILER;  DEFINE_COMPILER;
6538  uschar *cc = common->start + common->currententry->start;  pcre_uchar *cc = common->start + common->currententry->start;
6539  uschar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : 2);  pcre_uchar *ccbegin = cc + 1 + LINK_SIZE + (*cc == OP_BRA ? 0 : IMM2_SIZE);
6540  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
6541  int localsize = get_localsize(common, ccbegin, ccend);  int localsize = get_localsize(common, ccbegin, ccend);
6542  int framesize = get_framesize(common, cc, TRUE);  int framesize = get_framesize(common, cc, TRUE);
6543  int alternativesize;  int alternativesize;
# Line 6016  if (!needsframe) Line 6551  if (!needsframe)
6551    framesize = 0;    framesize = 0;
6552  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;  alternativesize = *(cc + GET(cc, 1)) == OP_ALT ? 1 : 0;
6553    
6554  SLJIT_ASSERT(common->currententry->entry == NULL);  SLJIT_ASSERT(common->currententry->entry == NULL && common->recursive_head != 0);
6555  common->currententry->entry = LABEL();  common->currententry->entry = LABEL();
6556  set_jumps(common->currententry->calls, common->currententry->entry);  set_jumps(common->currententry->calls, common->currententry->entry);
6557    
# Line 6024  sljit_emit_fast_enter(compiler, TMP2, 0, Line 6559  sljit_emit_fast_enter(compiler, TMP2, 0,
6559  allocate_stack(common, localsize + framesize + alternativesize);  allocate_stack(common, localsize + framesize + alternativesize);
6560  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);
6561  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);  copy_locals(common, ccbegin, ccend, TRUE, localsize + framesize + alternativesize, framesize + alternativesize);
6562  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);
6563  if (needsframe)  if (needsframe)
6564    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);    init_frame(common, cc, framesize + alternativesize - 1, alternativesize, FALSE);
6565    
# Line 6066  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); Line 6601  OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0);
6601  jump = JUMP(SLJIT_JUMP);  jump = JUMP(SLJIT_JUMP);
6602    
6603  set_jumps(common->accept, LABEL());  set_jumps(common->accept, LABEL());
6604  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);
6605  if (needsframe)  if (needsframe)
6606    {    {
6607    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));    OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
# Line 6082  copy_locals(common, ccbegin, ccend, FALS Line 6617  copy_locals(common, ccbegin, ccend, FALS
6617  free_stack(common, localsize + framesize + alternativesize);  free_stack(common, localsize + framesize + alternativesize);
6618  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), sizeof(sljit_w));
6619  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);  OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
6620  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);
6621  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);  sljit_emit_fast_return(compiler, SLJIT_MEM1(STACK_TOP), 0);
6622  }  }
6623    
# Line 6090  sljit_emit_fast_return(compiler, SLJIT_M Line 6625  sljit_emit_fast_return(compiler, SLJIT_M
6625  #undef CURRENT_AS  #undef CURRENT_AS
6626    
6627  void  void
6628  _pcre_jit_compile(const real_pcre *re, pcre_extra *extra)  PRIV(jit_compile)(const REAL_PCRE *re, PUBL(extra) *extra, int mode)
6629  {  {
6630  struct sljit_compiler *compiler;  struct sljit_compiler *compiler;
6631  fallback_common rootfallback;  fallback_common rootfallback;
6632  compiler_common common_data;  compiler_common common_data;
6633  compiler_common *common = &common_data;  compiler_common *common = &common_data;
6634  const uschar *tables = re->tables;  const pcre_uint8 *tables = re->tables;
6635  pcre_study_data *study;  pcre_study_data *study;
6636  uschar *ccend;  pcre_uchar *ccend;
6637  executable_function *function;  executable_functions *functions;
6638  void *executable_func;  void *executable_func;
6639  sljit_uw executable_size;  sljit_uw executable_size;
6640  struct sljit_label *leave;  struct sljit_label *leave;
6641  struct sljit_label *mainloop = NULL;  struct sljit_label *mainloop = NULL;
6642  struct sljit_label *empty_match_found;  struct sljit_label *empty_match_found;
6643  struct sljit_label *empty_match_fallback;  struct sljit_label *empty_match_fallback;
6644  struct sljit_jump *alloc_error;  struct sljit_jump *jump;
6645  struct sljit_jump *reqbyte_notfound = NULL;  struct sljit_jump *reqbyte_notfound = NULL;
6646  struct sljit_jump *empty_match;  struct sljit_jump *empty_match;
6647    
# Line 6114  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_ Line 6649  SLJIT_ASSERT((extra->flags & PCRE_EXTRA_
6649  study = extra->study_data;  study = extra->study_data;
6650    
6651  if (!tables)  if (!tables)
6652    tables = _pcre_default_tables;    tables = PRIV(default_tables);
6653    
6654  memset(&rootfallback, 0, sizeof(fallback_common));  memset(&rootfallback, 0, sizeof(fallback_common));
6655  rootfallback.cc = (uschar *)re + re->name_table_offset + re->name_count * re->name_entry_size;  memset(common, 0, sizeof(compiler_common));
6656    rootfallback.cc = (pcre_uchar *)re + re->name_table_offset + re->name_count * re->name_entry_size;
6657    
 common->compiler = NULL;  
6658  common->start = rootfallback.cc;  common->start = rootfallback.cc;
 common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);  
6659  common->fcc = tables + fcc_offset;  common->fcc = tables + fcc_offset;
6660  common->lcc = (sljit_w)(tables + lcc_offset);  common->lcc = (sljit_w)(tables + lcc_offset);
6661    common->mode = mode;
6662  common->nltype = NLTYPE_FIXED;  common->nltype = NLTYPE_FIXED;
6663  switch(re->options & PCRE_NEWLINE_BITS)  switch(re->options & PCRE_NEWLINE_BITS)
6664    {    {
# Line 6158  else Line 6693  else
6693    }    }
6694  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;  common->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
6695  common->ctypes = (sljit_w)(tables + ctypes_offset);  common->ctypes = (sljit_w)(tables + ctypes_offset);
6696  common->name_table = (sljit_w)re + re->name_table_offset;  common->name_table = (sljit_w)((pcre_uchar *)re + re->name_table_offset);
6697  common->name_count = re->name_count;  common->name_count = re->name_count;
6698  common->name_entry_size = re->name_entry_size;  common->name_entry_size = re->name_entry_size;
 common->acceptlabel = NULL;  
 common->stubs = NULL;  
 common->entries = NULL;  
 common->currententry = NULL;  
 common->accept = NULL;  
 common->calllimit = NULL;  
 common->stackalloc = NULL;  
 common->revertframes = NULL;  
 common->wordboundary = NULL;  
 common->anynewline = NULL;  
 common->hspace = NULL;  
 common->vspace = NULL;  
 common->casefulcmp = NULL;  
 common->caselesscmp = NULL;  
6699  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;  common->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
6700  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
6701  common->utf8 = (re->options & PCRE_UTF8) != 0;  /* PCRE_UTF16 has the same value as PCRE_UTF8. */
6702    common->utf = (re->options & PCRE_UTF8) != 0;
6703  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
6704  common->useucp = (re->options & PCRE_UCP) != 0;  common->use_ucp = (re->options & PCRE_UCP) != 0;
 #endif  
 common->utf8readchar = NULL;  
 common->utf8readtype8 = NULL;  
 #endif  
 #ifdef SUPPORT_UCP  
 common->getucd = NULL;  
6705  #endif  #endif
6706    #endif /* SUPPORT_UTF */
6707  ccend = bracketend(rootfallback.cc);  ccend = bracketend(rootfallback.cc);
6708    
6709    /* Calculate the local space size on the stack. */
6710    common->ovector_start = CALL_LIMIT + sizeof(sljit_w);
6711    
6712  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);  SLJIT_ASSERT(*rootfallback.cc == OP_BRA && ccend[-(1 + LINK_SIZE)] == OP_KET);
6713  common->localsize = get_localspace(common, rootfallback.cc, ccend);  common->localsize = get_localspace(common, rootfallback.cc, ccend);
6714  if (common->localsize < 0)  if (common->localsize < 0)
6715    return;    return;
6716    
6717    /* Checking flags and updating ovector_start. */
6718    if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6719      {
6720      common->req_char_ptr = common->ovector_start;
6721      common->ovector_start += sizeof(sljit_w);
6722      }
6723    if (mode != JIT_COMPILE)
6724      {
6725      common->start_used_ptr = common->ovector_start;
6726      common->ovector_start += sizeof(sljit_w);
6727      if (mode == JIT_PARTIAL_SOFT_COMPILE)
6728        {
6729        common->hit_start = common->ovector_start;
6730        common->ovector_start += sizeof(sljit_w);
6731        }
6732      }
6733    if ((re->options & PCRE_FIRSTLINE) != 0)
6734      {
6735      common->first_line_end = common->ovector_start;
6736      common->ovector_start += sizeof(sljit_w);
6737      }
6738    
6739    /* Aligning ovector to even number of sljit words. */
6740    if ((common->ovector_start & sizeof(sljit_w)) != 0)
6741      common->ovector_start += sizeof(sljit_w);
6742    
6743    SLJIT_ASSERT(!(common->req_char_ptr != 0 && common->start_used_ptr != 0));
6744    common->cbraptr = OVECTOR_START + (re->top_bracket + 1) * 2 * sizeof(sljit_w);
6745  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);  common->localsize += common->cbraptr + (re->top_bracket + 1) * sizeof(sljit_w);
6746  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)  if (common->localsize > SLJIT_MAX_LOCAL_SIZE)
6747    return;    return;
6748  common->localptrs = (int*)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));  common->localptrs = (int *)SLJIT_MALLOC((ccend - rootfallback.cc) * sizeof(int));
6749  if (!common->localptrs)  if (!common->localptrs)
6750    return;    return;
6751  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));  memset(common->localptrs, 0, (ccend - rootfallback.cc) * sizeof(int));
# Line 6214  sljit_emit_enter(compiler, 1, 5, 5, comm Line 6764  sljit_emit_enter(compiler, 1, 5, 5, comm
6764    
6765  /* Register init. */  /* Register init. */
6766  reset_ovector(common, (re->top_bracket + 1) * 2);  reset_ovector(common, (re->top_bracket + 1) * 2);
6767  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6768    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, SLJIT_TEMPORARY_REG1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->req_char_ptr, SLJIT_TEMPORARY_REG1, 0);
6769    
6770  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, ARGUMENTS, 0, SLJIT_SAVED_REG1, 0);
6771  OP1(SLJIT_MOV, TMP1, 0, SLJIT_GENERAL_REG1, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_SAVED_REG1, 0);
6772  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str));
6773  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));  OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, end));
6774  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, stack));
# Line 6227  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1( Line 6777  OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(
6777  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));  OP1(SLJIT_MOV, STACK_LIMIT, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(struct sljit_stack, limit));
6778  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT, TMP1, 0);
6779    
6780    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6781      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6782    
6783  /* Main part of the matching */  /* Main part of the matching */
6784  if ((re->options & PCRE_ANCHORED) == 0)  if ((re->options & PCRE_ANCHORED) == 0)
6785    {    {
6786    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);    mainloop = mainloop_entry(common, (re->flags & PCRE_HASCRORLF) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6787    /* Forward search if possible. */    /* Forward search if possible. */
6788    if ((re->flags & PCRE_FIRSTSET) != 0)    if ((re->flags & PCRE_FIRSTSET) != 0)
6789      fast_forward_first_byte(common, re->first_byte, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_first_char(common, (pcre_uchar)re->first_char, (re->flags & PCRE_FCH_CASELESS) != 0, (re->options & PCRE_FIRSTLINE) != 0);
6790    else if ((re->flags & PCRE_STARTLINE) != 0)    else if ((re->flags & PCRE_STARTLINE) != 0)
6791      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_newline(common, (re->options & PCRE_FIRSTLINE) != 0);
6792    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)    else if ((re->flags & PCRE_STARTLINE) == 0 && study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)
6793      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);      fast_forward_start_bits(common, (sljit_uw)study->start_bits, (re->options & PCRE_FIRSTLINE) != 0);
6794    }    }
6795  if ((re->flags & PCRE_REQCHSET) != 0)  if (mode == JIT_COMPILE && (re->flags & PCRE_REQCHSET) != 0)
6796    reqbyte_notfound = search_requested_char(common, re->req_byte, (re->flags & PCRE_FIRSTSET) != 0);    reqbyte_notfound = search_requested_char(common, (pcre_uchar)re->req_char, (re->flags & PCRE_RCH_CASELESS) != 0, (re->flags & PCRE_FIRSTSET) != 0);
6797    
6798  /* Store the current STR_PTR in OVECTOR(0). */  /* Store the current STR_PTR in OVECTOR(0). */
6799  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);
6800  /* Copy the limit of allowed recursions. */  /* Copy the limit of allowed recursions. */
6801  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);  OP1(SLJIT_MOV, CALL_COUNT, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CALL_LIMIT);
6802    /* Copy the beginning of the string. */
6803    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6804      {
6805      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0);
6806      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6807      JUMPHERE(jump);
6808      }
6809    else if (mode == JIT_PARTIAL_HARD_COMPILE)
6810      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, STR_PTR, 0);
6811    
6812  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);  compile_hotpath(common, rootfallback.cc, ccend, &rootfallback);
6813  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))  if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 6265  if (common->accept != NULL) Line 6827  if (common->accept != NULL)
6827  /* This means we have a match. Update the ovector. */  /* This means we have a match. Update the ovector. */
6828  copy_ovector(common, re->top_bracket + 1);  copy_ovector(common, re->top_bracket + 1);
6829  leave = LABEL();  leave = LABEL();
6830  sljit_emit_return(compiler, SLJIT_UNUSED, 0);  sljit_emit_return(compiler, SLJIT_MOV, SLJIT_RETURN_REG, 0);
6831    
6832    if (mode != JIT_COMPILE)
6833      {
6834      common->partialmatchlabel = LABEL();
6835      set_jumps(common->partialmatch, common->partialmatchlabel);
6836      return_with_partial_match(common, leave);
6837      }
6838    
6839  empty_match_fallback = LABEL();  empty_match_fallback = LABEL();
6840  compile_fallbackpath(common, rootfallback.top);  compile_fallbackpath(common, rootfallback.top);
# Line 6278  if (SLJIT_UNLIKELY(sljit_get_compiler_er Line 6847  if (SLJIT_UNLIKELY(sljit_get_compiler_er
6847    
6848  SLJIT_ASSERT(rootfallback.prev == NULL);  SLJIT_ASSERT(rootfallback.prev == NULL);
6849    
6850    if (mode == JIT_PARTIAL_SOFT_COMPILE)
6851      {
6852      /* Update hit_start only in the first time. */
6853      jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, -1);
6854      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr);
6855      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->start_used_ptr, SLJIT_IMM, -1);
6856      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, TMP1, 0);
6857      JUMPHERE(jump);
6858      }
6859    
6860  /* Check we have remaining characters. */  /* Check we have remaining characters. */
6861  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));  OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0));
6862    
# Line 6285  if ((re->options & PCRE_ANCHORED) == 0) Line 6864  if ((re->options & PCRE_ANCHORED) == 0)
6864    {    {
6865    if ((re->options & PCRE_FIRSTLINE) == 0)    if ((re->options & PCRE_FIRSTLINE) == 0)
6866      {      {
6867      if (study != NULL && study->minlength > 1)      if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6868        {        {
6869        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, study->minlength);        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
6870        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);        CMPTO(SLJIT_C_LESS_EQUAL, TMP1, 0, STR_END, 0, mainloop);
6871        }        }
6872      else      else
# Line 6295  if ((re->options & PCRE_ANCHORED) == 0) Line 6874  if ((re->options & PCRE_ANCHORED) == 0)
6874      }      }
6875    else    else
6876      {      {
6877      if (study != NULL && study->minlength > 1)      SLJIT_ASSERT(common->first_line_end != 0);
6878        if (mode == JIT_COMPILE && study != NULL && study->minlength > 1)
6879        {        {
6880        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, study->minlength);        OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(study->minlength));
6881        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, TMP1, 0, STR_END, 0);
6882        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);        COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER);
6883        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END);        OP2(SLJIT_SUB | SLJIT_SET_U, SLJIT_UNUSED, 0, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end);
6884        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);        COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_GREATER_EQUAL);
6885        JUMPTO(SLJIT_C_ZERO, mainloop);        JUMPTO(SLJIT_C_ZERO, mainloop);
6886        }        }
6887      else      else
6888        CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, mainloop);        CMPTO(SLJIT_C_LESS, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), common->first_line_end, mainloop);
6889      }      }
6890    }    }
6891    
6892    /* No more remaining characters. */
6893  if (reqbyte_notfound != NULL)  if (reqbyte_notfound != NULL)
6894    JUMPHERE(reqbyte_notfound);    JUMPHERE(reqbyte_notfound);
6895  /* Copy OVECTOR(1) to OVECTOR(0) */  
6896  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));  if (mode == JIT_PARTIAL_SOFT_COMPILE)
6897      CMPTO(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), common->hit_start, SLJIT_IMM, 0, common->partialmatchlabel);
6898