/[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 664 by ph10, Mon Aug 22 14:54:38 2011 UTC revision 850 by zherczeg, Wed Jan 4 17:29:11 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 119  The generated code will be the following Line 122  The generated code will be the following
122   jump to D hot path   jump to D hot path
123   C fallback path   C fallback path
124   A fallback path   A fallback path
125    
126   Notice, that the order of fallback code paths are the opposite of the fast   Notice, that the order of fallback code paths are the opposite of the fast
127   code paths. In this way the topmost value on the stack is always belong   code paths. In this way the topmost value on the stack is always belong
128   to the current fallback code path. The fallback code path must check   to the current fallback code path. The fallback code path must check
# 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    uschar notbol;    int calllimit;
159    uschar noteol;    pcre_uint8 notbol;
160    uschar notempty;    pcre_uint8 noteol;
161    uschar notempty_atstart;    pcre_uint8 notempty;
162      pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_function {
166    void *executable_func;    void *executable_func;
167    pcre_jit_callback callback;    pcre_jit_callback callback;
168    void *userdata;    void *userdata;
169      sljit_uw executable_size;
170  } executable_function;  } executable_function;
171    
172  typedef struct jump_list {  typedef struct jump_list {
# Line 169  typedef struct jump_list { Line 174  typedef struct jump_list {
174    struct jump_list *next;    struct jump_list *next;
175  } jump_list;  } jump_list;
176    
177  enum stub_types { stack_alloc, max_index };  enum stub_types { stack_alloc };
178    
179  typedef struct stub_list {  typedef struct stub_list {
180    enum stub_types type;    enum stub_types type;
# Line 193  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 264  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
269    
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    uschar *start;    pcre_uchar *start;
273    int localsize;    int localsize;
274    int *localptrs;    int *localptrs;
275    const uschar *fcc;    const pcre_uint8 *fcc;
276    sljit_w lcc;    sljit_w lcc;
277    int cbraptr;    int cbraptr;
278    int nltype;    int nltype;
# Line 275  typedef struct compiler_common { Line 280  typedef struct compiler_common {
280    int bsr_nltype;    int bsr_nltype;
281    int endonly;    int endonly;
282    sljit_w ctypes;    sljit_w ctypes;
283      sljit_uw name_table;
284      sljit_w name_count;
285      sljit_w name_entry_size;
286    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
287    stub_list *stubs;    stub_list *stubs;
288    recurse_entry *entries;    recurse_entry *entries;
289    recurse_entry *currententry;    recurse_entry *currententry;
290    jump_list *accept;    jump_list *accept;
291      jump_list *calllimit;
292    jump_list *stackalloc;    jump_list *stackalloc;
293    jump_list *revertframes;    jump_list *revertframes;
294    jump_list *wordboundary;    jump_list *wordboundary;
# Line 289  typedef struct compiler_common { Line 298  typedef struct compiler_common {
298    jump_list *casefulcmp;    jump_list *casefulcmp;
299    jump_list *caselesscmp;    jump_list *caselesscmp;
300    BOOL jscript_compat;    BOOL jscript_compat;
301  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
302    BOOL utf8;    BOOL utf;
303  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
304    BOOL useucp;    BOOL use_ucp;
305  #endif  #endif
306    jump_list *utf8readchar;    jump_list *utfreadchar;
307    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
308      jump_list *utfreadtype8;
309  #endif  #endif
310    #endif /* SUPPORT_UTF */
311  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
312    jump_list *getucd;    jump_list *getucd;
313  #endif  #endif
# Line 308  typedef struct compare_context { Line 319  typedef struct compare_context {
319    int length;    int length;
320    int sourcereg;    int sourcereg;
321  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
322    int byteptr;    int ucharptr;
323    union {    union {
324      int asint;      sljit_i asint;
325      short asshort;      sljit_uh asushort;
326    #ifdef COMPILE_PCRE8
327      sljit_ub asbyte;      sljit_ub asbyte;
328      sljit_ub asbytes[4];      sljit_ub asuchars[4];
329    #else
330    #ifdef COMPILE_PCRE16
331        sljit_uh asuchars[2];
332    #endif
333    #endif
334    } c;    } c;
335    union {    union {
336      int asint;      sljit_i asint;
337      short asshort;      sljit_uh asushort;
338    #ifdef COMPILE_PCRE8
339      sljit_ub asbyte;      sljit_ub asbyte;
340      sljit_ub asbytes[4];      sljit_ub asuchars[4];
341    #else
342    #ifdef COMPILE_PCRE16
343        sljit_uh asuchars[2];
344    #endif
345    #endif
346    } oc;    } oc;
347  #endif  #endif
348  } compare_context;  } compare_context;
349    
350  enum {  enum {
351    frame_end = 0,    frame_end = 0,
352    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
353  };  };
354    
355  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
# Line 341  enum { Line 363  enum {
363  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
364  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_GENERAL_REG3
365  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_GENERAL_EREG1
366  #define MAX_INDEX     SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_GENERAL_EREG2
367  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
368    
369  /* Locals layout. */  /* Locals layout. */
# Line 351  enum { Line 373  enum {
373  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
374  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
375  #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))  
376  /* Head of the last recursion. */  /* Head of the last recursion. */
377  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
378    /* Max limit of recursions. */
379    #define CALL_LIMIT       (5 * sizeof(sljit_w))
380  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
381  #define REQ_BYTE_PTR     (6 * sizeof(sljit_w))  #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
382  /* End pointer of the first line. */  /* End pointer of the first line. */
383  #define FIRSTLINE_END    (7 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
384  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
# Line 366  the start pointers when the end of the c Line 388  the start pointers when the end of the c
388  #define OVECTOR_START    (8 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
389  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
390  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
391  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
392    
393    #ifdef COMPILE_PCRE8
394    #define MOV_UCHAR  SLJIT_MOV_UB
395    #define MOVU_UCHAR SLJIT_MOVU_UB
396    #else
397    #ifdef COMPILE_PCRE16
398    #define MOV_UCHAR  SLJIT_MOV_UH
399    #define MOVU_UCHAR SLJIT_MOVU_UH
400    #else
401    #error Unsupported compiling mode
402    #endif
403    #endif
404    
405  /* Shortcuts. */  /* Shortcuts. */
406  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 390  the start pointers when the end of the c Line 424  the start pointers when the end of the c
424  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
425    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
426    
427  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
428  {  {
429  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));
430  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 399  cc += 1 + LINK_SIZE; Line 433  cc += 1 + LINK_SIZE;
433  return cc;  return cc;
434  }  }
435    
436  /* Functions whose might need modification for all new supported opcodes:  /* Functions whose might need modification for all new supported opcodes:
437   next_opcode   next_opcode
438   get_localspace   get_localspace
439   set_localptrs   set_localptrs
# Line 411  return cc; Line 445  return cc;
445   compile_fallbackpath   compile_fallbackpath
446  */  */
447    
448  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
449  {  {
450  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
451  switch(*cc)  switch(*cc)
# Line 466  switch(*cc) Line 500  switch(*cc)
500    case OP_SKIPZERO:    case OP_SKIPZERO:
501    return cc + 1;    return cc + 1;
502    
503      case OP_ANYBYTE:
504    #ifdef SUPPORT_UTF
505      if (common->utf) return NULL;
506    #endif
507      return cc + 1;
508    
509    case OP_CHAR:    case OP_CHAR:
510    case OP_CHARI:    case OP_CHARI:
511    case OP_NOT:    case OP_NOT:
512    case OP_NOTI:    case OP_NOTI:
   
513    case OP_STAR:    case OP_STAR:
514    case OP_MINSTAR:    case OP_MINSTAR:
515    case OP_PLUS:    case OP_PLUS:
# Line 508  switch(*cc) Line 547  switch(*cc)
547    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
548    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
549    cc += 2;    cc += 2;
550  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
551    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]);
552  #endif  #endif
553    return cc;    return cc;
554    
# Line 529  switch(*cc) Line 568  switch(*cc)
568    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
569    case OP_NOTEXACTI:    case OP_NOTEXACTI:
570    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
571    cc += 4;    cc += 2 + IMM2_SIZE;
572  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
573    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]);
574  #endif  #endif
575    return cc;    return cc;
576    
577    case OP_NOTPROP:    case OP_NOTPROP:
578    case OP_PROP:    case OP_PROP:
579      return cc + 1 + 2;
580    
581    case OP_TYPEUPTO:    case OP_TYPEUPTO:
582    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
583    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 544  switch(*cc) Line 585  switch(*cc)
585    case OP_REF:    case OP_REF:
586    case OP_REFI:    case OP_REFI:
587    case OP_CREF:    case OP_CREF:
588      case OP_NCREF:
589      case OP_RREF:
590      case OP_NRREF:
591    case OP_CLOSE:    case OP_CLOSE:
592    cc += 3;    cc += 1 + IMM2_SIZE;
593    return cc;    return cc;
594    
595    case OP_CRRANGE:    case OP_CRRANGE:
596    case OP_CRMINRANGE:    case OP_CRMINRANGE:
597    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
598    
599    case OP_CLASS:    case OP_CLASS:
600    case OP_NCLASS:    case OP_NCLASS:
601    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
602    
603  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
604    case OP_XCLASS:    case OP_XCLASS:
605    return cc + GET(cc, 1);    return cc + GET(cc, 1);
606  #endif  #endif
# Line 568  switch(*cc) Line 612  switch(*cc)
612    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
613    case OP_REVERSE:    case OP_REVERSE:
614    case OP_ONCE:    case OP_ONCE:
615      case OP_ONCE_NC:
616    case OP_BRA:    case OP_BRA:
617    case OP_BRAPOS:    case OP_BRAPOS:
618    case OP_COND:    case OP_COND:
# Line 585  switch(*cc) Line 630  switch(*cc)
630    case OP_CBRAPOS:    case OP_CBRAPOS:
631    case OP_SCBRA:    case OP_SCBRA:
632    case OP_SCBRAPOS:    case OP_SCBRAPOS:
633    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
634    
635    default:    default:
636    return NULL;    return NULL;
637    }    }
638  }  }
639    
640  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
641  {  {
642  int localspace = 0;  int localspace = 0;
643  uschar *alternative;  pcre_uchar *alternative;
644  /* 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. */
645  while (cc < ccend)  while (cc < ccend)
646    {    {
# Line 606  while (cc < ccend) Line 651  while (cc < ccend)
651      case OP_ASSERTBACK:      case OP_ASSERTBACK:
652      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
653      case OP_ONCE:      case OP_ONCE:
654        case OP_ONCE_NC:
655      case OP_BRAPOS:      case OP_BRAPOS:
656      case OP_SBRA:      case OP_SBRA:
657      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 617  while (cc < ccend) Line 663  while (cc < ccend)
663      case OP_CBRAPOS:      case OP_CBRAPOS:
664      case OP_SCBRAPOS:      case OP_SCBRAPOS:
665      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
666      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
667      break;      break;
668    
669      case OP_COND:      case OP_COND:
# Line 638  while (cc < ccend) Line 684  while (cc < ccend)
684  return localspace;  return localspace;
685  }  }
686    
687  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
688  {  {
689  uschar *cc = common->start;  pcre_uchar *cc = common->start;
690  uschar *alternative;  pcre_uchar *alternative;
691  while (cc < ccend)  while (cc < ccend)
692    {    {
693    switch(*cc)    switch(*cc)
# Line 651  while (cc < ccend) Line 697  while (cc < ccend)
697      case OP_ASSERTBACK:      case OP_ASSERTBACK:
698      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
699      case OP_ONCE:      case OP_ONCE:
700        case OP_ONCE_NC:
701      case OP_BRAPOS:      case OP_BRAPOS:
702      case OP_SBRA:      case OP_SBRA:
703      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 664  while (cc < ccend) Line 711  while (cc < ccend)
711      case OP_SCBRAPOS:      case OP_SCBRAPOS:
712      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
713      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
714      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
715      break;      break;
716    
717      case OP_COND:      case OP_COND:
# Line 687  while (cc < ccend) Line 734  while (cc < ccend)
734  }  }
735    
736  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
737  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
738  {  {
739  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
740  int length = 0;  int length = 0;
741  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
742  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
743    
744  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
745    {    {
746    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
747    possessive = TRUE;    possessive = TRUE;
748    }    }
749    
# Line 719  while (cc < ccend) Line 762  while (cc < ccend)
762      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
763      break;      break;
764    
     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;  
   
765      case OP_CBRA:      case OP_CBRA:
766      case OP_CBRAPOS:      case OP_CBRAPOS:
767      case OP_SCBRA:      case OP_SCBRA:
768      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
769      length += 3;      length += 3;
770      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
771      break;      break;
772    
773      default:      default:
# Line 761  while (cc < ccend) Line 777  while (cc < ccend)
777      }      }
778    
779  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
780  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
781    return -1;    return -1;
782    
783  if (length > 0)  if (length > 0)
784    return length + 2;    return length + 1;
785  return needs_frame ? 0 : -1;  return -1;
786  }  }
787    
788  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)
789  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
790  DEFINE_COMPILER;  DEFINE_COMPILER;
791  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
792  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
793  int offset;  int offset;
794    
795  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
796    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
797    
798  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);  
   
799  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
800    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
801  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 809  while (cc < ccend) Line 816  while (cc < ccend)
816      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
817      break;      break;
818    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
819      case OP_CBRA:      case OP_CBRA:
820      case OP_CBRAPOS:      case OP_CBRAPOS:
821      case OP_SCBRA:      case OP_SCBRA:
822      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_setmaxindex);  
       stackpos += (int)sizeof(sljit_w);  
       OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, MAX_INDEX, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
823      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
824      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
825      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 839  while (cc < ccend) Line 830  while (cc < ccend)
830      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
831      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
832    
833      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
834      break;      break;
835    
836      default:      default:
# Line 849  while (cc < ccend) Line 840  while (cc < ccend)
840      }      }
841    
842  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
843  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
844  }  }
845    
846  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)
847  {  {
848  int localsize = 2;  int localsize = 2;
849  uschar *alternative;  pcre_uchar *alternative;
850  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
851  while (cc < ccend)  while (cc < ccend)
852    {    {
# Line 866  while (cc < ccend) Line 857  while (cc < ccend)
857      case OP_ASSERTBACK:      case OP_ASSERTBACK:
858      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
859      case OP_ONCE:      case OP_ONCE:
860        case OP_ONCE_NC:
861      case OP_BRAPOS:      case OP_BRAPOS:
862      case OP_SBRA:      case OP_SBRA:
863      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 877  while (cc < ccend) Line 869  while (cc < ccend)
869      case OP_CBRA:      case OP_CBRA:
870      case OP_SCBRA:      case OP_SCBRA:
871      localsize++;      localsize++;
872      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
873      break;      break;
874    
875      case OP_CBRAPOS:      case OP_CBRAPOS:
876      case OP_SCBRAPOS:      case OP_SCBRAPOS:
877      localsize += 2;      localsize += 2;
878      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
879      break;      break;
880    
881      case OP_COND:      case OP_COND:
# Line 904  SLJIT_ASSERT(cc == ccend); Line 896  SLJIT_ASSERT(cc == ccend);
896  return localsize;  return localsize;
897  }  }
898    
899  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
900    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
901  {  {
902  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 913  int count; Line 905  int count;
905  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
906  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
907  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
908  uschar *alternative;  pcre_uchar *alternative;
909  enum {  enum {
910    start,    start,
911    loop,    loop,
# Line 968  while (status != end) Line 960  while (status != end)
960        case OP_ASSERTBACK:        case OP_ASSERTBACK:
961        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
962        case OP_ONCE:        case OP_ONCE:
963          case OP_ONCE_NC:
964        case OP_BRAPOS:        case OP_BRAPOS:
965        case OP_SBRA:        case OP_SBRA:
966        case OP_SBRAPOS:        case OP_SBRAPOS:
967        case OP_SCOND:        case OP_SCOND:
968        count = 1;        count = 1;
969        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
970        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
971        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
972        break;        break;
# Line 982  while (status != end) Line 975  while (status != end)
975        case OP_SCBRA:        case OP_SCBRA:
976        count = 1;        count = 1;
977        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
978        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
979        break;        break;
980    
981        case OP_CBRAPOS:        case OP_CBRAPOS:
982        case OP_SCBRAPOS:        case OP_SCBRAPOS:
983        count = 2;        count = 2;
984        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
985        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
986        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
987        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
988        break;        break;
989    
990        case OP_COND:        case OP_COND:
# Line 1000  while (status != end) Line 993  while (status != end)
993        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
994          {          {
995          count = 1;          count = 1;
996          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
997          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
998          }          }
999        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1164  while (list_item) Line 1157  while (list_item)
1157      case stack_alloc:      case stack_alloc:
1158      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1159      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, list_item->data);  
     break;  
1160      }      }
1161    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1162    list_item = list_item->next;    list_item = list_item->next;
# Line 1175  while (list_item) Line 1164  while (list_item)
1164  common->stubs = NULL;  common->stubs = NULL;
1165  }  }
1166    
1167    static SLJIT_INLINE void decrease_call_count(compiler_common *common)
1168    {
1169    DEFINE_COMPILER;
1170    
1171    OP2(SLJIT_SUB | SLJIT_SET_E, CALL_COUNT, 0, CALL_COUNT, 0, SLJIT_IMM, 1);
1172    add_jump(compiler, &common->calllimit, JUMP(SLJIT_C_ZERO));
1173    }
1174    
1175  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)  static SLJIT_INLINE void allocate_stack(compiler_common *common, int size)
1176  {  {
1177  /* May destroy all locals and registers except TMP2. */  /* May destroy all locals and registers except TMP2. */
# Line 1204  struct sljit_label *loop; Line 1201  struct sljit_label *loop;
1201  int i;  int i;
1202  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1203  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1204  OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  
1205  if (length < 8)  if (length < 8)
1206    {    {
1207    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1222  else Line 1218  else
1218    }    }
1219  }  }
1220    
1221  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1222  {  {
1223  DEFINE_COMPILER;  DEFINE_COMPILER;
1224  struct sljit_label *loop;  struct sljit_label *loop;
1225  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1226    
1227  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1228    OP1(SLJIT_MOV, SLJIT_GENERAL_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1229    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1230    
1231  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1232  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));
1233  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));
# Line 1240  loop = LABEL(); Line 1239  loop = LABEL();
1239  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1240  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1241  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1242    #ifdef COMPILE_PCRE16
1243    OP2(SLJIT_ASHR, SLJIT_GENERAL_REG2, 0, SLJIT_GENERAL_REG2, 0, SLJIT_IMM, 1);
1244    #endif
1245  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);
1246  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);
1247  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1248  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1249    
1250    /* Calculate the return value, which is the maximum ovector value. */
1251    if (topbracket > 1)
1252      {
1253      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1254      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1255    
1256      /* OVECTOR(0) is never equal to SLJIT_GENERAL_REG3. */
1257      loop = LABEL();
1258      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1259      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1260      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_GENERAL_REG3, 0, loop);
1261      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1262      }
1263    else
1264      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1265  }  }
1266    
1267  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, uschar* cc)  static SLJIT_INLINE BOOL char_has_othercase(compiler_common *common, pcre_uchar* cc)
1268  {  {
1269  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1270  unsigned int c;  unsigned int c;
1271    
1272  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1273  if (common->utf8)  if (common->utf)
1274    {    {
1275    GETCHAR(c, cc);    GETCHAR(c, cc);
1276    if (c > 127)    if (c > 127)
# Line 1263  if (common->utf8) Line 1281  if (common->utf8)
1281      return FALSE;      return FALSE;
1282  #endif  #endif
1283      }      }
1284    #ifndef COMPILE_PCRE8
1285      return common->fcc[c] != c;
1286    #endif
1287    }    }
1288  else  else
1289  #endif  #endif
1290    c = *cc;    c = *cc;
1291  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1292  }  }
1293    
1294  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)
1295  {  {
1296  /* Returns with the othercase. */  /* Returns with the othercase. */
1297  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1298  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1299    {    {
1300  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1301    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1283  if (common->utf8 && c > 127) Line 1304  if (common->utf8 && c > 127)
1304  #endif  #endif
1305    }    }
1306  #endif  #endif
1307  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1308  }  }
1309    
1310  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)
1311  {  {
1312  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1313  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1314  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1315  int n;  int n;
1316  #endif  #endif
1317    
1318  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1319  if (common->utf8)  if (common->utf)
1320    {    {
1321    GETCHAR(c, cc);    GETCHAR(c, cc);
1322    if (c <= 127)    if (c <= 127)
# Line 1312  if (common->utf8) Line 1333  if (common->utf8)
1333  else  else
1334    {    {
1335    c = *cc;    c = *cc;
1336    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1337    }    }
1338  #else  #else
1339  c = *cc;  c = *cc;
1340  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1341  #endif  #endif
1342    
1343  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1330  if (c <= 127 && bit == 0x20) Line 1351  if (c <= 127 && bit == 0x20)
1351  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1352    return 0;    return 0;
1353    
1354  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1355  if (common->utf8 && c > 127)  
1356    #ifdef SUPPORT_UTF
1357    if (common->utf && c > 127)
1358    {    {
1359    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1360    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1361      {      {
1362      n--;      n--;
# Line 1341  if (common->utf8 && c > 127) Line 1364  if (common->utf8 && c > 127)
1364      }      }
1365    return (n << 8) | bit;    return (n << 8) | bit;
1366    }    }
1367  #endif  #endif /* SUPPORT_UTF */
1368  return (0 << 8) | bit;  return (0 << 8) | bit;
1369    
1370    #else /* COMPILE_PCRE8 */
1371    
1372    #ifdef COMPILE_PCRE16
1373    #ifdef SUPPORT_UTF
1374    if (common->utf && c > 65535)
1375      {
1376      if (bit >= (1 << 10))
1377        bit >>= 10;
1378      else
1379        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1380      }
1381    #endif /* SUPPORT_UTF */
1382    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1383    #endif /* COMPILE_PCRE16 */
1384    
1385    #endif /* COMPILE_PCRE8 */
1386  }  }
1387    
1388  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)  static SLJIT_INLINE void check_input_end(compiler_common *common, jump_list **fallbacks)
# Line 1356  static void read_char(compiler_common *c Line 1396  static void read_char(compiler_common *c
1396  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1397  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1398  DEFINE_COMPILER;  DEFINE_COMPILER;
1399  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1400  struct sljit_jump *jump;  struct sljit_jump *jump;
1401  #endif  #endif
1402    
1403  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1404  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1405  if (common->utf8)  if (common->utf)
1406    {    {
1407    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1408    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1409    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1410    #ifdef COMPILE_PCRE16
1411      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1412    #endif
1413    #endif /* COMPILE_PCRE8 */
1414      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1415    JUMPHERE(jump);    JUMPHERE(jump);
1416    }    }
1417  #endif  #endif
1418  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));
1419  }  }
1420    
1421  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1378  static void peek_char(compiler_common *c Line 1423  static void peek_char(compiler_common *c
1423  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1424  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1425  DEFINE_COMPILER;  DEFINE_COMPILER;
1426  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1427  struct sljit_jump *jump;  struct sljit_jump *jump;
1428  #endif  #endif
1429    
1430  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1431  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1432  if (common->utf8)  if (common->utf)
1433    {    {
1434    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1435    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1436    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1437    #ifdef COMPILE_PCRE16
1438      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1439    #endif
1440    #endif /* COMPILE_PCRE8 */
1441      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1442    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1443    JUMPHERE(jump);    JUMPHERE(jump);
1444    }    }
# Line 1399  static void read_char8_type(compiler_com Line 1449  static void read_char8_type(compiler_com
1449  {  {
1450  /* 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. */
1451  DEFINE_COMPILER;  DEFINE_COMPILER;
1452  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1453  struct sljit_jump *jump;  struct sljit_jump *jump;
1454  #endif  #endif
1455    
1456  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1457  if (common->utf8)  if (common->utf)
1458    {    {
1459    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1460    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));
1461    #ifdef COMPILE_PCRE8
1462    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1463    it is a clever early read in most cases. */    it is needed in most cases. */
1464    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1465    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1466    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));  
1467    JUMPHERE(jump);    JUMPHERE(jump);
1468    #else
1469    #ifdef COMPILE_PCRE16
1470      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1471      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1472      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1473      JUMPHERE(jump);
1474      /* Skip low surrogate if necessary. */
1475      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1476      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1477      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1478      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1479      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1480    #endif
1481    #endif /* COMPILE_PCRE8 */
1482    return;    return;
1483    }    }
1484  #endif  #endif
1485  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1486  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));
1487  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1488    /* The ctypes array contains only 256 values. */
1489    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1490    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1491    #endif
1492    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1493    #ifdef COMPILE_PCRE16
1494    JUMPHERE(jump);
1495    #endif
1496  }  }
1497    
1498  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1499  {  {
1500  /* 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. */
1501  DEFINE_COMPILER;  DEFINE_COMPILER;
1502  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1503  struct sljit_label *label;  struct sljit_label *label;
1504    
1505  if (common->utf8)  if (common->utf)
1506    {    {
1507    label = LABEL();    label = LABEL();
1508    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1509    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));
1510    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1511    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1512    return;    return;
1513    }    }
1514  #endif  #endif
1515  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1516    if (common->utf)
1517      {
1518      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1519      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1520      /* Skip low surrogate if necessary. */
1521      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1522      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1523      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1524      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1525      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1526      return;
1527      }
1528    #endif
1529    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1530  }  }
1531    
1532  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 1463  else if (nltype == NLTYPE_ANYCRLF) Line 1549  else if (nltype == NLTYPE_ANYCRLF)
1549    }    }
1550  else  else
1551    {    {
1552    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1553    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));
1554    }    }
1555  }  }
1556    
1557  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1558  static void do_utf8readchar(compiler_common *common)  
1559    #ifdef COMPILE_PCRE8
1560    static void do_utfreadchar(compiler_common *common)
1561  {  {
1562  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1563  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. */
1564  DEFINE_COMPILER;  DEFINE_COMPILER;
1565  struct sljit_jump *jump;  struct sljit_jump *jump;
1566    
# Line 1480  sljit_emit_fast_enter(compiler, RETURN_A Line 1568  sljit_emit_fast_enter(compiler, RETURN_A
1568  /* Searching for the first zero. */  /* Searching for the first zero. */
1569  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);
1570  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1571  /* 2 byte sequence */  /* Two byte sequence. */
1572  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1573  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));
1574  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1575  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1576  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1577  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1578  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1579  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1580  JUMPHERE(jump);  JUMPHERE(jump);
1581    
1582  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);
1583  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1584  /* 3 byte sequence */  /* Three byte sequence. */
1585  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1586  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1587  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1588  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1589  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1590  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1591  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1592  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));
1593  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1594  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1595  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1596  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1597  JUMPHERE(jump);  JUMPHERE(jump);
1598    
1599  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1600  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);  
1601  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1602  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1603  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1604  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1605  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1606  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1607  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1608  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1609  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1610  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1611  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));
1612  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1613  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1614  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);  
1615  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1616  }  }
1617    
1618  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1619  {  {
1620  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1621  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1622  DEFINE_COMPILER;  DEFINE_COMPILER;
1623  struct sljit_jump *jump;  struct sljit_jump *jump;
1624  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1564  sljit_emit_fast_enter(compiler, RETURN_A Line 1627  sljit_emit_fast_enter(compiler, RETURN_A
1627    
1628  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);
1629  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1630  /* 2 byte sequence */  /* Two byte sequence. */
1631  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1632  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));
1633  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1634  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1635  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1581  sljit_emit_fast_return(compiler, RETURN_ Line 1644  sljit_emit_fast_return(compiler, RETURN_
1644  JUMPHERE(jump);  JUMPHERE(jump);
1645    
1646  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1647  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);  
1648  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1649  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1650  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1651  }  }
1652    
1653  #endif  #else /* COMPILE_PCRE8 */
1654    
1655    #ifdef COMPILE_PCRE16
1656    static void do_utfreadchar(compiler_common *common)
1657    {
1658    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1659    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1660    DEFINE_COMPILER;
1661    struct sljit_jump *jump;
1662    
1663    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1664    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1665    /* Do nothing, only return. */
1666    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1667    
1668    JUMPHERE(jump);
1669    /* Combine two 16 bit characters. */
1670    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1671    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1672    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1673    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1674    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1675    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1676    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1677    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1678    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1679    }
1680    #endif /* COMPILE_PCRE16 */
1681    
1682    #endif /* COMPILE_PCRE8 */
1683    
1684    #endif /* SUPPORT_UTF */
1685    
1686  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1687    
# Line 1606  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1699  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1699    
1700  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);
1701  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1702  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));
1703  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1704  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1705  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1706  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1707  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1708  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));
1709  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1710  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1711  }  }
# Line 1626  struct sljit_label *newlinelabel = NULL; Line 1719  struct sljit_label *newlinelabel = NULL;
1719  struct sljit_jump *start;  struct sljit_jump *start;
1720  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1721  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1722    #ifdef SUPPORT_UTF
1723    struct sljit_jump *singlechar;
1724    #endif
1725  jump_list *newline = NULL;  jump_list *newline = NULL;
1726  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1727  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1728    
1729  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1730      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1643  if (firstline) Line 1739  if (firstline)
1739    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1740      {      {
1741      mainloop = LABEL();      mainloop = LABEL();
1742      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1743      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1744      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1745      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1746      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);
1747      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);
1748      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_SUB, SLJIT_MEM1(SLJIT_LOCALS_REG), FIRSTLINE_END, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1749      }      }
1750    else    else
1751      {      {
# Line 1673  start = JUMP(SLJIT_JUMP); Line 1769  start = JUMP(SLJIT_JUMP);
1769  if (newlinecheck)  if (newlinecheck)
1770    {    {
1771    newlinelabel = LABEL();    newlinelabel = LABEL();
1772    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));
1773    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1774    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1775    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);
1776    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1777    #ifdef COMPILE_PCRE16
1778      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1779    #endif
1780    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1781    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1782    }    }
# Line 1685  if (newlinecheck) Line 1784  if (newlinecheck)
1784  mainloop = LABEL();  mainloop = LABEL();
1785    
1786  /* 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. */
1787  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1788  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1789  #endif  #endif
1790  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1791    
1792  if (readbyte)  if (readuchar)
1793    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1794    
1795  if (newlinecheck)  if (newlinecheck)
1796    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);
1797    
1798  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1799  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1800    if (common->utf)
1801    {    {
1802    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);
1803      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1804    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1805      JUMPHERE(singlechar);
1806      }
1807    #endif
1808    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1809    if (common->utf)
1810      {
1811      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1812      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1813      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1814      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1815      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1816      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1817      JUMPHERE(singlechar);
1818    }    }
 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);  
1819  #endif  #endif
1820  JUMPHERE(start);  JUMPHERE(start);
1821    
# Line 1718  if (newlinecheck) Line 1828  if (newlinecheck)
1828  return mainloop;  return mainloop;
1829  }  }
1830    
1831  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)
1832  {  {
1833  DEFINE_COMPILER;  DEFINE_COMPILER;
1834  struct sljit_label *start;  struct sljit_label *start;
1835  struct sljit_jump *leave;  struct sljit_jump *leave;
1836  struct sljit_jump *found;  struct sljit_jump *found;
1837  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1838    
1839  if (firstline)  if (firstline)
1840    {    {
# Line 1734  if (firstline) Line 1844  if (firstline)
1844    
1845  start = LABEL();  start = LABEL();
1846  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1847  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1848    
1849  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1850    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
1851      {
1852      oc = TABLE_GET(first_char, common->fcc, first_char);
1853    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1854      if (first_char > 127 && common->utf)
1855        oc = UCD_OTHERCASE(first_char);
1856    #endif
1857      }
1858    if (first_char == oc)
1859      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
1860  else  else
1861    {    {
1862    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
1863    if (ispowerof2(bit))    if (ispowerof2(bit))
1864      {      {
1865      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
1866      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
1867      }      }
1868    else    else
1869      {      {
1870      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);
1871      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1872      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);
1873      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 1758  else Line 1875  else
1875      }      }
1876    }    }
1877    
1878  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1879  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1880    if (common->utf)
1881    {    {
1882    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);
1883      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1884      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1885      }
1886    #endif
1887    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1888    if (common->utf)
1889      {
1890      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
1891      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1892      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1893      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1894      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1895    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1896    }    }
 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);  
1897  #endif  #endif
1898  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1899  JUMPHERE(found);  JUMPHERE(found);
# Line 1802  if (common->nltype == NLTYPE_FIXED && co Line 1928  if (common->nltype == NLTYPE_FIXED && co
1928    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));
1929    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1930    
1931    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
1932    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);
1933    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
1934    #ifdef COMPILE_PCRE16
1935      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1936    #endif
1937    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1938    
1939    loop = LABEL();    loop = LABEL();
1940    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));
1941    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1942    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
1943    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1944    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);
1945    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);
1946    
# Line 1842  if (common->nltype == NLTYPE_ANY || comm Line 1971  if (common->nltype == NLTYPE_ANY || comm
1971    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
1972    JUMPHERE(foundcr);    JUMPHERE(foundcr);
1973    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1974    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1975    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);
1976    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1977    #ifdef COMPILE_PCRE16
1978      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1979    #endif
1980    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1981    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
1982    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1862  DEFINE_COMPILER; Line 1994  DEFINE_COMPILER;
1994  struct sljit_label *start;  struct sljit_label *start;
1995  struct sljit_jump *leave;  struct sljit_jump *leave;
1996  struct sljit_jump *found;  struct sljit_jump *found;
1997    #ifndef COMPILE_PCRE8
1998    struct sljit_jump *jump;
1999    #endif
2000    
2001  if (firstline)  if (firstline)
2002    {    {
# Line 1871  if (firstline) Line 2006  if (firstline)
2006    
2007  start = LABEL();  start = LABEL();
2008  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2009  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2010  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2011  if (common->utf8)  if (common->utf)
2012    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2013    #endif
2014    #ifndef COMPILE_PCRE8
2015    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2016    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2017    JUMPHERE(jump);
2018  #endif  #endif
2019  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2020  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1883  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2023  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2023  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);
2024  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2025    
2026  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2027  if (common->utf8)  if (common->utf)
2028    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2029  else  #endif
2030    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));
2031  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2032  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2033      {
2034      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2035      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2036      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2037      }
2038    #endif
2039    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2040    if (common->utf)
2041      {
2042      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2043      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2044      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2045      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2046      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2047      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2048      }
2049  #endif  #endif
2050  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2051  JUMPHERE(found);  JUMPHERE(found);
# Line 1899  if (firstline) Line 2055  if (firstline)
2055    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2056  }  }
2057    
2058  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)
2059  {  {
2060  DEFINE_COMPILER;  DEFINE_COMPILER;
2061  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1908  struct sljit_jump *alreadyfound; Line 2064  struct sljit_jump *alreadyfound;
2064  struct sljit_jump *found;  struct sljit_jump *found;
2065  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2066  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2067  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2068    
2069  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR);
2070  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);
2071  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2072  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2073    
2074  if (has_firstbyte)  if (has_firstchar)
2075    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2076  else  else
2077    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2078    
2079  loop = LABEL();  loop = LABEL();
2080  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2081    
2082  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2083  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2084    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2085      {
2086      oc = TABLE_GET(req_char, common->fcc, req_char);
2087    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2088      if (req_char > 127 && common->utf)
2089        oc = UCD_OTHERCASE(req_char);
2090    #endif
2091      }
2092    if (req_char == oc)
2093      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2094  else  else
2095    {    {
2096    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2097    if (ispowerof2(bit))    if (ispowerof2(bit))
2098      {      {
2099      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2100      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2101      }      }
2102    else    else
2103      {      {
2104      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2105      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2106      }      }
2107    }    }
2108  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2109  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2110    
2111  JUMPHERE(found);  JUMPHERE(found);
2112  if (foundoc)  if (foundoc)
2113    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2114  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_BYTE_PTR, TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), REQ_CHAR_PTR, TMP1, 0);
2115  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2116  JUMPHERE(toolong);  JUMPHERE(toolong);
2117  return notfound;  return notfound;
# Line 1957  return notfound; Line 2120  return notfound;
2120  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2121  {  {
2122  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2123  struct sljit_jump *jump;  struct sljit_jump *jump;
2124  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2125    
2126  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);
2127  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2128    
2129  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2130  mainloop = LABEL();  mainloop = LABEL();
2131  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2132  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 1978  JUMPTO(SLJIT_JUMP, mainloop); Line 2139  JUMPTO(SLJIT_JUMP, mainloop);
2139  JUMPHERE(jump);  JUMPHERE(jump);
2140  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2141  /* 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);  
2142  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2143    
2144  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
2145  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2146  /* Set max index. */  /* Set string begin. */
2147  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2148  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));
2149  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(0), TMP2, 0);
# Line 2009  static void check_wordboundary(compiler_ Line 2159  static void check_wordboundary(compiler_
2159  {  {
2160  DEFINE_COMPILER;  DEFINE_COMPILER;
2161  struct sljit_jump *beginend;  struct sljit_jump *beginend;
2162    #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2163  struct sljit_jump *jump;  struct sljit_jump *jump;
2164    #endif
2165    
2166  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2167    
2168  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);
2169  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2024  read_char(common); Line 2176  read_char(common);
2176    
2177  /* Testing char type. */  /* Testing char type. */
2178  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2179  if (common->useucp)  if (common->use_ucp)
2180    {    {
2181    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2182    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2041  if (common->useucp) Line 2193  if (common->useucp)
2193  else  else
2194  #endif  #endif
2195    {    {
2196  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2197      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2198    #elif defined SUPPORT_UTF
2199    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2200    jump = NULL;    jump = NULL;
2201    if (common->utf8)    if (common->utf)
2202      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2203  #endif  #endif /* COMPILE_PCRE8 */
2204    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2205    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2206    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2207    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2208  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2209      JUMPHERE(jump);
2210    #elif defined SUPPORT_UTF
2211    if (jump != NULL)    if (jump != NULL)
2212      JUMPHERE(jump);      JUMPHERE(jump);
2213  #endif  #endif /* COMPILE_PCRE8 */
2214    }    }
2215  JUMPHERE(beginend);  JUMPHERE(beginend);
2216    
# Line 2064  peek_char(common); Line 2220  peek_char(common);
2220    
2221  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2222  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2223  if (common->useucp)  if (common->use_ucp)
2224    {    {
2225    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2226    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2080  if (common->useucp) Line 2236  if (common->useucp)
2236  else  else
2237  #endif  #endif
2238    {    {
2239  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2240      /* TMP2 may be destroyed by peek_char. */
2241      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2242      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2243    #elif defined SUPPORT_UTF
2244    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2245    jump = NULL;    jump = NULL;
2246    if (common->utf8)    if (common->utf)
2247      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2248  #endif  #endif
2249    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2250    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2251    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2252  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2253      JUMPHERE(jump);
2254    #elif defined SUPPORT_UTF
2255    if (jump != NULL)    if (jump != NULL)
2256      JUMPHERE(jump);      JUMPHERE(jump);
2257  #endif  #endif /* COMPILE_PCRE8 */
2258    }    }
2259  JUMPHERE(beginend);  JUMPHERE(beginend);
2260    
# Line 2111  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2273  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2273  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);
2274  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2275  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);
2276  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2277  if (common->utf8)  #ifdef COMPILE_PCRE8
2278    if (common->utf)
2279    {    {
2280    #endif
2281    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2282    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2283    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);
2284    #ifdef COMPILE_PCRE8
2285    }    }
2286  #endif  #endif
2287    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2288  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2289  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2290  }  }
# Line 2135  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2301  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2301  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);
2302  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2303  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);
2304  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2305  if (common->utf8)  #ifdef COMPILE_PCRE8
2306    if (common->utf)
2307    {    {
2308    #endif
2309    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2310    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);
2311    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2151  if (common->utf8) Line 2319  if (common->utf8)
2319    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);
2320    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2321    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);
2322    #ifdef COMPILE_PCRE8
2323    }    }
2324  #endif  #endif
2325    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2326  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2327    
2328  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2169  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2339  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2339  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);
2340  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2341  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);
2342  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2343  if (common->utf8)  #ifdef COMPILE_PCRE8
2344    if (common->utf)
2345    {    {
2346    #endif
2347    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2348    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2349    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);
2350    #ifdef COMPILE_PCRE8
2351    }    }
2352  #endif  #endif
2353    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2354  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2355    
2356  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2195  sljit_emit_fast_enter(compiler, RETURN_A Line 2369  sljit_emit_fast_enter(compiler, RETURN_A
2369  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2370  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2371  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2372  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2373  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));
2374    
2375  label = LABEL();  label = LABEL();
2376  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2377  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2378  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2379  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));
2380  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2381    
2382  JUMPHERE(jump);  JUMPHERE(jump);
2383  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));
2384  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2385  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2386  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2227  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2401  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2401  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2402  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2403  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2404  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2405  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));
2406    
2407  label = LABEL();  label = LABEL();
2408  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2409  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2410    #ifndef COMPILE_PCRE8
2411    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2412    #endif
2413  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2414    #ifndef COMPILE_PCRE8
2415    JUMPHERE(jump);
2416    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2417    #endif
2418  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2419    #ifndef COMPILE_PCRE8
2420    JUMPHERE(jump);
2421    #endif
2422  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2423  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));
2424  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2425    
2426  JUMPHERE(jump);  JUMPHERE(jump);
2427  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));
2428  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2429  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2430  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2251  sljit_emit_fast_return(compiler, RETURN_ Line 2435  sljit_emit_fast_return(compiler, RETURN_
2435  #undef CHAR1  #undef CHAR1
2436  #undef CHAR2  #undef CHAR2
2437    
2438  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2439    
2440  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)
2441  {  {
2442  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2443  int c1, c2;  int c1, c2;
2444  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2445  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2446    
2447  while (src1 < end1)  while (src1 < end1)
2448    {    {
# Line 2272  while (src1 < end1) Line 2455  while (src1 < end1)
2455  return src2;  return src2;
2456  }  }
2457    
2458  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2459    
2460  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,
2461      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2462  {  {
2463  DEFINE_COMPILER;  DEFINE_COMPILER;
2464  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2465  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2466  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2467  int utf8length;  int utflength;
2468  #endif  #endif
2469    
2470  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2290  if (caseless && char_has_othercase(commo Line 2472  if (caseless && char_has_othercase(commo
2472    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2473    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2474    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2475    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2476      othercasechar = cc + (othercasebit >> 8);
2477    othercasebit &= 0xff;    othercasebit &= 0xff;
2478    #else
2479    #ifdef COMPILE_PCRE16
2480      othercasechar = cc + (othercasebit >> 9);
2481      if ((othercasebit & 0x100) != 0)
2482        othercasebit = (othercasebit & 0xff) << 8;
2483      else
2484        othercasebit &= 0xff;
2485    #endif
2486    #endif
2487    }    }
2488    
2489  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2490    {    {
2491    #ifdef COMPILE_PCRE8
2492  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2493    if (context->length >= 4)    if (context->length >= 4)
2494      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2495    else if (context->length >= 2)    else if (context->length >= 2)
2496      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2497    else    else
2498  #endif  #endif
2499      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2500    #else
2501    #ifdef COMPILE_PCRE16
2502    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2503      if (context->length >= 4)
2504        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2505      else
2506    #endif
2507        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2508    #endif
2509    #endif /* COMPILE_PCRE8 */
2510    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2511    }    }
2512    
2513  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2514  utf8length = 1;  utflength = 1;
2515  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2516    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2517    
2518  do  do
2519    {    {
2520  #endif  #endif
2521    
2522    context->length--;    context->length -= IN_UCHARS(1);
2523  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2524    
2525    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2526    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2527      {      {
2528      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2529      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2530      }      }
2531    else    else
2532      {      {
2533      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2534      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2535      }      }
2536    context->byteptr++;    context->ucharptr++;
2537    
2538    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2539      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2540    #else
2541      if (context->ucharptr >= 2 || context->length == 0)
2542    #endif
2543      {      {
2544      if (context->length >= 4)      if (context->length >= 4)
2545        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);
2546    #ifdef COMPILE_PCRE8
2547      else if (context->length >= 2)      else if (context->length >= 2)
2548        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);
2549      else if (context->length >= 1)      else if (context->length >= 1)
2550        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);
2551    #else
2552        else if (context->length >= 2)
2553          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2554    #endif
2555      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2556    
2557      switch(context->byteptr)      switch(context->ucharptr)
2558        {        {
2559        case 4:        case 4 / sizeof(pcre_uchar):
2560        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2561          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);
2562        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));
2563        break;        break;
2564    
2565        case 2:        case 2 / sizeof(pcre_uchar):
2566        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2567          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);
2568        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));
2569        break;        break;
2570    
2571    #ifdef COMPILE_PCRE8
2572        case 1:        case 1:
2573        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2574          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);
2575        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));
2576        break;        break;
2577    #endif
2578    
2579        default:        default:
2580        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2581        break;        break;
2582        }        }
2583      context->byteptr = 0;      context->ucharptr = 0;
2584      }      }
2585    
2586  #else  #else
2587    
2588    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2589    #ifdef COMPILE_PCRE8
2590    if (context->length > 0)    if (context->length > 0)
2591      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);
2592    #else
2593      if (context->length > 0)
2594        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2595    #endif
2596    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2597    
2598    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2599      {      {
2600      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2601      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 2387  do Line 2606  do
2606  #endif  #endif
2607    
2608    cc++;    cc++;
2609  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2610    utf8length--;    utflength--;
2611    }    }
2612  while (utf8length > 0);  while (utflength > 0);
2613  #endif  #endif
2614    
2615  return cc;  return cc;
2616  }  }
2617    
2618  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2619    
2620  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2621    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2418  return cc; Line 2637  return cc;
2637      } \      } \
2638    charoffset = (value);    charoffset = (value);
2639    
2640  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)
2641  {  {
2642  DEFINE_COMPILER;  DEFINE_COMPILER;
2643  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2426  jump_list **list = (*cc & XCL_NOT) == 0 Line 2645  jump_list **list = (*cc & XCL_NOT) == 0
2645  unsigned int c;  unsigned int c;
2646  int compares;  int compares;
2647  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2648  uschar *ccbegin;  pcre_uchar *ccbegin;
2649  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2650  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2651  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2652  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2653    unsigned int typeoffset;
2654  #endif  #endif
2655  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2656    unsigned int charoffset;
2657    
2658  /* 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. */
2659  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
2660  read_char(common);  read_char(common);
2661    
2662  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2663    {    {
2664    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2665    if (common->utf8)  #ifndef COMPILE_PCRE8
2666      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2667    #elif defined SUPPORT_UTF
2668      if (common->utf)
2669      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2670    #endif
2671    
2672    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2673    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2451  if ((*cc++ & XCL_MAP) != 0) Line 2676  if ((*cc++ & XCL_MAP) != 0)
2676    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);
2677    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2678    
2679    if (common->utf8)  #ifndef COMPILE_PCRE8
2680      JUMPHERE(jump);
2681    #elif defined SUPPORT_UTF
2682      if (common->utf)
2683      JUMPHERE(jump);      JUMPHERE(jump);
2684    #endif
2685    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2686  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2687    charsaved = TRUE;    charsaved = TRUE;
2688  #endif  #endif
2689    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2690    }    }
2691    
2692  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2469  while (*cc != XCL_END) Line 2698  while (*cc != XCL_END)
2698    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2699      {      {
2700      cc += 2;      cc += 2;
2701  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2702      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]);
2703  #endif  #endif
2704  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2705      needschar = TRUE;      needschar = TRUE;
# Line 2479  while (*cc != XCL_END) Line 2708  while (*cc != XCL_END)
2708    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2709      {      {
2710      cc += 2;      cc += 2;
2711  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2712      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]);
2713  #endif  #endif
2714      cc++;      cc++;
2715  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2716      if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];      if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
2717  #endif  #endif
2718  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2719      needschar = TRUE;      needschar = TRUE;
# Line 2554  if (needstype || needsscript) Line 2783  if (needstype || needsscript)
2783      {      {
2784      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2785        {        {
2786        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));
2787        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2788        }        }
2789      else      else
2790        {        {
2791        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2792        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));
2793        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2794        }        }
2795      }      }
# Line 2584  while (*cc != XCL_END) Line 2813  while (*cc != XCL_END)
2813    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2814      {      {
2815      cc ++;      cc ++;
2816  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2817      if (common->utf8)      if (common->utf)
2818        {        {
2819        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2820        }        }
# Line 2615  while (*cc != XCL_END) Line 2844  while (*cc != XCL_END)
2844    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2845      {      {
2846      cc ++;      cc ++;
2847  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2848      if (common->utf8)      if (common->utf)
2849        {        {
2850        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2851        }        }
# Line 2624  while (*cc != XCL_END) Line 2853  while (*cc != XCL_END)
2853  #endif  #endif
2854        c = *cc++;        c = *cc++;
2855      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
2856  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2857      if (common->utf8)      if (common->utf)
2858        {        {
2859        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2860        }        }
# Line 2681  while (*cc != XCL_END) Line 2910  while (*cc != XCL_END)
2910        break;        break;
2911    
2912        case PT_GC:        case PT_GC:
2913        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
2914        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
2915        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);
2916        break;        break;
2917    
2918        case PT_PC:        case PT_PC:
# Line 2745  if (found != NULL) Line 2974  if (found != NULL)
2974    
2975  #endif  #endif
2976    
2977  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)
2978  {  {
2979  DEFINE_COMPILER;  DEFINE_COMPILER;
2980  int length;  int length;
2981  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2982  compare_context context;  compare_context context;
 struct sljit_label *label;  
2983  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
2984  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2985    struct sljit_label *label;
2986  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2987  uschar propdata[5];  pcre_uchar propdata[5];
2988  #endif  #endif
2989  #endif  #endif
2990    
# Line 2810  switch(type) Line 3039  switch(type)
3039      {      {
3040      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);
3041      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3042      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3043      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));
3044      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3045      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 2821  switch(type) Line 3050  switch(type)
3050    
3051    case OP_ALLANY:    case OP_ALLANY:
3052    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3053  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3054    if (common->utf8)    if (common->utf)
3055      {      {
3056      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3057      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));
3058    #ifdef COMPILE_PCRE8
3059        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3060        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3061        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3062    #else /* COMPILE_PCRE8 */
3063    #ifdef COMPILE_PCRE16
3064        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3065        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3066        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3067        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3068        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3069      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3070    #endif /* COMPILE_PCRE16 */
3071    #endif /* COMPILE_PCRE8 */
3072        JUMPHERE(jump[0]);
3073      return cc;      return cc;
3074      }      }
3075  #endif  #endif
3076    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));
3077      return cc;
3078    
3079      case OP_ANYBYTE:
3080      check_input_end(common, fallbacks);
3081      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3082    return cc;    return cc;
3083    
3084  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3085  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3086    case OP_NOTPROP:    case OP_NOTPROP:
3087    case OP_PROP:    case OP_PROP:
# Line 2852  switch(type) Line 3100  switch(type)
3100    read_char(common);    read_char(common);
3101    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);
3102    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    jump[1] = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
3103    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3104    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);
3105    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));
3106    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3107    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3108    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2904  switch(type) Line 3152  switch(type)
3152    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);
3153    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3154      {      {
3155      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3156      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3157      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));
3158      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3159      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));
3160      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));
3161      }      }
3162    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3163      {      {
3164      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3165      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3166      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));
3167      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));
3168      }      }
3169    else    else
3170      {      {
3171      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3172      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);
3173      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3174      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);
3175      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3176      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3177      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3178        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3179      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3180      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3181    
3182      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3183      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3184        {        {
3185        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3186        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));
3187        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));
3188        }        }
# Line 2973  switch(type) Line 3222  switch(type)
3222    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3223    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3224    
3225    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, end));    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, STR_PTR, 0, STR_END, 0));
   add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP2, 0, STR_PTR, 0));  
   
3226    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3227      {      {
3228      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3229      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3230      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3231      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3232      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));
3233      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));
3234      }      }
# Line 3015  switch(type) Line 3262  switch(type)
3262    
3263    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3264      {      {
3265      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3266      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER, TMP2, 0, STR_END, 0));
3267      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3268      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3269      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));
3270      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));
3271      }      }
# Line 3033  switch(type) Line 3280  switch(type)
3280    case OP_CHAR:    case OP_CHAR:
3281    case OP_CHARI:    case OP_CHARI:
3282    length = 1;    length = 1;
3283  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3284    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3285  #endif  #endif
3286    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)    if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)
3287      {      {
3288      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));
3289      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));
3290    
3291      context.length = length;      context.length = IN_UCHARS(length);
3292      context.sourcereg = -1;      context.sourcereg = -1;
3293  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3294      context.byteptr = 0;      context.ucharptr = 0;
3295  #endif  #endif
3296      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3297      }      }
3298    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    check_input_end(common, fallbacks);
3299    read_char(common);    read_char(common);
3300  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3301    if (common->utf8)    if (common->utf)
3302      {      {
3303      GETCHAR(c, cc);      GETCHAR(c, cc);
3304      }      }
# Line 3067  switch(type) Line 3314  switch(type)
3314    
3315    case OP_NOT:    case OP_NOT:
3316    case OP_NOTI:    case OP_NOTI:
3317      check_input_end(common, fallbacks);
3318    length = 1;    length = 1;
3319  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3320    if (common->utf8)    if (common->utf)
3321      {      {
3322      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3323        c = *cc;
3324      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3325        {        {
3326        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);  
3327        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3328          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));
3329        else        else
3330          {          {
3331          /* 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. */
3332          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3333          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));
3334          }          }
3335        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3336        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));
3337        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3338          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3339          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3340          JUMPHERE(jump[0]);
3341          return cc + 1;
3342        }        }
3343      else      else
3344    #endif /* COMPILE_PCRE8 */
3345          {
3346          GETCHARLEN(c, cc, length);
3347        read_char(common);        read_char(common);
3348          }
3349      }      }
3350    else    else
3351  #endif  #endif /* SUPPORT_UTF */
3352      {      {
3353      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);  
3354      c = *cc;      c = *cc;
3355      }      }
3356    
# Line 3121  switch(type) Line 3371  switch(type)
3371        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));        add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, oc));
3372        }        }
3373      }      }
3374    return cc + length;    return cc + 1;
3375    
3376    case OP_CLASS:    case OP_CLASS:
3377    case OP_NCLASS:    case OP_NCLASS:
3378    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3379    read_char(common);    read_char(common);
3380  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3381    jump[0] = NULL;    jump[0] = NULL;
3382    if (common->utf8)  #ifdef COMPILE_PCRE8
3383      /* This check only affects 8 bit mode. In other modes, we
3384      always need to compare the value with 255. */
3385      if (common->utf)
3386    #endif /* COMPILE_PCRE8 */
3387      {      {
3388      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3389      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3138  switch(type) Line 3392  switch(type)
3392        jump[0] = NULL;        jump[0] = NULL;
3393        }        }
3394      }      }
3395  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3396    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3397    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3398    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3399    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3400    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);
3401    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3402  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3403    if (jump[0] != NULL)    if (jump[0] != NULL)
3404      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3405  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3406    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3407    
3408  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3409    case OP_XCLASS:    case OP_XCLASS:
3410    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3411    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3161  switch(type) Line 3415  switch(type)
3415    length = GET(cc, 0);    length = GET(cc, 0);
3416    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3417    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3418    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3419  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3420      {      {
3421        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3422      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3423      label = LABEL();      label = LABEL();
3424      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));
3425      skip_char_back(common);      skip_char_back(common);
3426      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);
3427      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
3428      return cc + LINK_SIZE;      return cc + LINK_SIZE;
3429      }      }
3430  #endif  #endif
3431    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, length);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3432      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3433    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, STR_PTR, 0, TMP1, 0));
3434    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3435    }    }
# Line 3182  SLJIT_ASSERT_STOP(); Line 3437  SLJIT_ASSERT_STOP();
3437  return cc;  return cc;
3438  }  }
3439    
3440  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)
3441  {  {
3442  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3443  /* 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. */
3444  DEFINE_COMPILER;  DEFINE_COMPILER;
3445  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3446  compare_context context;  compare_context context;
3447  int size;  int size;
3448    
# Line 3200  do Line 3455  do
3455    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3456      {      {
3457      size = 1;      size = 1;
3458  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3459      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3460        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3461  #endif  #endif
3462      }      }
3463    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3464      {      {
3465      size = 1;      size = 1;
3466  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3467      if (common->utf8)      if (common->utf)
3468        {        {
3469        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)
3470          size = 0;          size = 0;
3471        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3472          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3473        }        }
3474      else      else
3475  #endif  #endif
3476      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)
3477        size = 0;        size = 0;
# Line 3225  do Line 3480  do
3480      size = 0;      size = 0;
3481    
3482    cc += 1 + size;    cc += 1 + size;
3483    context.length += size;    context.length += IN_UCHARS(size);
3484    }    }
3485  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3486    
# Line 3238  if (context.length > 0) Line 3493  if (context.length > 0)
3493    
3494    context.sourcereg = -1;    context.sourcereg = -1;
3495  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3496    context.byteptr = 0;    context.ucharptr = 0;
3497  #endif  #endif
3498    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);
3499    return cc;    return cc;
# Line 3248  if (context.length > 0) Line 3503  if (context.length > 0)
3503  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3504  }  }
3505    
3506  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)
3507  {  {
3508  DEFINE_COMPILER;  DEFINE_COMPILER;
3509  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3270  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3525  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3525  }  }
3526    
3527  /* Forward definitions. */  /* Forward definitions. */
3528  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3529  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3530    
3531  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3301  static void compile_fallbackpath(compile Line 3556  static void compile_fallbackpath(compile
3556    
3557  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type*)fallback)
3558    
3559  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)
3560  {  {
3561  DEFINE_COMPILER;  DEFINE_COMPILER;
3562  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3311  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT Line 3566  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT
3566  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3567    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)));
3568    
3569  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3570  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3571    {    {
3572    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);
3573    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 3324  if (common->utf8 && *cc == OP_REFI) Line 3578  if (common->utf8 && *cc == OP_REFI)
3578    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3579    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3580    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);
3581    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));
3582    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3583    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));    add_jump(compiler, fallbacks, CMP(SLJIT_C_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0));
3584    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3585    }    }
3586  else  else
3587  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3588    {    {
3589    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);
3590    if (withchecks)    if (withchecks)
# Line 3350  if (jump != NULL) Line 3603  if (jump != NULL)
3603    else    else
3604      JUMPHERE(jump);      JUMPHERE(jump);
3605    }    }
3606  return cc + 3;  return cc + 1 + IMM2_SIZE;
3607  }  }
3608    
3609  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)
3610  {  {
3611  DEFINE_COMPILER;  DEFINE_COMPILER;
3612  fallback_common *fallback;  fallback_common *fallback;
3613  uschar type;  pcre_uchar type;
3614  struct sljit_label *label;  struct sljit_label *label;
3615  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3616  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3617  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3618  int min = 0, max = 0;  int min = 0, max = 0;
3619  BOOL minimize;  BOOL minimize;
3620    
3621  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3622    
3623  type = cc[3];  type = cc[1 + IMM2_SIZE];
3624  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3625  switch(type)  switch(type)
3626    {    {
# Line 3375  switch(type) Line 3628  switch(type)
3628    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3629    min = 0;    min = 0;
3630    max = 0;    max = 0;
3631    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3632    break;    break;
3633    case OP_CRPLUS:    case OP_CRPLUS:
3634    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3635    min = 1;    min = 1;
3636    max = 0;    max = 0;
3637    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3638    break;    break;
3639    case OP_CRQUERY:    case OP_CRQUERY:
3640    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3641    min = 0;    min = 0;
3642    max = 1;    max = 1;
3643    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3644    break;    break;
3645    case OP_CRRANGE:    case OP_CRRANGE:
3646    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3647    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3648    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3649    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3650    break;    break;
3651    default:    default:
3652    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3453  if (!minimize) Line 3706  if (!minimize)
3706    
3707    JUMPHERE(zerolength);    JUMPHERE(zerolength);
3708    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();    FALLBACK_AS(iterator_fallback)->hotpath = LABEL();
3709    
3710      decrease_call_count(common);
3711    return cc;    return cc;
3712    }    }
3713    
# Line 3490  else if (max > 0) Line 3745  else if (max > 0)
3745  if (jump != NULL)  if (jump != NULL)
3746    JUMPHERE(jump);    JUMPHERE(jump);
3747  JUMPHERE(zerolength);  JUMPHERE(zerolength);
3748    
3749    decrease_call_count(common);
3750  return cc;  return cc;
3751  }  }
3752    
3753  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)
3754  {  {
3755  DEFINE_COMPILER;  DEFINE_COMPILER;
3756  fallback_common *fallback;  fallback_common *fallback;
# Line 3539  add_jump(compiler, &fallback->topfallbac Line 3796  add_jump(compiler, &fallback->topfallbac
3796  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3797  }  }
3798    
3799  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)
3800  {  {
3801  DEFINE_COMPILER;  DEFINE_COMPILER;
3802  int framesize;  int framesize;
3803  int localptr;  int localptr;
3804  fallback_common altfallback;  fallback_common altfallback;
3805  uschar *ccbegin;  pcre_uchar *ccbegin;
3806  uschar opcode;  pcre_uchar opcode;
3807  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
3808  jump_list *tmp = NULL;  jump_list *tmp = NULL;
3809  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
3810  jump_list **found;  jump_list **found;
# Line 3563  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3820  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3820    bra = *cc;    bra = *cc;
3821    cc++;    cc++;
3822    }    }
3823  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
3824  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
3825  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
3826  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3622  while (1) Line 3879  while (1)
3879    if (common->accept != NULL)    if (common->accept != NULL)
3880      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3881    
3882      /* Reset stack. */
3883    if (framesize < 0)    if (framesize < 0)
3884      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3885      else {
3886        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3887          {
3888          /* We don't need to keep the STR_PTR, only the previous localptr. */
3889          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3890          }
3891        else
3892          {
3893          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3894          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3895          }
3896      }
3897    
3898    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3899      {      {
3900      /* 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. */
3901      if (conditional)      if (conditional)
3902        {        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));  
         }  
       }  
3903      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3904        {        {
3905        if (framesize < 0)        if (framesize < 0)
3906          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3907        else        else
3908          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3909          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));
3910          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));
3911          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3653  while (1) Line 3913  while (1)
3913        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));
3914        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3915        }        }
3916      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3917        {        {
3918        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3919          {        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));  
         }  
3920        }        }
3921      }      }
3922    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3687  if (opcode == OP_ASSERT || opcode == OP_ Line 3943  if (opcode == OP_ASSERT || opcode == OP_
3943    /* Assert is failed. */    /* Assert is failed. */
3944    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3945      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3946    
3947    if (framesize < 0)    if (framesize < 0)
3948      {      {
3949      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3698  if (opcode == OP_ASSERT || opcode == OP_ Line 3955  if (opcode == OP_ASSERT || opcode == OP_
3955    else    else
3956      {      {
3957      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));  
3958      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3959      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3960        {        {
# Line 3709  if (opcode == OP_ASSERT || opcode == OP_ Line 3964  if (opcode == OP_ASSERT || opcode == OP_
3964      else      else
3965        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3966      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);  
3967      }      }
3968    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3969    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3733  if (opcode == OP_ASSERT || opcode == OP_ Line 3986  if (opcode == OP_ASSERT || opcode == OP_
3986      }      }
3987    else    else
3988      {      {
3989      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)  
3990        {        {
3991        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3992        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));
3993          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3994        }        }
3995      else if (bra == OP_BRAMINZERO)      else
3996        {        {
3997        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3998        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));
3999          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4000          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4001        }        }
4002      }      }
4003    
# Line 3780  else Line 4034  else
4034      {      {
4035      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4036      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));  
4037      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4038      if (bra != OP_BRA)      if (bra != OP_BRA)
4039        {        {
# Line 3791  else Line 4043  else
4043      else      else
4044        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4045      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);  
4046      }      }
4047    
4048    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3816  common->accept = save_accept; Line 4066  common->accept = save_accept;
4066  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4067  }  }
4068    
4069    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4070    {
4071    int condition = FALSE;
4072    pcre_uchar *slotA = name_table;
4073    pcre_uchar *slotB;
4074    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4075    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4076    sljit_w no_capture;
4077    int i;
4078    
4079    locals += OVECTOR_START / sizeof(sljit_w);
4080    no_capture = locals[1];
4081    
4082    for (i = 0; i < name_count; i++)
4083      {
4084      if (GET2(slotA, 0) == refno) break;
4085      slotA += name_entry_size;
4086      }
4087    
4088    if (i < name_count)
4089      {
4090      /* Found a name for the number - there can be only one; duplicate names
4091      for different numbers are allowed, but not vice versa. First scan down
4092      for duplicates. */
4093    
4094      slotB = slotA;
4095      while (slotB > name_table)
4096        {
4097        slotB -= name_entry_size;
4098        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4099          {
4100          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4101          if (condition) break;
4102          }
4103        else break;
4104        }
4105    
4106      /* Scan up for duplicates */
4107      if (!condition)
4108        {
4109        slotB = slotA;
4110        for (i++; i < name_count; i++)
4111          {
4112          slotB += name_entry_size;
4113          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4114            {
4115            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4116            if (condition) break;
4117            }
4118          else break;
4119          }
4120        }
4121      }
4122    return condition;
4123    }
4124    
4125    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4126    {
4127    int condition = FALSE;
4128    pcre_uchar *slotA = name_table;
4129    pcre_uchar *slotB;
4130    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4131    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4132    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4133    int i;
4134    
4135    for (i = 0; i < name_count; i++)
4136      {
4137      if (GET2(slotA, 0) == recno) break;
4138      slotA += name_entry_size;
4139      }
4140    
4141    if (i < name_count)
4142      {
4143      /* Found a name for the number - there can be only one; duplicate
4144      names for different numbers are allowed, but not vice versa. First
4145      scan down for duplicates. */
4146    
4147      slotB = slotA;
4148      while (slotB > name_table)
4149        {
4150        slotB -= name_entry_size;
4151        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4152          {
4153          condition = GET2(slotB, 0) == group_num;
4154          if (condition) break;
4155          }
4156        else break;
4157        }
4158    
4159      /* Scan up for duplicates */
4160      if (!condition)
4161        {
4162        slotB = slotA;
4163        for (i++; i < name_count; i++)
4164          {
4165          slotB += name_entry_size;
4166          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4167            {
4168            condition = GET2(slotB, 0) == group_num;
4169            if (condition) break;
4170            }
4171          else break;
4172          }
4173        }
4174      }
4175    return condition;
4176    }
4177    
4178  /*  /*
4179    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4180    
# Line 3825  return cc + 1 + LINK_SIZE; Line 4184  return cc + 1 + LINK_SIZE;
4184      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
4185          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
4186      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.
4187      C - Push the previous OVECTOR(i), OVECTOR(i+1), MAX_INDEX and OVECTOR_PRIV(i) to the stack.      C - Push the previous OVECTOR(i), OVECTOR(i+1) and OVECTOR_PRIV(i) to the stack.
4188      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
4189     () - opional values stored on the stack     () - opional values stored on the stack
4190    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3863  return cc + 1 + LINK_SIZE; Line 4222  return cc + 1 + LINK_SIZE;
4222      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.
4223    
4224    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4225    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4226    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4227    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4228                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4229                                              Or nothing, if trace is unnecessary
4230  */  */
4231    
4232  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)
4233  {  {
4234  DEFINE_COMPILER;  DEFINE_COMPILER;
4235  fallback_common *fallback;  fallback_common *fallback;
4236  uschar opcode;  pcre_uchar opcode;
4237  int localptr = 0;  int localptr = 0;
4238  int offset = 0;  int offset = 0;
4239  int stacksize;  int stacksize;
4240  uschar *ccbegin;  pcre_uchar *ccbegin;
4241  uschar *hotpath;  pcre_uchar *hotpath;
4242  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4243  uschar ket;  pcre_uchar ket;
4244  assert_fallback *assert;  assert_fallback *assert;
4245  BOOL has_alternatives;  BOOL has_alternatives;
4246  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3899  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4259  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4259    
4260  opcode = *cc;  opcode = *cc;
4261  ccbegin = cc;  ccbegin = cc;
4262    hotpath = ccbegin + 1 + LINK_SIZE;
4263    
4264  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)
4265    {    {
4266    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3910  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4272  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4272  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4273  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)));
4274  cc += GET(cc, 1);  cc += GET(cc, 1);
4275  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4276    has_alternatives = *cc == OP_ALT;
4277    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4278      {
4279      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4280      if (*hotpath == OP_NRREF)
4281        {
4282        stacksize = GET2(hotpath, 1);
4283        if (common->currententry == NULL || stacksize == RREF_ANY)
4284          has_alternatives = FALSE;
4285        else if (common->currententry->start == 0)
4286          has_alternatives = stacksize != 0;
4287        else
4288          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4289        }
4290      }
4291    
4292  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4293    opcode = OP_SCOND;    opcode = OP_SCOND;
4294    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4295      opcode = OP_ONCE;
4296    
4297  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4298    {    {
# Line 3921  if (opcode == OP_CBRA || opcode == OP_SC Line 4301  if (opcode == OP_CBRA || opcode == OP_SC
4301    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4302    offset <<= 1;    offset <<= 1;
4303    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4304      hotpath += IMM2_SIZE;
4305    }    }
4306  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4307    {    {
4308    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4309    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4310    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4311    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4312    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4052  if (opcode == OP_ONCE) Line 4433  if (opcode == OP_ONCE)
4433  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4434    {    {
4435    /* Saving the previous values. */    /* Saving the previous values. */
4436    allocate_stack(common, 4);    allocate_stack(common, 3);
4437    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4438    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));
4439    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4440    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4441    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4442    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4443    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4444    }    }
4445  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4446    {    {
# Line 4080  else if (has_alternatives) Line 4458  else if (has_alternatives)
4458    }    }
4459    
4460  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4461  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4462    {    {
4463    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4464      {      {
4465        SLJIT_ASSERT(has_alternatives);
4466      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4467        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)));
4468      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4469        }
4470      else if (*hotpath == OP_NCREF)
4471        {
4472        SLJIT_ASSERT(has_alternatives);
4473        stacksize = GET2(hotpath, 1);
4474        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4475    
4476        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4477        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4478        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4479        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4480        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4481        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4482        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4483        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4484        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4485    
4486        JUMPHERE(jump);
4487        hotpath += 1 + IMM2_SIZE;
4488        }
4489      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4490        {
4491        /* Never has other case. */
4492        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4493    
4494        stacksize = GET2(hotpath, 1);
4495        if (common->currententry == NULL)
4496          stacksize = 0;
4497        else if (stacksize == RREF_ANY)
4498          stacksize = 1;
4499        else if (common->currententry->start == 0)
4500          stacksize = stacksize == 0;
4501        else
4502          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4503    
4504        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4505          {
4506          SLJIT_ASSERT(!has_alternatives);
4507          if (stacksize != 0)
4508            hotpath += 1 + IMM2_SIZE;
4509          else
4510            {
4511            if (*cc == OP_ALT)
4512              {
4513              hotpath = cc + 1 + LINK_SIZE;
4514              cc += GET(cc, 1);
4515              }
4516            else
4517              hotpath = cc;
4518            }
4519          }
4520        else
4521          {
4522          SLJIT_ASSERT(has_alternatives);
4523    
4524          stacksize = GET2(hotpath, 1);
4525          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4526          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4527          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4528          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4529          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4530          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4531          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4532          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4533          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4534          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4535          hotpath += 1 + IMM2_SIZE;
4536          }
4537      }      }
4538    else    else
4539      {      {
4540      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4541      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4542      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4543      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4123  if (opcode == OP_ONCE) Line 4567  if (opcode == OP_ONCE)
4567        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);
4568        }        }
4569      }      }
4570    else if (ket == OP_KETRMAX)    else
4571      {      {
4572      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4573      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));
4574      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4575          {
4576          /* TMP2 which is set here used by OP_KETRMAX below. */
4577          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4578          }
4579      }      }
4580    }    }
4581    
# Line 4210  if (bra == OP_BRAMINZERO) Line 4658  if (bra == OP_BRAMINZERO)
4658    /* Continue to the normal fallback. */    /* Continue to the normal fallback. */
4659    }    }
4660    
4661    if ((ket != OP_KET && bra != OP_BRAMINZERO) || bra == OP_BRAZERO)
4662      decrease_call_count(common);
4663    
4664  /* Skip the other alternatives. */  /* Skip the other alternatives. */
4665  while (*cc == OP_ALT)  while (*cc == OP_ALT)
4666    cc += GET(cc, 1);    cc += GET(cc, 1);
# Line 4217  cc += 1 + LINK_SIZE; Line 4668  cc += 1 + LINK_SIZE;
4668  return cc;  return cc;
4669  }  }
4670    
4671  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)
4672  {  {
4673  DEFINE_COMPILER;  DEFINE_COMPILER;
4674  fallback_common *fallback;  fallback_common *fallback;
4675  uschar opcode;  pcre_uchar opcode;
4676  int localptr;  int localptr;
4677  int cbraprivptr = 0;  int cbraprivptr = 0;
4678  int framesize;  int framesize;
4679  int stacksize;  int stacksize;
4680  int offset = 0;  int offset = 0;
4681  BOOL zero = FALSE;  BOOL zero = FALSE;
4682  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4683  int stack;  int stack;
4684  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4685  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4241  if (*cc == OP_BRAPOSZERO) Line 4692  if (*cc == OP_BRAPOSZERO)
4692    }    }
4693    
4694  opcode = *cc;  opcode = *cc;
4695  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4696  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4697  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4698  switch(opcode)  switch(opcode)
# Line 4256  switch(opcode) Line 4707  switch(opcode)
4707    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4708    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4709    offset <<= 1;    offset <<= 1;
4710    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4711    break;    break;
4712    
4713    default:    default:
# Line 4268  framesize = get_framesize(common, cc, FA Line 4719  framesize = get_framesize(common, cc, FA
4719  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4720  if (framesize < 0)  if (framesize < 0)
4721    {    {
4722    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4723    if (!zero)    if (!zero)
4724      stacksize++;      stacksize++;
4725    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4281  if (framesize < 0) Line 4732  if (framesize < 0)
4732      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));
4733      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4734      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), MAX_INDEX, 0);  
4735      }      }
4736    else    else
4737      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), STR_PTR, 0);
# Line 4339  while (*cc != OP_KETRPOS) Line 4789  while (*cc != OP_KETRPOS)
4789        {        {
4790        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
4791        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4792        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4793          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4794        }        }
4795      else      else
4796        {        {
# Line 4360  while (*cc != OP_KETRPOS) Line 4809  while (*cc != OP_KETRPOS)
4809      {      {
4810      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4811        {        {
4812          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4813        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);  
4814        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), STR_PTR, 0);
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
       add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, MAX_INDEX, 0, SLJIT_IMM, (offset >> 1) + 1));  
4815        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4816          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4817        }        }
4818      else      else
4819        {        {
4820        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4821          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4822        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4823          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));
4824        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 4379  while (*cc != OP_KETRPOS) Line 4827  while (*cc != OP_KETRPOS)
4827      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4828        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));
4829    
     /* TMP2 must be set above. */  
4830      if (!zero)      if (!zero)
4831        {        {
4832        if (framesize < 0)        if (framesize < 0)
4833          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);
4834        else        else
4835          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);
4836        }        }
4837      }      }
4838    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4407  while (*cc != OP_KETRPOS) Line 4854  while (*cc != OP_KETRPOS)
4854      {      {
4855      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4856        {        {
4857          /* Last alternative. */
4858        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4859          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4860        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 4434  if (!zero) Line 4882  if (!zero)
4882    
4883  /* None of them matched. */  /* None of them matched. */
4884  set_jumps(emptymatch, LABEL());  set_jumps(emptymatch, LABEL());
4885    decrease_call_count(common);
4886  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4887  }  }
4888    
4889  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)
4890  {  {
4891  int class_len;  int class_len;
4892    
# Line 4476  else Line 4925  else
4925    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
4926    *type = *opcode;    *type = *opcode;
4927    cc++;    cc++;
4928    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
4929    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
4930    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
4931      {      {
# Line 4487  else Line 4936  else
4936    else    else
4937      {      {
4938      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
4939      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
4940      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
4941    
4942      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4499  else Line 4948  else
4948        *opcode = OP_EXACT;        *opcode = OP_EXACT;
4949    
4950      if (end != NULL)      if (end != NULL)
4951        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
4952      }      }
4953    return cc;    return cc;
4954    }    }
# Line 4507  else Line 4956  else
4956  if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)  if (*opcode == OP_UPTO || *opcode == OP_MINUPTO || *opcode == OP_EXACT || *opcode == OP_POSUPTO)
4957    {    {
4958    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
4959    cc += 2;    cc += IMM2_SIZE;
4960    }    }
4961    
4962  if (*type == 0)  if (*type == 0)
# Line 4522  if (*type == 0) Line 4971  if (*type == 0)
4971  if (end != NULL)  if (end != NULL)
4972    {    {
4973    *end = cc + 1;    *end = cc + 1;
4974  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4975    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
4976  #endif  #endif
4977    }    }
4978  return cc;  return cc;
4979  }  }
4980    
4981  static uschar *compile_iterator_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static pcre_uchar *compile_iterator_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
4982  {  {
4983  DEFINE_COMPILER;  DEFINE_COMPILER;
4984  fallback_common *fallback;  fallback_common *fallback;
4985  uschar opcode;  pcre_uchar opcode;
4986  uschar type;  pcre_uchar type;
4987  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
4988  uschar* end;  pcre_uchar* end;
4989  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
4990  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4991  struct sljit_label *label;  struct sljit_label *label;
# Line 4694  switch(opcode) Line 5143  switch(opcode)
5143    break;    break;
5144    }    }
5145    
5146    decrease_call_count(common);
5147  return end;  return end;
5148  }  }
5149    
5150  static SLJIT_INLINE uschar *compile_fail_accept_hotpath(compiler_common *common, uschar *cc, fallback_common *parent)  static SLJIT_INLINE pcre_uchar *compile_fail_accept_hotpath(compiler_common *common, pcre_uchar *cc, fallback_common *parent)
5151  {  {
5152  DEFINE_COMPILER;  DEFINE_COMPILER;
5153  fallback_common *fallback;  fallback_common *fallback;
# Line 4741  add_jump(compiler, &fallback->topfallbac Line 5191  add_jump(compiler, &fallback->topfallbac
5191  return cc + 1;  return cc + 1;
5192  }  }
5193    
5194  static SLJIT_INLINE uschar *compile_close_hotpath(compiler_common *common, uschar *cc)  static SLJIT_INLINE pcre_uchar *compile_close_hotpath(compiler_common *common, pcre_uchar *cc)
5195  {  {
5196  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
5197  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5198    
5199  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5200  if (common->currententry != NULL)  if (common->currententry != NULL)
5201    return cc + 3;    return cc + 1 + IMM2_SIZE;
5202    
5203  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR_PRIV(offset));
5204  offset <<= 1;  offset <<= 1;
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  
5205  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);
5206  offset = (offset >> 1) + 1;  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5207  jump = CMP(SLJIT_C_GREATER_EQUAL, MAX_INDEX, 0, SLJIT_IMM, offset);  return cc + 1 + IMM2_SIZE;
 OP1(SLJIT_MOV, MAX_INDEX, 0, SLJIT_IMM, offset);  
 JUMPHERE(jump);  
 return cc + 3;  
5208  }  }
5209    
5210  static void compile_hotpath(compiler_common *common, uschar *cc, uschar *ccend, fallback_common *parent)  static void compile_hotpath(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend, fallback_common *parent)
5211  {  {
5212  DEFINE_COMPILER;  DEFINE_COMPILER;
5213  fallback_common *fallback;  fallback_common *fallback;
# Line 4783  while (cc < ccend) Line 5228  while (cc < ccend)
5228      case OP_WORDCHAR:      case OP_WORDCHAR:
5229      case OP_ANY:      case OP_ANY:
5230      case OP_ALLANY:      case OP_ALLANY:
5231        case OP_ANYBYTE:
5232      case OP_NOTPROP:      case OP_NOTPROP:
5233      case OP_PROP:      case OP_PROP:
5234      case OP_ANYNL:      case OP_ANYNL:
# Line 4887  while (cc < ccend) Line 5333  while (cc < ccend)
5333    
5334      case OP_CLASS:      case OP_CLASS:
5335      case OP_NCLASS:      case OP_NCLASS:
5336      if (cc[33] >= OP_CRSTAR && cc[33] <= OP_CRMINRANGE)      if (cc[1 + (32 / sizeof(pcre_uchar))] >= OP_CRSTAR && cc[1 + (32 / sizeof(pcre_uchar))] <= OP_CRMINRANGE)
5337        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5338      else      else
5339        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);        cc = compile_char1_hotpath(common, *cc, cc + 1, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks);
5340      break;      break;
5341    
5342  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5343      case OP_XCLASS:      case OP_XCLASS:
5344      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)      if (*(cc + GET(cc, 1)) >= OP_CRSTAR && *(cc + GET(cc, 1)) <= OP_CRMINRANGE)
5345        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 4904  while (cc < ccend) Line 5350  while (cc < ccend)
5350    
5351      case OP_REF:      case OP_REF:
5352      case OP_REFI:      case OP_REFI:
5353      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5354        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5355      else      else
5356        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);        cc = compile_ref_hotpath(common, cc, parent->top != NULL ? &parent->top->nextfallbacks : &parent->topfallbacks, TRUE, FALSE);
# Line 4937  while (cc < ccend) Line 5383  while (cc < ccend)
5383        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), STR_PTR, 0);
5384        }        }
5385      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();      FALLBACK_AS(braminzero_fallback)->hotpath = LABEL();
5386        if (cc[1] > OP_ASSERTBACK_NOT)
5387          decrease_call_count(common);
5388      break;      break;
5389    
5390      case OP_ONCE:      case OP_ONCE:
5391        case OP_ONCE_NC:
5392      case OP_BRA:      case OP_BRA:
5393      case OP_CBRA:      case OP_CBRA:
5394      case OP_COND:      case OP_COND:
# Line 5009  SLJIT_ASSERT(cc == ccend); Line 5458  SLJIT_ASSERT(cc == ccend);
5458  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5459  {  {
5460  DEFINE_COMPILER;  DEFINE_COMPILER;
5461  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5462  uschar opcode;  pcre_uchar opcode;
5463  uschar type;  pcre_uchar type;
5464  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5465  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5466  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5136  switch(opcode) Line 5585  switch(opcode)
5585  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_ref_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5586  {  {
5587  DEFINE_COMPILER;  DEFINE_COMPILER;
5588  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5589  uschar type;  pcre_uchar type;
5590    
5591  type = cc[3];  type = cc[1 + IMM2_SIZE];
5592  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5593    {    {
5594    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5168  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5617  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5617  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5618  {  {
5619  DEFINE_COMPILER;  DEFINE_COMPILER;
5620  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5621  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
 struct sljit_jump *jump;  
5622  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5623    
5624  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5216  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5664  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5664    {    {
5665    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);
5666    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5667      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));
5668    
5669    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5670    }    }
5671  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5672    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
   OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr);  
   add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
   JUMPHERE(jump);  
   }  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), CURRENT_AS(assert_fallback)->localptr, SLJIT_MEM1(STACK_TOP), CURRENT_AS(assert_fallback)->framesize * sizeof(sljit_w));  
5673    
5674  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5675    {    {
# Line 5248  int offset = 0; Line 5689  int offset = 0;
5689  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5690  int stacksize;  int stacksize;
5691  int count;  int count;
5692  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5693  uschar *ccbegin;  pcre_uchar *ccbegin;
5694  uschar *ccprev;  pcre_uchar *ccprev;
5695  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5696  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5697  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5698  uschar ket;  pcre_uchar ket;
5699  assert_fallback *assert;  assert_fallback *assert;
5700    BOOL has_alternatives;
5701  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5702  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5703  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5271  opcode = *cc; Line 5713  opcode = *cc;
5713  ccbegin = cc;  ccbegin = cc;
5714  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5715  cc += GET(cc, 1);  cc += GET(cc, 1);
5716    has_alternatives = *cc == OP_ALT;
5717    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5718      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5719  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5720    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5721  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5722    opcode = OP_SCOND;    opcode = OP_SCOND;
5723    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5724      opcode = OP_ONCE;
5725    
5726  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5727    {    {
# Line 5317  else if (bra == OP_BRAZERO) Line 5764  else if (bra == OP_BRAZERO)
5764    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5765    }    }
5766    
5767  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5768    {    {
5769    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5770      {      {
# Line 5326  if (opcode == OP_ONCE) Line 5773  if (opcode == OP_ONCE)
5773      }      }
5774    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5775    }    }
5776    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5777      {
5778      if (has_alternatives)
5779        {
5780        /* Always exactly one alternative. */
5781        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5782        free_stack(common, 1);
5783    
5784        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5785        if (SLJIT_UNLIKELY(!jumplistitem))
5786          return;
5787        jumplist = jumplistitem;
5788        jumplistitem->next = NULL;
5789        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5790        }
5791      }
5792  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5793    {    {
5794    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5357  else if (*cc == OP_ALT) Line 5820  else if (*cc == OP_ALT)
5820    
5821    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5822    }    }
 else if (opcode == OP_COND || opcode == OP_SCOND)  
   {  
   /* Always one. */  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));