/[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 696 by zherczeg, Sun Sep 18 15:09:49 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) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_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  } executable_function;    sljit_uw executable_sizes[JIT_NUMBER_OF_COMPILE_MODES];
170    } executable_functions;
171    
172  typedef struct jump_list {  typedef struct jump_list {
173    struct sljit_jump *jump;    struct sljit_jump *jump;
# Line 194  typedef struct fallback_common { Line 198  typedef struct fallback_common {
198    struct fallback_common *top;    struct fallback_common *top;
199    jump_list *topfallbacks;    jump_list *topfallbacks;
200    /* Opcode pointer. */    /* Opcode pointer. */
201    uschar *cc;    pcre_uchar *cc;
202  } fallback_common;  } fallback_common;
203    
204  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 265  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
269    
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    uschar *start;    pcre_uchar *start;
273    
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;
298    int endonly;    int endonly;
299    sljit_w ctypes;    sljit_w ctypes;
300      sljit_uw name_table;
301      sljit_w name_count;
302      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 291  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 310  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 331  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 352  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 saved local variables */  
 #define LOCALS_HEAD      (4 * sizeof(sljit_w))  
 /* Head of the last recursion. */  
 #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  
400  /* Max limit of recursions. */  /* Max limit of recursions. */
401  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (4 * sizeof(sljit_w))
 /* Last known position of the requested byte. */  
 #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  
 /* End pointer of the first line. */  
 #define FIRSTLINE_END    (9 * 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    (10 * 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 393  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 414  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 469  switch(*cc) Line 518  switch(*cc)
518    case OP_SKIPZERO:    case OP_SKIPZERO:
519    return cc + 1;    return cc + 1;
520    
521      case OP_ANYBYTE:
522    #ifdef SUPPORT_UTF
523      if (common->utf) return NULL;
524    #endif
525      return cc + 1;
526    
527    case OP_CHAR:    case OP_CHAR:
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 511  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 532  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 547  switch(*cc) Line 603  switch(*cc)
603    case OP_REF:    case OP_REF:
604    case OP_REFI:    case OP_REFI:
605    case OP_CREF:    case OP_CREF:
606      case OP_NCREF:
607      case OP_RREF:
608      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 571  switch(*cc) Line 630  switch(*cc)
630    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
631    case OP_REVERSE:    case OP_REVERSE:
632    case OP_ONCE:    case OP_ONCE:
633      case OP_ONCE_NC:
634    case OP_BRA:    case OP_BRA:
635    case OP_BRAPOS:    case OP_BRAPOS:
636    case OP_COND:    case OP_COND:
# Line 588  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 609  while (cc < ccend) Line 669  while (cc < ccend)
669      case OP_ASSERTBACK:      case OP_ASSERTBACK:
670      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
671      case OP_ONCE:      case OP_ONCE:
672        case OP_ONCE_NC:
673      case OP_BRAPOS:      case OP_BRAPOS:
674      case OP_SBRA:      case OP_SBRA:
675      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 620  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 631  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 641  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 654  while (cc < ccend) Line 725  while (cc < ccend)
725      case OP_ASSERTBACK:      case OP_ASSERTBACK:
726      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
727      case OP_ONCE:      case OP_ONCE:
728        case OP_ONCE_NC:
729      case OP_BRAPOS:      case OP_BRAPOS:
730      case OP_SBRA:      case OP_SBRA:
731      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 667  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 690  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);
 uschar *end;  
768  int length = 0;  int length = 0;
769  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
770  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
771    
772  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
# Line 720  while (cc < ccend) Line 790  while (cc < ccend)
790      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
791      break;      break;
792    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     if (needs_frame || length > 0)  
       {  
       cc = bracketend(cc);  
       break;  
       }  
     /* Check whether a frame must be created. */  
     end = bracketend(cc);  
     while (cc < end)  
       {  
       if (*cc == OP_SET_SOM || *cc == OP_CBRA || *cc == OP_CBRAPOS  
           || *cc == OP_SCBRA || *cc == OP_SCBRAPOS || *cc == OP_RECURSE)  
         needs_frame = TRUE;  
       cc = next_opcode(common, cc);  
       SLJIT_ASSERT(cc != NULL);  
       }  
     break;  
   
793      case OP_CBRA:      case OP_CBRA:
794      case OP_CBRAPOS:      case OP_CBRAPOS:
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 757  while (cc < ccend) Line 805  while (cc < ccend)
805      }      }
806    
807  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
808  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
809    return -1;    return -1;
810    
811  if (length > 0)  if (length > 0)
812    return length + 2;    return length + 1;
813  return needs_frame ? 0 : -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  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
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  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
824    {  SLJIT_UNUSED_ARG(stacktop);
825    SLJIT_ASSERT(stackpos + 1 == stacktop);  SLJIT_ASSERT(stackpos >= stacktop + 2);
   return;  
   }  
826    
827  stackpos = STACK(stackpos);  stackpos = STACK(stackpos);
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
 OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacktop), TMP1, 0);  
   
828  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
829    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
830  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 804  while (cc < ccend) Line 845  while (cc < ccend)
845      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
846      break;      break;
847    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
848      case OP_CBRA:      case OP_CBRA:
849      case OP_CBRAPOS:      case OP_CBRAPOS:
850      case OP_SCBRA:      case OP_SCBRA:
# Line 826  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 836  while (cc < ccend) Line 869  while (cc < ccend)
869      }      }
870    
871  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
872  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  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 853  while (cc < ccend) Line 886  while (cc < ccend)
886      case OP_ASSERTBACK:      case OP_ASSERTBACK:
887      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
888      case OP_ONCE:      case OP_ONCE:
889        case OP_ONCE_NC:
890      case OP_BRAPOS:      case OP_BRAPOS:
891      case OP_SBRA:      case OP_SBRA:
892      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 864  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 891  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 900  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 935  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 955  while (status != end) Line 989  while (status != end)
989        case OP_ASSERTBACK:        case OP_ASSERTBACK:
990        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
991        case OP_ONCE:        case OP_ONCE:
992          case OP_ONCE_NC:
993        case OP_BRAPOS:        case OP_BRAPOS:
994        case OP_SBRA:        case OP_SBRA:
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 969  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 987  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 1195  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 1219  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 1244  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 * 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 1272  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 1292  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 1321  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 1339  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 1350  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 SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  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;  DEFINE_COMPILER;
1506  add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));  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 void fallback_at_str_end(compiler_common *common, jump_list **fallbacks)
1534    {
1535    DEFINE_COMPILER;
1536    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 1365  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    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1576    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    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 1387  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    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1603    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    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 1408  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    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1634    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 192);    add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL));
   add_jump(compiler, &common->utf8readtype8, JUMP(SLJIT_FAST_CALL));  
1635    JUMPHERE(jump);    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);
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 1472  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 (>= 192). 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;
1734    
# Line 1489  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 (>= 192) 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 1573  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 1590  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);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), (sljit_w)PRIV(utf8_table4) - 0xc0);
 OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  
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 1615  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 1635  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_UTF
1891    struct sljit_jump *singlechar;
1892    #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 1646  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 1682  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 1694  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  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1968  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1969    if (common->utf)
1970    {    {
1971    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1972      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(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    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
1988  #endif  #endif
1989  JUMPHERE(start);  JUMPHERE(start);
1990    
# Line 1727  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 1767  else Line 2044  else
2044      }      }
2045    }    }
2046    
2047  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2048  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2049    if (common->utf)
2050    {    {
2051    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2052      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    }    }
 else  
   OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
 #else  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  
2066  #endif  #endif
2067  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2068  JUMPHERE(found);  JUMPHERE(found);
# Line 1800  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 1811  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 1851  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 1871  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_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2182    #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  #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);
# Line 1892  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    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2198  else  #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  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2201  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2202      {
2203      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2204      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);
2217      }
2218  #endif  #endif
2219  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2220  JUMPHERE(found);  JUMPHERE(found);
# Line 1908  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 1917  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 1966  return notfound; Line 2290  return notfound;
2290  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2291  {  {
2292  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2293  struct sljit_jump *jump;  struct sljit_jump *jump;
2294  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2295    
2296  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);
2297  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2298    
2299  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2300  mainloop = LABEL();  mainloop = LABEL();
2301  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2302  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
# Line 1987  JUMPTO(SLJIT_JUMP, mainloop); Line 2309  JUMPTO(SLJIT_JUMP, mainloop);
2309  JUMPHERE(jump);  JUMPHERE(jump);
2310  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2311  /* End of dropping frames. */  /* End of dropping frames. */
 OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
 CMPTO(SLJIT_C_GREATER_EQUAL, TMP1, 0, STACK_TOP, 0, mainloop);  
 JUMPHERE(earlyexit);  
2312  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2313    
2314  JUMPHERE(jump);  JUMPHERE(jump);
# Line 2010  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    
2336  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2337    
2338  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);  sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, 1, 5, 5, common->localsize);
2339  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
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 2045  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 2084  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 2115  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 2139  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 2155  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 2173  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 2199  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 2231  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 2255  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 2294  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 2391  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 2422  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 2430  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;
2823  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2824    unsigned int typeoffset;
2825  #endif  #endif
2826  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2827    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 2455  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 2473  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 2483  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 2558  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 2588  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 2619  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 2628  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 2685  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 2749  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 2785  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 2793  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 2801  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 2824  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      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);      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);
3236        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]);
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;
3254    
3255      case OP_ANYBYTE:
3256      fallback_at_str_end(common, fallbacks);
3257      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 2852  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 2869  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 2877  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 2885  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 2901  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 2954  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 2977  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 3006  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 3014  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 3037  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 3071  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);
       OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);  
3558        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3559          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, c));
3560        else        else
3561          {          {
3562          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */          /* Since UTF8 code page is fixed, we know that c is in [a-z] or [A-Z] range. */
3563          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3564          add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 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, TMP2, 0);        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3568        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3569          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);
3571          JUMPHERE(jump[0]);
3572          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 3129  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 3142  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 3165  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 3204  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 3229  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 3242  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 3252  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 3262  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 3274  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 3303  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 3328  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 3354  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 3379  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 3501  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 3547  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 3571  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 3630  while (1) Line 4146  while (1)
4146    if (common->accept != NULL)    if (common->accept != NULL)
4147      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
4148    
4149      /* Reset stack. */
4150    if (framesize < 0)    if (framesize < 0)
4151      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4152      else {
4153        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
4154          {
4155          /* We don't need to keep the STR_PTR, only the previous localptr. */
4156          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4157          }
4158        else
4159          {
4160          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4161          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
4162          }
4163      }
4164    
4165    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
4166      {      {
4167      /* We know that STR_PTR was stored on the top of the stack. */      /* We know that STR_PTR was stored on the top of the stack. */
4168      if (conditional)      if (conditional)
4169        {        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
       if (framesize < 0)  
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);  
       else  
         {  
         OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
         }  
       }  
4170      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
4171        {        {
4172        if (framesize < 0)        if (framesize < 0)
4173          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4174        else        else
4175          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
4176          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
4177          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), (framesize + 1) * sizeof(sljit_w));
4178          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3661  while (1) Line 4180  while (1)
4180        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));        OP2(SLJIT_ADD, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, sizeof(sljit_w));
4181        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
4182        }        }
4183      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
4184        {        {
4185        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
4186          {        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
         OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), framesize * sizeof(sljit_w));  
         }  
4187        }        }
4188      }      }
4189    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3695  if (opcode == OP_ASSERT || opcode == OP_ Line 4210  if (opcode == OP_ASSERT || opcode == OP_
4210    /* Assert is failed. */    /* Assert is failed. */
4211    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
4212      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4213    
4214    if (framesize < 0)    if (framesize < 0)
4215      {      {
4216      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3706  if (opcode == OP_ASSERT || opcode == OP_ Line 4222  if (opcode == OP_ASSERT || opcode == OP_
4222    else    else
4223      {      {
4224      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
     if (framesize > 0)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
4225      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4226      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
4227        {        {
# Line 3717  if (opcode == OP_ASSERT || opcode == OP_ Line 4231  if (opcode == OP_ASSERT || opcode == OP_
4231      else      else
4232        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4233      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
     if (framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
4234      }      }
4235    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
4236    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3741  if (opcode == OP_ASSERT || opcode == OP_ Line 4253  if (opcode == OP_ASSERT || opcode == OP_
4253      }      }
4254    else    else
4255      {      {
4256      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      if (bra == OP_BRA)
     OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(TMP1), (framesize + 1) * sizeof(sljit_w));  
     if (bra == OP_BRAZERO)  
4257        {        {
4258        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4259        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
4260          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
4261        }        }
4262      else if (bra == OP_BRAMINZERO)      else
4263        {        {
4264        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4265        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 2) * sizeof(sljit_w));
4266          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4267          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4268        }        }
4269      }      }
4270    
# Line 3788  else Line 4301  else
4301      {      {
4302      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4303      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
     if (framesize > 0)  
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
4304      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4305      if (bra != OP_BRA)      if (bra != OP_BRA)
4306        {        {
# Line 3799  else Line 4310  else
4310      else      else
4311        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4312      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
     if (framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP2, 0);  
4313      }      }
4314    
4315    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3824  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, pcre_uchar *name_table)
4337    {
4338    int condition = FALSE;
4339    pcre_uchar *slotA = name_table;
4340    pcre_uchar *slotB;
4341    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4342    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4343    sljit_w no_capture;
4344    int i;
4345    
4346    locals += refno & 0xff;
4347    refno >>= 8;
4348    no_capture = locals[1];
4349    
4350    for (i = 0; i < name_count; i++)
4351      {
4352      if (GET2(slotA, 0) == refno) break;
4353      slotA += name_entry_size;
4354      }
4355    
4356    if (i < name_count)
4357      {
4358      /* Found a name for the number - there can be only one; duplicate names
4359      for different numbers are allowed, but not vice versa. First scan down
4360      for duplicates. */
4361    
4362      slotB = slotA;
4363      while (slotB > name_table)
4364        {
4365        slotB -= name_entry_size;
4366        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4367          {
4368          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4369          if (condition) break;
4370          }
4371        else break;
4372        }
4373    
4374      /* Scan up for duplicates */
4375      if (!condition)
4376        {
4377        slotB = slotA;
4378        for (i++; i < name_count; i++)
4379          {
4380          slotB += name_entry_size;
4381          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4382            {
4383            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4384            if (condition) break;
4385            }
4386          else break;
4387          }
4388        }
4389      }
4390    return condition;
4391    }
4392    
4393    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4394    {
4395    int condition = FALSE;
4396    pcre_uchar *slotA = name_table;
4397    pcre_uchar *slotB;
4398    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4399    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4400    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4401    int i;
4402    
4403    for (i = 0; i < name_count; i++)
4404      {
4405      if (GET2(slotA, 0) == recno) break;
4406      slotA += name_entry_size;
4407      }
4408    
4409    if (i < name_count)
4410      {
4411      /* Found a name for the number - there can be only one; duplicate
4412      names for different numbers are allowed, but not vice versa. First
4413      scan down for duplicates. */
4414    
4415      slotB = slotA;
4416      while (slotB > name_table)
4417        {
4418        slotB -= name_entry_size;
4419        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4420          {
4421          condition = GET2(slotB, 0) == group_num;
4422          if (condition) break;
4423          }
4424        else break;
4425        }
4426    
4427      /* Scan up for duplicates */
4428      if (!condition)
4429        {
4430        slotB = slotA;
4431        for (i++; i < name_count; i++)
4432          {
4433          slotB += name_entry_size;
4434          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4435            {
4436            condition = GET2(slotB, 0) == group_num;
4437            if (condition) break;
4438            }
4439          else break;
4440          }
4441        }
4442      }
4443    return condition;
4444    }
4445    
4446  /*  /*
4447    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4448    
# Line 3871  return cc + 1 + LINK_SIZE; Line 4490  return cc + 1 + LINK_SIZE;
4490      M - Any values pushed by the current alternative. Can be empty, or anything.      M - Any values pushed by the current alternative. Can be empty, or anything.
4491    
4492    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4493    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4494    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4495    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4496                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4497                                              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 3907  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4527  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4527    
4528  opcode = *cc;  opcode = *cc;
4529  ccbegin = cc;  ccbegin = cc;
4530    hotpath = ccbegin + 1 + LINK_SIZE;
4531    
4532  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)  if ((opcode == OP_COND || opcode == OP_SCOND) && cc[1 + LINK_SIZE] == OP_DEF)
4533    {    {
4534    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3918  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4540  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4540  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4541  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));  SLJIT_ASSERT(!((bra == OP_BRAZERO && ket == OP_KETRMIN) || (bra == OP_BRAMINZERO && ket == OP_KETRMAX)));
4542  cc += GET(cc, 1);  cc += GET(cc, 1);
4543  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4544    has_alternatives = *cc == OP_ALT;
4545    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4546      {
4547      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4548      if (*hotpath == OP_NRREF)
4549        {
4550        stacksize = GET2(hotpath, 1);
4551        if (common->currententry == NULL || stacksize == RREF_ANY)
4552          has_alternatives = FALSE;
4553        else if (common->currententry->start == 0)
4554          has_alternatives = stacksize != 0;
4555        else
4556          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4557        }
4558      }
4559    
4560  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4561    opcode = OP_SCOND;    opcode = OP_SCOND;
4562    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4563      opcode = OP_ONCE;
4564    
4565  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4566    {    {
# Line 3929  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 += 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 4085  else if (has_alternatives) Line 4726  else if (has_alternatives)
4726    }    }
4727    
4728  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4729  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4730    {    {
4731    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4732      {      {
4733        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)
4739        {
4740        SLJIT_ASSERT(has_alternatives);
4741        stacksize = GET2(hotpath, 1);
4742        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4743    
4744        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);
4746        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 << 8) | (common->ovector_start / sizeof(sljit_w)));
4748        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4749        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));
4751        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4752        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4753    
4754        JUMPHERE(jump);
4755        hotpath += 1 + IMM2_SIZE;
4756        }
4757      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4758        {
4759        /* Never has other case. */
4760        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4761    
4762        stacksize = GET2(hotpath, 1);
4763        if (common->currententry == NULL)
4764          stacksize = 0;
4765        else if (stacksize == RREF_ANY)
4766          stacksize = 1;
4767        else if (common->currententry->start == 0)
4768          stacksize = stacksize == 0;
4769        else
4770          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4771    
4772        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4773          {
4774          SLJIT_ASSERT(!has_alternatives);
4775          if (stacksize != 0)
4776            hotpath += 1 + IMM2_SIZE;
4777          else
4778            {
4779            if (*cc == OP_ALT)
4780              {
4781              hotpath = cc + 1 + LINK_SIZE;
4782              cc += GET(cc, 1);
4783              }
4784            else
4785              hotpath = cc;
4786            }
4787          }
4788        else
4789          {
4790          SLJIT_ASSERT(has_alternatives);
4791    
4792          stacksize = GET2(hotpath, 1);
4793          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4794          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4795          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4796          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4797          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4798          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4799          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4800          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);
4802          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4803          hotpath += 1 + IMM2_SIZE;
4804          }
4805      }      }
4806    else    else
4807      {      {
4808      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4809      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4810      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4811      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4128  if (opcode == OP_ONCE) Line 4835  if (opcode == OP_ONCE)
4835        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
4836        }        }
4837      }      }
4838    else if (ket == OP_KETRMAX)    else
4839      {      {
4840      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4841      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (FALLBACK_AS(bracket_fallback)->u.framesize + stacksize) * sizeof(sljit_w));
4842      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4843          {
4844          /* TMP2 which is set here used by OP_KETRMAX below. */
4845          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4846          }
4847      }      }
4848    }    }
4849    
# Line 4197  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 4225  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 4249  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 4264  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 4366  while (*cc != OP_KETRPOS) Line 5077  while (*cc != OP_KETRPOS)
5077      {      {
5078      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5079        {        {
5080          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
5081        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
5082        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);
5083        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
5084        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
# Line 4376  while (*cc != OP_KETRPOS) Line 5086  while (*cc != OP_KETRPOS)
5086      else      else
5087        {        {
5088        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5089          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
5090        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
5091          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));          OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w));
5092        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (framesize + 1) * sizeof(sljit_w), STR_PTR, 0);
# Line 4384  while (*cc != OP_KETRPOS) Line 5095  while (*cc != OP_KETRPOS)
5095      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
5096        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));        add_jump(compiler, &emptymatch, CMP(SLJIT_C_EQUAL, TMP1, 0, STR_PTR, 0));
5097    
     /* TMP2 must be set above. */  
5098      if (!zero)      if (!zero)
5099        {        {
5100        if (framesize < 0)        if (framesize < 0)
5101          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(stacksize - 1), SLJIT_IMM, 0);
5102        else        else
5103          OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), (stacksize - 1) * sizeof(sljit_w), SLJIT_IMM, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
5104        }        }
5105      }      }
5106    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4412  while (*cc != OP_KETRPOS) Line 5122  while (*cc != OP_KETRPOS)
5122      {      {
5123      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
5124        {        {
5125          /* Last alternative. */
5126        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
5127          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5128        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
# Line 4443  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 4482  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 4493  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 4505  else Line 5216  else
5216        *opcode = OP_EXACT;        *opcode = OP_EXACT;