/[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 695 by zherczeg, Sat Sep 17 06:05:38 2011 UTC revision 883 by zherczeg, Mon Jan 16 08:35:42 2012 UTC
# Line 6  Line 6 
6  and semantics are as close as possible to those of the Perl 5 language.  and semantics are as close as possible to those of the Perl 5 language.
7    
8                         Written by Philip Hazel                         Written by Philip Hazel
9             Copyright (c) 1997-2008 University of Cambridge             Copyright (c) 1997-2012 University of Cambridge
10    
11    The machine code generator part (this module) was written by Zoltan Herczeg    The machine code generator part (this module) was written by Zoltan Herczeg
12                        Copyright (c) 2010-2011                        Copyright (c) 2010-2012
13    
14  -----------------------------------------------------------------------------  -----------------------------------------------------------------------------
15  Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
# Line 52  POSSIBILITY OF SUCH DAMAGE. Line 52  POSSIBILITY OF SUCH DAMAGE.
52  we just include it. This way we don't need to touch the build  we just include it. This way we don't need to touch the build
53  system files. */  system files. */
54    
55    #define SLJIT_MALLOC(size) (PUBL(malloc))(size)
56    #define SLJIT_FREE(ptr) (PUBL(free))(ptr)
57  #define SLJIT_CONFIG_AUTO 1  #define SLJIT_CONFIG_AUTO 1
58    #define SLJIT_CONFIG_STATIC 1
59  #define SLJIT_VERBOSE 0  #define SLJIT_VERBOSE 0
60  #define SLJIT_DEBUG 0  #define SLJIT_DEBUG 0
61    
62  #include "sljit/sljitLir.c"  #include "sljit/sljitLir.c"
63    
64  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED  #if defined SLJIT_CONFIG_UNSUPPORTED && SLJIT_CONFIG_UNSUPPORTED
65  #error "Unsupported architecture"  #error Unsupported architecture
66  #endif  #endif
67    
68  /* Allocate memory on the stack. Fast, but limited size. */  /* Allocate memory on the stack. Fast, but limited size. */
# Line 145  Thus we can restore the locals to a part Line 148  Thus we can restore the locals to a part
148  typedef struct jit_arguments {  typedef struct jit_arguments {
149    /* Pointers first. */    /* Pointers first. */
150    struct sljit_stack *stack;    struct sljit_stack *stack;
151    PCRE_SPTR str;    const pcre_uchar *str;
152    PCRE_SPTR begin;    const pcre_uchar *begin;
153    PCRE_SPTR end;    const pcre_uchar *end;
154    int *offsets;    int *offsets;
155    uschar *ptr;    pcre_uchar *ptr;
156    /* Everything else after. */    /* Everything else after. */
157    int offsetcount;    int offsetcount;
158    int calllimit;    int calllimit;
159    uschar notbol;    pcre_uint8 notbol;
160    uschar noteol;    pcre_uint8 noteol;
161    uschar notempty;    pcre_uint8 notempty;
162    uschar notempty_atstart;    pcre_uint8 notempty_atstart;
163  } jit_arguments;  } jit_arguments;
164    
165  typedef struct executable_function {  typedef struct executable_function {
166    void *executable_func;    void *executable_func;
167    pcre_jit_callback callback;    PUBL(jit_callback) callback;
168    void *userdata;    void *userdata;
169      sljit_uw executable_size;
170  } executable_function;  } executable_function;
171    
172  typedef struct jump_list {  typedef struct jump_list {
# Line 170  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 194  typedef struct fallback_common { Line 198  typedef struct fallback_common {
198    struct fallback_common *top;    struct fallback_common *top;
199    jump_list *topfallbacks;    jump_list *topfallbacks;
200    /* Opcode pointer. */    /* Opcode pointer. */
201    uschar *cc;    pcre_uchar *cc;
202  } fallback_common;  } fallback_common;
203    
204  typedef struct assert_fallback {  typedef struct assert_fallback {
# Line 265  typedef struct recurse_fallback { Line 269  typedef struct recurse_fallback {
269    
270  typedef struct compiler_common {  typedef struct compiler_common {
271    struct sljit_compiler *compiler;    struct sljit_compiler *compiler;
272    uschar *start;    pcre_uchar *start;
273    int localsize;    int localsize;
274    int *localptrs;    int *localptrs;
275    const uschar *fcc;    const pcre_uint8 *fcc;
276    sljit_w lcc;    sljit_w lcc;
277    int cbraptr;    int cbraptr;
278    int nltype;    int nltype;
# Line 276  typedef struct compiler_common { Line 280  typedef struct compiler_common {
280    int bsr_nltype;    int bsr_nltype;
281    int endonly;    int endonly;
282    sljit_w ctypes;    sljit_w ctypes;
283      sljit_uw name_table;
284      sljit_w name_count;
285      sljit_w name_entry_size;
286    struct sljit_label *acceptlabel;    struct sljit_label *acceptlabel;
287    stub_list *stubs;    stub_list *stubs;
288    recurse_entry *entries;    recurse_entry *entries;
# Line 291  typedef struct compiler_common { Line 298  typedef struct compiler_common {
298    jump_list *casefulcmp;    jump_list *casefulcmp;
299    jump_list *caselesscmp;    jump_list *caselesscmp;
300    BOOL jscript_compat;    BOOL jscript_compat;
301  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
302    BOOL utf8;    BOOL utf;
303  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
304    BOOL useucp;    BOOL use_ucp;
305  #endif  #endif
306    jump_list *utf8readchar;    jump_list *utfreadchar;
307    jump_list *utf8readtype8;  #ifdef COMPILE_PCRE8
308      jump_list *utfreadtype8;
309  #endif  #endif
310    #endif /* SUPPORT_UTF */
311  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
312    jump_list *getucd;    jump_list *getucd;
313  #endif  #endif
# Line 310  typedef struct compare_context { Line 319  typedef struct compare_context {
319    int length;    int length;
320    int sourcereg;    int sourcereg;
321  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
322    int byteptr;    int ucharptr;
323    union {    union {
324      int asint;      sljit_i asint;
325      short asshort;      sljit_uh asushort;
326    #ifdef COMPILE_PCRE8
327      sljit_ub asbyte;      sljit_ub asbyte;
328      sljit_ub asbytes[4];      sljit_ub asuchars[4];
329    #else
330    #ifdef COMPILE_PCRE16
331        sljit_uh asuchars[2];
332    #endif
333    #endif
334    } c;    } c;
335    union {    union {
336      int asint;      sljit_i asint;
337      short asshort;      sljit_uh asushort;
338    #ifdef COMPILE_PCRE8
339      sljit_ub asbyte;      sljit_ub asbyte;
340      sljit_ub asbytes[4];      sljit_ub asuchars[4];
341    #else
342    #ifdef COMPILE_PCRE16
343        sljit_uh asuchars[2];
344    #endif
345    #endif
346    } oc;    } oc;
347  #endif  #endif
348  } compare_context;  } compare_context;
349    
350  enum {  enum {
351    frame_end = 0,    frame_end = 0,
352    frame_setmaxindex = -1,    frame_setstrbegin = -1
   frame_setstrbegin = -2  
353  };  };
354    
355    /* Undefine sljit macros. */
356    #undef CMP
357    
358  /* Used for accessing the elements of the stack. */  /* Used for accessing the elements of the stack. */
359  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))  #define STACK(i)      ((-(i) - 1) * (int)sizeof(sljit_w))
360    
361  #define TMP1          SLJIT_TEMPORARY_REG1  #define TMP1          SLJIT_TEMPORARY_REG1
362  #define TMP2          SLJIT_TEMPORARY_REG3  #define TMP2          SLJIT_TEMPORARY_REG3
363  #define TMP3          SLJIT_TEMPORARY_EREG2  #define TMP3          SLJIT_TEMPORARY_EREG2
364  #define STR_PTR       SLJIT_GENERAL_REG1  #define STR_PTR       SLJIT_SAVED_REG1
365  #define STR_END       SLJIT_GENERAL_REG2  #define STR_END       SLJIT_SAVED_REG2
366  #define STACK_TOP     SLJIT_TEMPORARY_REG2  #define STACK_TOP     SLJIT_TEMPORARY_REG2
367  #define STACK_LIMIT   SLJIT_GENERAL_REG3  #define STACK_LIMIT   SLJIT_SAVED_REG3
368  #define ARGUMENTS     SLJIT_GENERAL_EREG1  #define ARGUMENTS     SLJIT_SAVED_EREG1
369  #define CALL_COUNT    SLJIT_GENERAL_EREG2  #define CALL_COUNT    SLJIT_SAVED_EREG2
370  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1  #define RETURN_ADDR   SLJIT_TEMPORARY_EREG1
371    
372  /* Locals layout. */  /* Locals layout. */
# Line 353  enum { Line 376  enum {
376  /* Two local variables for possessive quantifiers (char1 cannot use them). */  /* Two local variables for possessive quantifiers (char1 cannot use them). */
377  #define POSSESSIVE0      (2 * sizeof(sljit_w))  #define POSSESSIVE0      (2 * sizeof(sljit_w))
378  #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))  
379  /* Head of the last recursion. */  /* Head of the last recursion. */
380  #define RECURSIVE_HEAD   (5 * sizeof(sljit_w))  #define RECURSIVE_HEAD   (4 * sizeof(sljit_w))
 /* Number of recursions. */  
 #define MAX_INDEX        (6 * sizeof(sljit_w))  
381  /* Max limit of recursions. */  /* Max limit of recursions. */
382  #define CALL_LIMIT       (7 * sizeof(sljit_w))  #define CALL_LIMIT       (5 * sizeof(sljit_w))
383  /* Last known position of the requested byte. */  /* Last known position of the requested byte. */
384  #define REQ_BYTE_PTR     (8 * sizeof(sljit_w))  #define REQ_CHAR_PTR     (6 * sizeof(sljit_w))
385  /* End pointer of the first line. */  /* End pointer of the first line. */
386  #define FIRSTLINE_END    (9 * sizeof(sljit_w))  #define FIRSTLINE_END    (7 * sizeof(sljit_w))
387  /* The output vector is stored on the stack, and contains pointers  /* The output vector is stored on the stack, and contains pointers
388  to characters. The vector data is divided into two groups: the first  to characters. The vector data is divided into two groups: the first
389  group contains the start / end character pointers, and the second is  group contains the start / end character pointers, and the second is
390  the start pointers when the end of the capturing group has not yet reached. */  the start pointers when the end of the capturing group has not yet reached. */
391  #define OVECTOR_START    (10 * sizeof(sljit_w))  #define OVECTOR_START    (8 * sizeof(sljit_w))
392  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))  #define OVECTOR(i)       (OVECTOR_START + (i) * sizeof(sljit_w))
393  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))  #define OVECTOR_PRIV(i)  (common->cbraptr + (i) * sizeof(sljit_w))
394  #define PRIV(cc)         (common->localptrs[(cc) - common->start])  #define PRIV_DATA(cc)    (common->localptrs[(cc) - common->start])
395    
396    #ifdef COMPILE_PCRE8
397    #define MOV_UCHAR  SLJIT_MOV_UB
398    #define MOVU_UCHAR SLJIT_MOVU_UB
399    #else
400    #ifdef COMPILE_PCRE16
401    #define MOV_UCHAR  SLJIT_MOV_UH
402    #define MOVU_UCHAR SLJIT_MOVU_UH
403    #else
404    #error Unsupported compiling mode
405    #endif
406    #endif
407    
408  /* Shortcuts. */  /* Shortcuts. */
409  #define DEFINE_COMPILER \  #define DEFINE_COMPILER \
# Line 396  the start pointers when the end of the c Line 427  the start pointers when the end of the c
427  #define COND_VALUE(op, dst, dstw, type) \  #define COND_VALUE(op, dst, dstw, type) \
428    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))    sljit_emit_cond_value(compiler, (op), (dst), (dstw), (type))
429    
430  static uschar* bracketend(uschar* cc)  static pcre_uchar* bracketend(pcre_uchar* cc)
431  {  {
432  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));  SLJIT_ASSERT((*cc >= OP_ASSERT && *cc <= OP_ASSERTBACK_NOT) || (*cc >= OP_ONCE && *cc <= OP_SCOND));
433  do cc += GET(cc, 1); while (*cc == OP_ALT);  do cc += GET(cc, 1); while (*cc == OP_ALT);
# Line 417  return cc; Line 448  return cc;
448   compile_fallbackpath   compile_fallbackpath
449  */  */
450    
451  static uschar *next_opcode(compiler_common *common, uschar *cc)  static pcre_uchar *next_opcode(compiler_common *common, pcre_uchar *cc)
452  {  {
453  SLJIT_UNUSED_ARG(common);  SLJIT_UNUSED_ARG(common);
454  switch(*cc)  switch(*cc)
# Line 472  switch(*cc) Line 503  switch(*cc)
503    case OP_SKIPZERO:    case OP_SKIPZERO:
504    return cc + 1;    return cc + 1;
505    
506      case OP_ANYBYTE:
507    #ifdef SUPPORT_UTF
508      if (common->utf) return NULL;
509    #endif
510      return cc + 1;
511    
512    case OP_CHAR:    case OP_CHAR:
513    case OP_CHARI:    case OP_CHARI:
514    case OP_NOT:    case OP_NOT:
515    case OP_NOTI:    case OP_NOTI:
   
516    case OP_STAR:    case OP_STAR:
517    case OP_MINSTAR:    case OP_MINSTAR:
518    case OP_PLUS:    case OP_PLUS:
# Line 514  switch(*cc) Line 550  switch(*cc)
550    case OP_NOTPOSPLUSI:    case OP_NOTPOSPLUSI:
551    case OP_NOTPOSQUERYI:    case OP_NOTPOSQUERYI:
552    cc += 2;    cc += 2;
553  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
554    if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
555  #endif  #endif
556    return cc;    return cc;
557    
# Line 535  switch(*cc) Line 571  switch(*cc)
571    case OP_NOTMINUPTOI:    case OP_NOTMINUPTOI:
572    case OP_NOTEXACTI:    case OP_NOTEXACTI:
573    case OP_NOTPOSUPTOI:    case OP_NOTPOSUPTOI:
574    cc += 4;    cc += 2 + IMM2_SIZE;
575  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
576    if (common->utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];    if (common->utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
577  #endif  #endif
578    return cc;    return cc;
579    
580    case OP_NOTPROP:    case OP_NOTPROP:
581    case OP_PROP:    case OP_PROP:
582      return cc + 1 + 2;
583    
584    case OP_TYPEUPTO:    case OP_TYPEUPTO:
585    case OP_TYPEMINUPTO:    case OP_TYPEMINUPTO:
586    case OP_TYPEEXACT:    case OP_TYPEEXACT:
# Line 550  switch(*cc) Line 588  switch(*cc)
588    case OP_REF:    case OP_REF:
589    case OP_REFI:    case OP_REFI:
590    case OP_CREF:    case OP_CREF:
591      case OP_NCREF:
592      case OP_RREF:
593      case OP_NRREF:
594    case OP_CLOSE:    case OP_CLOSE:
595    cc += 3;    cc += 1 + IMM2_SIZE;
596    return cc;    return cc;
597    
598    case OP_CRRANGE:    case OP_CRRANGE:
599    case OP_CRMINRANGE:    case OP_CRMINRANGE:
600    return cc + 5;    return cc + 1 + 2 * IMM2_SIZE;
601    
602    case OP_CLASS:    case OP_CLASS:
603    case OP_NCLASS:    case OP_NCLASS:
604    return cc + 33;    return cc + 1 + 32 / sizeof(pcre_uchar);
605    
606  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
607    case OP_XCLASS:    case OP_XCLASS:
608    return cc + GET(cc, 1);    return cc + GET(cc, 1);
609  #endif  #endif
# Line 574  switch(*cc) Line 615  switch(*cc)
615    case OP_ASSERTBACK_NOT:    case OP_ASSERTBACK_NOT:
616    case OP_REVERSE:    case OP_REVERSE:
617    case OP_ONCE:    case OP_ONCE:
618      case OP_ONCE_NC:
619    case OP_BRA:    case OP_BRA:
620    case OP_BRAPOS:    case OP_BRAPOS:
621    case OP_COND:    case OP_COND:
# Line 591  switch(*cc) Line 633  switch(*cc)
633    case OP_CBRAPOS:    case OP_CBRAPOS:
634    case OP_SCBRA:    case OP_SCBRA:
635    case OP_SCBRAPOS:    case OP_SCBRAPOS:
636    return cc + 1 + LINK_SIZE + 2;    return cc + 1 + LINK_SIZE + IMM2_SIZE;
637    
638    default:    default:
639    return NULL;    return NULL;
640    }    }
641  }  }
642    
643  static int get_localspace(compiler_common *common, uschar *cc, uschar *ccend)  static int get_localspace(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend)
644  {  {
645  int localspace = 0;  int localspace = 0;
646  uschar *alternative;  pcre_uchar *alternative;
647  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */  /* Calculate important variables (like stack size) and checks whether all opcodes are supported. */
648  while (cc < ccend)  while (cc < ccend)
649    {    {
# Line 612  while (cc < ccend) Line 654  while (cc < ccend)
654      case OP_ASSERTBACK:      case OP_ASSERTBACK:
655      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
656      case OP_ONCE:      case OP_ONCE:
657        case OP_ONCE_NC:
658      case OP_BRAPOS:      case OP_BRAPOS:
659      case OP_SBRA:      case OP_SBRA:
660      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 623  while (cc < ccend) Line 666  while (cc < ccend)
666      case OP_CBRAPOS:      case OP_CBRAPOS:
667      case OP_SCBRAPOS:      case OP_SCBRAPOS:
668      localspace += sizeof(sljit_w);      localspace += sizeof(sljit_w);
669      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
670      break;      break;
671    
672      case OP_COND:      case OP_COND:
# Line 644  while (cc < ccend) Line 687  while (cc < ccend)
687  return localspace;  return localspace;
688  }  }
689    
690  static void set_localptrs(compiler_common *common, int localptr, uschar *ccend)  static void set_localptrs(compiler_common *common, int localptr, pcre_uchar *ccend)
691  {  {
692  uschar *cc = common->start;  pcre_uchar *cc = common->start;
693  uschar *alternative;  pcre_uchar *alternative;
694  while (cc < ccend)  while (cc < ccend)
695    {    {
696    switch(*cc)    switch(*cc)
# Line 657  while (cc < ccend) Line 700  while (cc < ccend)
700      case OP_ASSERTBACK:      case OP_ASSERTBACK:
701      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
702      case OP_ONCE:      case OP_ONCE:
703        case OP_ONCE_NC:
704      case OP_BRAPOS:      case OP_BRAPOS:
705      case OP_SBRA:      case OP_SBRA:
706      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 670  while (cc < ccend) Line 714  while (cc < ccend)
714      case OP_SCBRAPOS:      case OP_SCBRAPOS:
715      common->localptrs[cc - common->start] = localptr;      common->localptrs[cc - common->start] = localptr;
716      localptr += sizeof(sljit_w);      localptr += sizeof(sljit_w);
717      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
718      break;      break;
719    
720      case OP_COND:      case OP_COND:
# Line 693  while (cc < ccend) Line 737  while (cc < ccend)
737  }  }
738    
739  /* Returns with -1 if no need for frame. */  /* Returns with -1 if no need for frame. */
740  static int get_framesize(compiler_common *common, uschar *cc, BOOL recursive)  static int get_framesize(compiler_common *common, pcre_uchar *cc, BOOL recursive)
741  {  {
742  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 uschar *end;  
743  int length = 0;  int length = 0;
744  BOOL possessive = FALSE;  BOOL possessive = FALSE;
 BOOL needs_frame = FALSE;  
 BOOL needs_maxindex = FALSE;  
745  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
746    
747  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))  if (!recursive && (*cc == OP_CBRAPOS || *cc == OP_SCBRAPOS))
748    {    {
749    length = 3 + 2;    length = 3;
   needs_maxindex = TRUE;  
750    possessive = TRUE;    possessive = TRUE;
751    }    }
752    
# Line 725  while (cc < ccend) Line 765  while (cc < ccend)
765      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
766      break;      break;
767    
     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;  
   
768      case OP_CBRA:      case OP_CBRA:
769      case OP_CBRAPOS:      case OP_CBRAPOS:
770      case OP_SCBRA:      case OP_SCBRA:
771      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       needs_maxindex = TRUE;  
       length += 2;  
       }  
772      length += 3;      length += 3;
773      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
774      break;      break;
775    
776      default:      default:
# Line 767  while (cc < ccend) Line 780  while (cc < ccend)
780      }      }
781    
782  /* Possessive quantifiers can use a special case. */  /* Possessive quantifiers can use a special case. */
783  if (SLJIT_UNLIKELY(possessive) && !needs_frame && length == 3 + 2)  if (SLJIT_UNLIKELY(possessive) && length == 3)
784    return -1;    return -1;
785    
786  if (length > 0)  if (length > 0)
787    return length + 2;    return length + 1;
788  return needs_frame ? 0 : -1;  return -1;
789  }  }
790    
791  static void init_frame(compiler_common *common, uschar *cc, int stackpos, int stacktop, BOOL recursive)  static void init_frame(compiler_common *common, pcre_uchar *cc, int stackpos, int stacktop, BOOL recursive)
792  {  {
 /* TMP2 must contain STACK_TOP - (-STACK(stackpos)) */  
793  DEFINE_COMPILER;  DEFINE_COMPILER;
794  uschar *ccend = bracketend(cc);  pcre_uchar *ccend = bracketend(cc);
 BOOL needs_maxindex = FALSE;  
795  BOOL setsom_found = FALSE;  BOOL setsom_found = FALSE;
796  int offset;  int offset;
797    
798  if (stackpos < stacktop)  /* >= 1 + shortest item size (2) */
799    {  SLJIT_ASSERT(stackpos >= stacktop + 2);
   SLJIT_ASSERT(stackpos + 1 == stacktop);  
   return;  
   }  
800    
801  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);  
   
802  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))  if (recursive || (*cc != OP_CBRAPOS && *cc != OP_SCBRAPOS))
803    cc = next_opcode(common, cc);    cc = next_opcode(common, cc);
804  SLJIT_ASSERT(cc != NULL);  SLJIT_ASSERT(cc != NULL);
# Line 815  while (cc < ccend) Line 819  while (cc < ccend)
819      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;      cc += (*cc == OP_SET_SOM) ? 1 : 1 + LINK_SIZE;
820      break;      break;
821    
     case OP_ASSERT:  
     case OP_ASSERT_NOT:  
     case OP_ASSERTBACK:  
     case OP_ASSERTBACK_NOT:  
     case OP_ONCE:  
     cc = bracketend(cc);  
     break;  
   
822      case OP_CBRA:      case OP_CBRA:
823      case OP_CBRAPOS:      case OP_CBRAPOS:
824      case OP_SCBRA:      case OP_SCBRA:
825      case OP_SCBRAPOS:      case OP_SCBRAPOS:
     if (!needs_maxindex)  
       {  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
       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, TMP1, 0);  
       stackpos += (int)sizeof(sljit_w);  
       needs_maxindex = TRUE;  
       }  
826      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;      offset = (GET2(cc, 1 + LINK_SIZE)) << 1;
827      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, OVECTOR(offset));
828      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
# Line 846  while (cc < ccend) Line 833  while (cc < ccend)
833      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, TMP2, 0);
834      stackpos += (int)sizeof(sljit_w);      stackpos += (int)sizeof(sljit_w);
835    
836      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
837      break;      break;
838    
839      default:      default:
# Line 856  while (cc < ccend) Line 843  while (cc < ccend)
843      }      }
844    
845  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);  OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), stackpos, SLJIT_IMM, frame_end);
846  SLJIT_ASSERT(stackpos == STACK(stacktop + 1));  SLJIT_ASSERT(stackpos == STACK(stacktop));
847  }  }
848    
849  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)
850  {  {
851  int localsize = 2;  int localsize = 2;
852  uschar *alternative;  pcre_uchar *alternative;
853  /* Calculate the sum of the local variables. */  /* Calculate the sum of the local variables. */
854  while (cc < ccend)  while (cc < ccend)
855    {    {
# Line 873  while (cc < ccend) Line 860  while (cc < ccend)
860      case OP_ASSERTBACK:      case OP_ASSERTBACK:
861      case OP_ASSERTBACK_NOT:      case OP_ASSERTBACK_NOT:
862      case OP_ONCE:      case OP_ONCE:
863        case OP_ONCE_NC:
864      case OP_BRAPOS:      case OP_BRAPOS:
865      case OP_SBRA:      case OP_SBRA:
866      case OP_SBRAPOS:      case OP_SBRAPOS:
# Line 884  while (cc < ccend) Line 872  while (cc < ccend)
872      case OP_CBRA:      case OP_CBRA:
873      case OP_SCBRA:      case OP_SCBRA:
874      localsize++;      localsize++;
875      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
876      break;      break;
877    
878      case OP_CBRAPOS:      case OP_CBRAPOS:
879      case OP_SCBRAPOS:      case OP_SCBRAPOS:
880      localsize += 2;      localsize += 2;
881      cc += 1 + LINK_SIZE + 2;      cc += 1 + LINK_SIZE + IMM2_SIZE;
882      break;      break;
883    
884      case OP_COND:      case OP_COND:
# Line 911  SLJIT_ASSERT(cc == ccend); Line 899  SLJIT_ASSERT(cc == ccend);
899  return localsize;  return localsize;
900  }  }
901    
902  static void copy_locals(compiler_common *common, uschar *cc, uschar *ccend,  static void copy_locals(compiler_common *common, pcre_uchar *cc, pcre_uchar *ccend,
903    BOOL save, int stackptr, int stacktop)    BOOL save, int stackptr, int stacktop)
904  {  {
905  DEFINE_COMPILER;  DEFINE_COMPILER;
# Line 920  int count; Line 908  int count;
908  BOOL tmp1next = TRUE;  BOOL tmp1next = TRUE;
909  BOOL tmp1empty = TRUE;  BOOL tmp1empty = TRUE;
910  BOOL tmp2empty = TRUE;  BOOL tmp2empty = TRUE;
911  uschar *alternative;  pcre_uchar *alternative;
912  enum {  enum {
913    start,    start,
914    loop,    loop,
# Line 975  while (status != end) Line 963  while (status != end)
963        case OP_ASSERTBACK:        case OP_ASSERTBACK:
964        case OP_ASSERTBACK_NOT:        case OP_ASSERTBACK_NOT:
965        case OP_ONCE:        case OP_ONCE:
966          case OP_ONCE_NC:
967        case OP_BRAPOS:        case OP_BRAPOS:
968        case OP_SBRA:        case OP_SBRA:
969        case OP_SBRAPOS:        case OP_SBRAPOS:
970        case OP_SCOND:        case OP_SCOND:
971        count = 1;        count = 1;
972        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
973        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
974        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
975        break;        break;
# Line 989  while (status != end) Line 978  while (status != end)
978        case OP_SCBRA:        case OP_SCBRA:
979        count = 1;        count = 1;
980        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[0] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
981        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
982        break;        break;
983    
984        case OP_CBRAPOS:        case OP_CBRAPOS:
985        case OP_SCBRAPOS:        case OP_SCBRAPOS:
986        count = 2;        count = 2;
987        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));        srcw[1] = OVECTOR_PRIV(GET2(cc, 1 + LINK_SIZE));
988        srcw[0] = PRIV(cc);        srcw[0] = PRIV_DATA(cc);
989        SLJIT_ASSERT(srcw[0] != 0);        SLJIT_ASSERT(srcw[0] != 0);
990        cc += 1 + LINK_SIZE + 2;        cc += 1 + LINK_SIZE + IMM2_SIZE;
991        break;        break;
992    
993        case OP_COND:        case OP_COND:
# Line 1007  while (status != end) Line 996  while (status != end)
996        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)        if (*alternative == OP_KETRMAX || *alternative == OP_KETRMIN)
997          {          {
998          count = 1;          count = 1;
999          srcw[0] = PRIV(cc);          srcw[0] = PRIV_DATA(cc);
1000          SLJIT_ASSERT(srcw[0] != 0);          SLJIT_ASSERT(srcw[0] != 0);
1001          }          }
1002        cc += 1 + LINK_SIZE;        cc += 1 + LINK_SIZE;
# Line 1171  while (list_item) Line 1160  while (list_item)
1160      case stack_alloc:      case stack_alloc:
1161      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));      add_jump(compiler, &common->stackalloc, JUMP(SLJIT_FAST_CALL));
1162      break;      break;
   
     case max_index:  
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, list_item->data);  
     break;  
1163      }      }
1164    JUMPTO(SLJIT_JUMP, list_item->leave);    JUMPTO(SLJIT_JUMP, list_item->leave);
1165    list_item = list_item->next;    list_item = list_item->next;
# Line 1219  struct sljit_label *loop; Line 1204  struct sljit_label *loop;
1204  int i;  int i;
1205  /* At this point we can freely use all temporary registers. */  /* At this point we can freely use all temporary registers. */
1206  /* TMP1 returns with begin - 1. */  /* TMP1 returns with begin - 1. */
1207  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, 1);  OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, IN_UCHARS(1));
 OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), SLJIT_OFFSETOF(jit_arguments, begin), SLJIT_IMM, 1);  
1208  if (length < 8)  if (length < 8)
1209    {    {
1210    for (i = 0; i < length; i++)    for (i = 0; i < length; i++)
# Line 1237  else Line 1221  else
1221    }    }
1222  }  }
1223    
1224  static SLJIT_INLINE void copy_ovector(compiler_common *common)  static SLJIT_INLINE void copy_ovector(compiler_common *common, int topbracket)
1225  {  {
1226  DEFINE_COMPILER;  DEFINE_COMPILER;
1227  struct sljit_label *loop;  struct sljit_label *loop;
1228  struct sljit_jump *earlyexit;  struct sljit_jump *earlyexit;
1229    
1230  /* At this point we can freely use all registers. */  /* At this point we can freely use all registers. */
1231    OP1(SLJIT_MOV, SLJIT_SAVED_REG3, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
1232    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1), STR_PTR, 0);
1233    
1234  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, ARGUMENTS, 0);
1235  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));
1236  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));
1237  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));  OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), SLJIT_OFFSETOF(jit_arguments, begin));
1238  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START);
1239  /* Unlikely, but possible */  /* Unlikely, but possible */
1240  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);  earlyexit = CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 0);
1241  loop = LABEL();  loop = LABEL();
1242  OP2(SLJIT_SUB, SLJIT_GENERAL_REG2, 0, SLJIT_MEM1(SLJIT_GENERAL_REG1), 0, SLJIT_TEMPORARY_REG1, 0);  OP2(SLJIT_SUB, SLJIT_SAVED_REG2, 0, SLJIT_MEM1(SLJIT_SAVED_REG1), 0, SLJIT_TEMPORARY_REG1, 0);
1243  OP2(SLJIT_ADD, SLJIT_GENERAL_REG1, 0, SLJIT_GENERAL_REG1, 0, SLJIT_IMM, sizeof(sljit_w));  OP2(SLJIT_ADD, SLJIT_SAVED_REG1, 0, SLJIT_SAVED_REG1, 0, SLJIT_IMM, sizeof(sljit_w));
1244  /* Copy the integer value to the output buffer */  /* Copy the integer value to the output buffer */
1245  OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_GENERAL_REG2, 0);  #ifdef COMPILE_PCRE16
1246    OP2(SLJIT_ASHR, SLJIT_SAVED_REG2, 0, SLJIT_SAVED_REG2, 0, SLJIT_IMM, 1);
1247    #endif
1248    OP1(SLJIT_MOVU_SI, SLJIT_MEM1(SLJIT_TEMPORARY_REG3), sizeof(int), SLJIT_SAVED_REG2, 0);
1249  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);
1250  JUMPTO(SLJIT_C_NOT_ZERO, loop);  JUMPTO(SLJIT_C_NOT_ZERO, loop);
1251  JUMPHERE(earlyexit);  JUMPHERE(earlyexit);
1252    
1253    /* Calculate the return value, which is the maximum ovector value. */
1254    if (topbracket > 1)
1255      {
1256      OP2(SLJIT_ADD, SLJIT_TEMPORARY_REG1, 0, SLJIT_LOCALS_REG, 0, SLJIT_IMM, OVECTOR_START + topbracket * 2 * sizeof(sljit_w));
1257      OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, topbracket + 1);
1258    
1259      /* OVECTOR(0) is never equal to SLJIT_SAVED_REG3. */
1260      loop = LABEL();
1261      OP1(SLJIT_MOVU, SLJIT_TEMPORARY_REG3, 0, SLJIT_MEM1(SLJIT_TEMPORARY_REG1), -(2 * (sljit_w)sizeof(sljit_w)));
1262      OP2(SLJIT_SUB, SLJIT_TEMPORARY_REG2, 0, SLJIT_TEMPORARY_REG2, 0, SLJIT_IMM, 1);
1263      CMPTO(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG3, 0, SLJIT_SAVED_REG3, 0, loop);
1264      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_TEMPORARY_REG2, 0);
1265      }
1266    else
1267      OP1(SLJIT_MOV, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1);
1268  }  }
1269    
1270  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)
1271  {  {
1272  /* Detects if the character has an othercase. */  /* Detects if the character has an othercase. */
1273  unsigned int c;  unsigned int c;
1274    
1275  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1276  if (common->utf8)  if (common->utf)
1277    {    {
1278    GETCHAR(c, cc);    GETCHAR(c, cc);
1279    if (c > 127)    if (c > 127)
# Line 1278  if (common->utf8) Line 1284  if (common->utf8)
1284      return FALSE;      return FALSE;
1285  #endif  #endif
1286      }      }
1287    #ifndef COMPILE_PCRE8
1288      return common->fcc[c] != c;
1289    #endif
1290    }    }
1291  else  else
1292  #endif  #endif
1293    c = *cc;    c = *cc;
1294  return common->fcc[c] != c;  return MAX_255(c) ? common->fcc[c] != c : FALSE;
1295  }  }
1296    
1297  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)
1298  {  {
1299  /* Returns with the othercase. */  /* Returns with the othercase. */
1300  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1301  if (common->utf8 && c > 127)  if (common->utf && c > 127)
1302    {    {
1303  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1304    return UCD_OTHERCASE(c);    return UCD_OTHERCASE(c);
# Line 1298  if (common->utf8 && c > 127) Line 1307  if (common->utf8 && c > 127)
1307  #endif  #endif
1308    }    }
1309  #endif  #endif
1310  return common->fcc[c];  return TABLE_GET(c, common->fcc, c);
1311  }  }
1312    
1313  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)
1314  {  {
1315  /* Detects if the character and its othercase has only 1 bit difference. */  /* Detects if the character and its othercase has only 1 bit difference. */
1316  unsigned int c, oc, bit;  unsigned int c, oc, bit;
1317  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1318  int n;  int n;
1319  #endif  #endif
1320    
1321  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1322  if (common->utf8)  if (common->utf)
1323    {    {
1324    GETCHAR(c, cc);    GETCHAR(c, cc);
1325    if (c <= 127)    if (c <= 127)
# Line 1327  if (common->utf8) Line 1336  if (common->utf8)
1336  else  else
1337    {    {
1338    c = *cc;    c = *cc;
1339    oc = common->fcc[c];    oc = TABLE_GET(c, common->fcc, c);
1340    }    }
1341  #else  #else
1342  c = *cc;  c = *cc;
1343  oc = common->fcc[c];  oc = TABLE_GET(c, common->fcc, c);
1344  #endif  #endif
1345    
1346  SLJIT_ASSERT(c != oc);  SLJIT_ASSERT(c != oc);
# Line 1345  if (c <= 127 && bit == 0x20) Line 1354  if (c <= 127 && bit == 0x20)
1354  if (!ispowerof2(bit))  if (!ispowerof2(bit))
1355    return 0;    return 0;
1356    
1357  #ifdef SUPPORT_UTF8  #ifdef COMPILE_PCRE8
1358  if (common->utf8 && c > 127)  
1359    #ifdef SUPPORT_UTF
1360    if (common->utf && c > 127)
1361    {    {
1362    n = _pcre_utf8_table4[*cc & 0x3f];    n = GET_EXTRALEN(*cc);
1363    while ((bit & 0x3f) == 0)    while ((bit & 0x3f) == 0)
1364      {      {
1365      n--;      n--;
# Line 1356  if (common->utf8 && c > 127) Line 1367  if (common->utf8 && c > 127)
1367      }      }
1368    return (n << 8) | bit;    return (n << 8) | bit;
1369    }    }
1370  #endif  #endif /* SUPPORT_UTF */
1371  return (0 << 8) | bit;  return (0 << 8) | bit;
1372    
1373    #else /* COMPILE_PCRE8 */
1374    
1375    #ifdef COMPILE_PCRE16
1376    #ifdef SUPPORT_UTF
1377    if (common->utf && c > 65535)
1378      {
1379      if (bit >= (1 << 10))
1380        bit >>= 10;
1381      else
1382        return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8));
1383      }
1384    #endif /* SUPPORT_UTF */
1385    return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8));
1386    #endif /* COMPILE_PCRE16 */
1387    
1388    #endif /* COMPILE_PCRE8 */
1389  }  }
1390    
1391  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 1371  static void read_char(compiler_common *c Line 1399  static void read_char(compiler_common *c
1399  /* Reads the character into TMP1, updates STR_PTR.  /* Reads the character into TMP1, updates STR_PTR.
1400  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1401  DEFINE_COMPILER;  DEFINE_COMPILER;
1402  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1403  struct sljit_jump *jump;  struct sljit_jump *jump;
1404  #endif  #endif
1405    
1406  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1407  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1408  if (common->utf8)  if (common->utf)
1409    {    {
1410    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1411    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1412    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1413    #ifdef COMPILE_PCRE16
1414      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1415    #endif
1416    #endif /* COMPILE_PCRE8 */
1417      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1418    JUMPHERE(jump);    JUMPHERE(jump);
1419    }    }
1420  #endif  #endif
1421  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));
1422  }  }
1423    
1424  static void peek_char(compiler_common *common)  static void peek_char(compiler_common *common)
# Line 1393  static void peek_char(compiler_common *c Line 1426  static void peek_char(compiler_common *c
1426  /* Reads the character into TMP1, keeps STR_PTR.  /* Reads the character into TMP1, keeps STR_PTR.
1427  Does not check STR_END. TMP2 Destroyed. */  Does not check STR_END. TMP2 Destroyed. */
1428  DEFINE_COMPILER;  DEFINE_COMPILER;
1429  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1430  struct sljit_jump *jump;  struct sljit_jump *jump;
1431  #endif  #endif
1432    
1433  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1434  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1435  if (common->utf8)  if (common->utf)
1436    {    {
1437    /* Should not found a value between 128 and 192 here. */  #ifdef COMPILE_PCRE8
1438    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 192);    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
1439    add_jump(compiler, &common->utf8readchar, JUMP(SLJIT_FAST_CALL));  #else
1440    #ifdef COMPILE_PCRE16
1441      jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1442    #endif
1443    #endif /* COMPILE_PCRE8 */
1444      add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL));
1445    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1446    JUMPHERE(jump);    JUMPHERE(jump);
1447    }    }
# Line 1414  static void read_char8_type(compiler_com Line 1452  static void read_char8_type(compiler_com
1452  {  {
1453  /* 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. */
1454  DEFINE_COMPILER;  DEFINE_COMPILER;
1455  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
1456  struct sljit_jump *jump;  struct sljit_jump *jump;
1457  #endif  #endif
1458    
1459  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1460  if (common->utf8)  if (common->utf)
1461    {    {
1462    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1463    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));
1464    #ifdef COMPILE_PCRE8
1465    /* This can be an extra read in some situations, but hopefully    /* This can be an extra read in some situations, but hopefully
1466    it is a clever early read in most cases. */    it is needed in most cases. */
1467    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1468    /* Should not found a value between 128 and 192 here. */    jump = CMP(SLJIT_C_LESS, TMP2, 0, SLJIT_IMM, 0xc0);
1469    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));  
1470    JUMPHERE(jump);    JUMPHERE(jump);
1471    #else
1472    #ifdef COMPILE_PCRE16
1473      OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1474      jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1475      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1476      JUMPHERE(jump);
1477      /* Skip low surrogate if necessary. */
1478      OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xfc00);
1479      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0xd800);
1480      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1481      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1482      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1483    #endif
1484    #endif /* COMPILE_PCRE8 */
1485    return;    return;
1486    }    }
1487  #endif  #endif
1488  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);
1489  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));
1490  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);  #ifdef COMPILE_PCRE16
1491    /* The ctypes array contains only 256 values. */
1492    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1493    jump = CMP(SLJIT_C_GREATER, TMP2, 0, SLJIT_IMM, 255);
1494    #endif
1495    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes);
1496    #ifdef COMPILE_PCRE16
1497    JUMPHERE(jump);
1498    #endif
1499  }  }
1500    
1501  static void skip_char_back(compiler_common *common)  static void skip_char_back(compiler_common *common)
1502  {  {
1503  /* 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. */
1504  DEFINE_COMPILER;  DEFINE_COMPILER;
1505  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1506  struct sljit_label *label;  struct sljit_label *label;
1507    
1508  if (common->utf8)  if (common->utf)
1509    {    {
1510    label = LABEL();    label = LABEL();
1511    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1512    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));
1513    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0);
1514    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);    CMPTO(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 0x80, label);
1515    return;    return;
1516    }    }
1517  #endif  #endif
1518  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1519    if (common->utf)
1520      {
1521      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1));
1522      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1523      /* Skip low surrogate if necessary. */
1524      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1525      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00);
1526      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1527      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1528      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1529      return;
1530      }
1531    #endif
1532    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1533  }  }
1534    
1535  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 1478  else if (nltype == NLTYPE_ANYCRLF) Line 1552  else if (nltype == NLTYPE_ANYCRLF)
1552    }    }
1553  else  else
1554    {    {
1555    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline <= 255);    SLJIT_ASSERT(nltype == NLTYPE_FIXED && common->newline < 256);
1556    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));
1557    }    }
1558  }  }
1559    
1560  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1561  static void do_utf8readchar(compiler_common *common)  
1562    #ifdef COMPILE_PCRE8
1563    static void do_utfreadchar(compiler_common *common)
1564  {  {
1565  /* Fast decoding an utf8 character. TMP1 contains the first byte  /* Fast decoding a UTF-8 character. TMP1 contains the first byte
1566  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. */
1567  DEFINE_COMPILER;  DEFINE_COMPILER;
1568  struct sljit_jump *jump;  struct sljit_jump *jump;
1569    
# Line 1495  sljit_emit_fast_enter(compiler, RETURN_A Line 1571  sljit_emit_fast_enter(compiler, RETURN_A
1571  /* Searching for the first zero. */  /* Searching for the first zero. */
1572  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);
1573  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1574  /* 2 byte sequence */  /* Two byte sequence. */
1575  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1576  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));
1577  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1f);
1578  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6);
1579  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1580  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1581  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1582  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1583  JUMPHERE(jump);  JUMPHERE(jump);
1584    
1585  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);
1586  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1587  /* 3 byte sequence */  /* Three byte sequence. */
1588  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1589  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x0f);
1590  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 12);
1591  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1592  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1593  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1594  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
1595  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));
1596  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1597  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1598  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2));
1599  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1600  JUMPHERE(jump);  JUMPHERE(jump);
1601    
1602  OP2(SLJIT_AND | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x08);  /* Four byte sequence. */
1603  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);  
1604  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x07);
1605  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);  OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 18);
1606  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1607  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);
1608  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1609  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2));
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
 OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 3);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 3);  
 sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  
 JUMPHERE(jump);  
   
 /* 5 byte sequence */  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);  
 OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x03);  
 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 24);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 2);  
 OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  
 OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12);  
 OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  
 OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 3);  
1610  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1611  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1612  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1613  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 4);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(3));
1614  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 4);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3));
1615  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f);
1616  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1617  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 4);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3));
1618  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1619  }  }
1620    
1621  static void do_utf8readtype8(compiler_common *common)  static void do_utfreadtype8(compiler_common *common)
1622  {  {
1623  /* Fast decoding an utf8 character type. TMP2 contains the first byte  /* Fast decoding a UTF-8 character type. TMP2 contains the first byte
1624  of the character (>= 192) and TMP1 is destroyed. Return value in TMP1. */  of the character (>= 0xc0). Return value in TMP1. */
1625  DEFINE_COMPILER;  DEFINE_COMPILER;
1626  struct sljit_jump *jump;  struct sljit_jump *jump;
1627  struct sljit_jump *compare;  struct sljit_jump *compare;
# Line 1579  sljit_emit_fast_enter(compiler, RETURN_A Line 1630  sljit_emit_fast_enter(compiler, RETURN_A
1630    
1631  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);
1632  jump = JUMP(SLJIT_C_NOT_ZERO);  jump = JUMP(SLJIT_C_NOT_ZERO);
1633  /* 2 byte sequence */  /* Two byte sequence. */
1634  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1635  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));
1636  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);  OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x1f);
1637  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6);
1638  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f);
# Line 1596  sljit_emit_fast_return(compiler, RETURN_ Line 1647  sljit_emit_fast_return(compiler, RETURN_
1647  JUMPHERE(jump);  JUMPHERE(jump);
1648    
1649  /* We only have types for characters less than 256. */  /* We only have types for characters less than 256. */
1650  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);  
1651  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1652  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);  OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0);
1653  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1654  }  }
1655    
1656  #endif  #else /* COMPILE_PCRE8 */
1657    
1658    #ifdef COMPILE_PCRE16
1659    static void do_utfreadchar(compiler_common *common)
1660    {
1661    /* Fast decoding a UTF-16 character. TMP1 contains the first 16 bit char
1662    of the character (>= 0xd800). Return char value in TMP1, length - 1 in TMP2. */
1663    DEFINE_COMPILER;
1664    struct sljit_jump *jump;
1665    
1666    sljit_emit_fast_enter(compiler, RETURN_ADDR, 0, 1, 5, 5, common->localsize);
1667    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xdc00);
1668    /* Do nothing, only return. */
1669    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1670    
1671    JUMPHERE(jump);
1672    /* Combine two 16 bit characters. */
1673    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
1674    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1675    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff);
1676    OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10);
1677    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3ff);
1678    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0);
1679    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(1));
1680    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000);
1681    sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1682    }
1683    #endif /* COMPILE_PCRE16 */
1684    
1685    #endif /* COMPILE_PCRE8 */
1686    
1687    #endif /* SUPPORT_UTF */
1688    
1689  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
1690    
# Line 1621  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si Line 1702  SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && si
1702    
1703  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);
1704  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1705  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));
1706  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);  OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK);
1707  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);  OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, UCD_BLOCK_SHIFT);
1708  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0);
1709  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)_pcre_ucd_stage2);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, (sljit_w)PRIV(ucd_stage2));
1710  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);  OP1(SLJIT_MOV_UH, TMP2, 0, SLJIT_MEM2(TMP2, TMP1), 1);
1711  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));
1712  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3);
1713  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
1714  }  }
# Line 1641  struct sljit_label *newlinelabel = NULL; Line 1722  struct sljit_label *newlinelabel = NULL;
1722  struct sljit_jump *start;  struct sljit_jump *start;
1723  struct sljit_jump *end = NULL;  struct sljit_jump *end = NULL;
1724  struct sljit_jump *nl = NULL;  struct sljit_jump *nl = NULL;
1725    #ifdef SUPPORT_UTF
1726    struct sljit_jump *singlechar;
1727    #endif
1728  jump_list *newline = NULL;  jump_list *newline = NULL;
1729  BOOL newlinecheck = FALSE;  BOOL newlinecheck = FALSE;
1730  BOOL readbyte = FALSE;  BOOL readuchar = FALSE;
1731    
1732  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||  if (!(hascrorlf || firstline) && (common->nltype == NLTYPE_ANY ||
1733      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))      common->nltype == NLTYPE_ANYCRLF || common->newline > 255))
# Line 1658  if (firstline) Line 1742  if (firstline)
1742    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
1743      {      {
1744      mainloop = LABEL();      mainloop = LABEL();
1745      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));
1746      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);      end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1747      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1748      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
1749      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);
1750      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);
1751      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));
1752      }      }
1753    else    else
1754      {      {
# Line 1688  start = JUMP(SLJIT_JUMP); Line 1772  start = JUMP(SLJIT_JUMP);
1772  if (newlinecheck)  if (newlinecheck)
1773    {    {
1774    newlinelabel = LABEL();    newlinelabel = LABEL();
1775    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));
1776    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    end = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1777    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1778    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);
1779    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1780    #ifdef COMPILE_PCRE16
1781      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1782    #endif
1783    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1784    nl = JUMP(SLJIT_JUMP);    nl = JUMP(SLJIT_JUMP);
1785    }    }
# Line 1700  if (newlinecheck) Line 1787  if (newlinecheck)
1787  mainloop = LABEL();  mainloop = LABEL();
1788    
1789  /* 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. */
1790  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
1791  if (common->utf8) readbyte = TRUE;  if (common->utf) readuchar = TRUE;
1792  #endif  #endif
1793  if (newlinecheck) readbyte = TRUE;  if (newlinecheck) readuchar = TRUE;
1794    
1795  if (readbyte)  if (readuchar)
1796    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1797    
1798  if (newlinecheck)  if (newlinecheck)
1799    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);
1800    
1801  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1802  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1803    if (common->utf)
1804    {    {
1805    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);
1806      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1807    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1808      JUMPHERE(singlechar);
1809      }
1810    #endif
1811    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1812    if (common->utf)
1813      {
1814      singlechar = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
1815      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1816      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1817      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1818      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1819      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1820      JUMPHERE(singlechar);
1821    }    }
 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);  
1822  #endif  #endif
1823  JUMPHERE(start);  JUMPHERE(start);
1824    
# Line 1733  if (newlinecheck) Line 1831  if (newlinecheck)
1831  return mainloop;  return mainloop;
1832  }  }
1833    
1834  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)
1835  {  {
1836  DEFINE_COMPILER;  DEFINE_COMPILER;
1837  struct sljit_label *start;  struct sljit_label *start;
1838  struct sljit_jump *leave;  struct sljit_jump *leave;
1839  struct sljit_jump *found;  struct sljit_jump *found;
1840  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
1841    
1842  if (firstline)  if (firstline)
1843    {    {
# Line 1749  if (firstline) Line 1847  if (firstline)
1847    
1848  start = LABEL();  start = LABEL();
1849  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1850  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1851    
1852  if ((firstbyte & REQ_CASELESS) == 0)  oc = first_char;
1853    found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, firstbyte & 0xff);  if (caseless)
1854      {
1855      oc = TABLE_GET(first_char, common->fcc, first_char);
1856    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
1857      if (first_char > 127 && common->utf)
1858        oc = UCD_OTHERCASE(first_char);
1859    #endif
1860      }
1861    if (first_char == oc)
1862      found = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, first_char);
1863  else  else
1864    {    {
1865    firstbyte &= 0xff;    bit = first_char ^ oc;
   oc = common->fcc[firstbyte];  
   bit = firstbyte ^ oc;  
1866    if (ispowerof2(bit))    if (ispowerof2(bit))
1867      {      {
1868      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, bit);
1869      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, firstbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, first_char | bit);
1870      }      }
1871    else    else
1872      {      {
1873      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);
1874      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);      COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_EQUAL);
1875      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);
1876      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 1773  else Line 1878  else
1878      }      }
1879    }    }
1880    
1881  #ifdef SUPPORT_UTF8  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
1882  if (common->utf8)  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
1883    if (common->utf)
1884    {    {
1885    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);
1886      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
1887      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1888      }
1889    #endif
1890    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
1891    if (common->utf)
1892      {
1893      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
1894      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
1895      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
1896      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1897      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1898    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1899    }    }
 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);  
1900  #endif  #endif
1901  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
1902  JUMPHERE(found);  JUMPHERE(found);
# Line 1817  if (common->nltype == NLTYPE_FIXED && co Line 1931  if (common->nltype == NLTYPE_FIXED && co
1931    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));
1932    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);    firstchar = CMP(SLJIT_C_LESS_EQUAL, STR_PTR, 0, TMP2, 0);
1933    
1934    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2);    OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(2));
1935    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);
1936    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);    COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_GREATER_EQUAL);
1937    #ifdef COMPILE_PCRE16
1938      OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
1939    #endif
1940    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);    OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
1941    
1942    loop = LABEL();    loop = LABEL();
1943    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));
1944    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1945    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
1946    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);    OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
1947    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);
1948    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);
1949    
# Line 1857  if (common->nltype == NLTYPE_ANY || comm Line 1974  if (common->nltype == NLTYPE_ANY || comm
1974    leave = JUMP(SLJIT_JUMP);    leave = JUMP(SLJIT_JUMP);
1975    JUMPHERE(foundcr);    JUMPHERE(foundcr);
1976    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);    notfoundnl = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
1977    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
1978    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);
1979    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
1980    #ifdef COMPILE_PCRE16
1981      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
1982    #endif
1983    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
1984    JUMPHERE(notfoundnl);    JUMPHERE(notfoundnl);
1985    JUMPHERE(leave);    JUMPHERE(leave);
# Line 1877  DEFINE_COMPILER; Line 1997  DEFINE_COMPILER;
1997  struct sljit_label *start;  struct sljit_label *start;
1998  struct sljit_jump *leave;  struct sljit_jump *leave;
1999  struct sljit_jump *found;  struct sljit_jump *found;
2000    #ifndef COMPILE_PCRE8
2001    struct sljit_jump *jump;
2002    #endif
2003    
2004  if (firstline)  if (firstline)
2005    {    {
# Line 1886  if (firstline) Line 2009  if (firstline)
2009    
2010  start = LABEL();  start = LABEL();
2011  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);  leave = CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0);
2012  OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);  OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
2013  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2014  if (common->utf8)  if (common->utf)
2015    OP1(SLJIT_MOV_UB, TMP3, 0, SLJIT_MEM1(TMP1), (sljit_w)_pcre_utf8_char_sizes);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2016    #endif
2017    #ifndef COMPILE_PCRE8
2018    jump = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 255);
2019    OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 255);
2020    JUMPHERE(jump);
2021  #endif  #endif
2022  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);  OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2023  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);  OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 1898  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM Line 2026  OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TM
2026  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);
2027  found = JUMP(SLJIT_C_NOT_ZERO);  found = JUMP(SLJIT_C_NOT_ZERO);
2028    
2029  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2030  if (common->utf8)  if (common->utf)
2031    OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2032  else  #endif
2033    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));
2034  #else  #if defined SUPPORT_UTF && defined COMPILE_PCRE8
2035  OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, 1);  if (common->utf)
2036      {
2037      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0, start);
2038      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
2039      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2040      }
2041    #endif
2042    #if defined SUPPORT_UTF && defined COMPILE_PCRE16
2043    if (common->utf)
2044      {
2045      CMPTO(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800, start);
2046      OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
2047      OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
2048      COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
2049      OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2050      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
2051      }
2052  #endif  #endif
2053  JUMPTO(SLJIT_JUMP, start);  JUMPTO(SLJIT_JUMP, start);
2054  JUMPHERE(found);  JUMPHERE(found);
# Line 1914  if (firstline) Line 2058  if (firstline)
2058    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);    OP1(SLJIT_MOV, STR_END, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0);
2059  }  }
2060    
2061  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)
2062  {  {
2063  DEFINE_COMPILER;  DEFINE_COMPILER;
2064  struct sljit_label *loop;  struct sljit_label *loop;
# Line 1923  struct sljit_jump *alreadyfound; Line 2067  struct sljit_jump *alreadyfound;
2067  struct sljit_jump *found;  struct sljit_jump *found;
2068  struct sljit_jump *foundoc = NULL;  struct sljit_jump *foundoc = NULL;
2069  struct sljit_jump *notfound;  struct sljit_jump *notfound;
2070  pcre_uint16 oc, bit;  pcre_uchar oc, bit;
2071    
2072  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);
2073  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);
2074  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);  toolong = CMP(SLJIT_C_LESS, TMP1, 0, STR_END, 0);
2075  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);  alreadyfound = CMP(SLJIT_C_LESS, STR_PTR, 0, TMP2, 0);
2076    
2077  if (has_firstbyte)  if (has_firstchar)
2078    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, 1);    OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
2079  else  else
2080    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);    OP1(SLJIT_MOV, TMP1, 0, STR_PTR, 0);
2081    
2082  loop = LABEL();  loop = LABEL();
2083  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);  notfound = CMP(SLJIT_C_GREATER_EQUAL, TMP1, 0, STR_END, 0);
2084    
2085  OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2086  if ((reqbyte & REQ_CASELESS) == 0)  oc = req_char;
2087    found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte & 0xff);  if (caseless)
2088      {
2089      oc = TABLE_GET(req_char, common->fcc, req_char);
2090    #if defined SUPPORT_UCP && !(defined COMPILE_PCRE8)
2091      if (req_char > 127 && common->utf)
2092        oc = UCD_OTHERCASE(req_char);
2093    #endif
2094      }
2095    if (req_char == oc)
2096      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2097  else  else
2098    {    {
2099    reqbyte &= 0xff;    bit = req_char ^ oc;
   oc = common->fcc[reqbyte];  
   bit = reqbyte ^ oc;  
2100    if (ispowerof2(bit))    if (ispowerof2(bit))
2101      {      {
2102      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);      OP2(SLJIT_OR, TMP2, 0, TMP2, 0, SLJIT_IMM, bit);
2103      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte | bit);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char | bit);
2104      }      }
2105    else    else
2106      {      {
2107      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, reqbyte);      found = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, req_char);
2108      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);      foundoc = CMP(SLJIT_C_EQUAL, TMP2, 0, SLJIT_IMM, oc);
2109      }      }
2110    }    }
2111  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2112  JUMPTO(SLJIT_JUMP, loop);  JUMPTO(SLJIT_JUMP, loop);
2113    
2114  JUMPHERE(found);  JUMPHERE(found);
2115  if (foundoc)  if (foundoc)
2116    JUMPHERE(foundoc);    JUMPHERE(foundoc);
2117  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);
2118  JUMPHERE(alreadyfound);  JUMPHERE(alreadyfound);
2119  JUMPHERE(toolong);  JUMPHERE(toolong);
2120  return notfound;  return notfound;
# Line 1972  return notfound; Line 2123  return notfound;
2123  static void do_revertframes(compiler_common *common)  static void do_revertframes(compiler_common *common)
2124  {  {
2125  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *earlyexit;  
2126  struct sljit_jump *jump;  struct sljit_jump *jump;
2127  struct sljit_label *mainloop;  struct sljit_label *mainloop;
2128    
2129  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);
2130  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD);  OP1(SLJIT_MOV, TMP1, 0, STACK_TOP, 0);
2131    
2132  /* Drop frames until we reach STACK_TOP. */  /* Drop frames until we reach STACK_TOP. */
 earlyexit = CMP(SLJIT_C_LESS, TMP1, 0, STACK_TOP, 0);  
2133  mainloop = LABEL();  mainloop = LABEL();
2134  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), 0);
2135  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 1993  JUMPTO(SLJIT_JUMP, mainloop); Line 2142  JUMPTO(SLJIT_JUMP, mainloop);
2142  JUMPHERE(jump);  JUMPHERE(jump);
2143  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_end);
2144  /* 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);  
2145  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2146    
2147  JUMPHERE(jump);  JUMPHERE(jump);
 jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setmaxindex);  
 /* Set max index. */  
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  
 OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 2 * sizeof(sljit_w));  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP2, 0);  
 JUMPTO(SLJIT_JUMP, mainloop);  
   
 JUMPHERE(jump);  
2148  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);  jump = CMP(SLJIT_C_NOT_EQUAL, TMP2, 0, SLJIT_IMM, frame_setstrbegin);
2149  /* Set max index. */  /* Set string begin. */
2150  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));  OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), sizeof(sljit_w));
2151  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));
2152  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 2025  static void check_wordboundary(compiler_ Line 2162  static void check_wordboundary(compiler_
2162  {  {
2163  DEFINE_COMPILER;  DEFINE_COMPILER;
2164  struct sljit_jump *beginend;  struct sljit_jump *beginend;
2165  #ifdef SUPPORT_UTF8  #if !(defined COMPILE_PCRE8) || defined SUPPORT_UTF
2166  struct sljit_jump *jump;  struct sljit_jump *jump;
2167  #endif  #endif
2168    
2169  SLJIT_ASSERT(ctype_word == 0x10);  SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16);
2170    
2171  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);
2172  /* Get type of the previous char, and put it to LOCALS1. */  /* Get type of the previous char, and put it to LOCALS1. */
# Line 2042  read_char(common); Line 2179  read_char(common);
2179    
2180  /* Testing char type. */  /* Testing char type. */
2181  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2182  if (common->useucp)  if (common->use_ucp)
2183    {    {
2184    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2185    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2059  if (common->useucp) Line 2196  if (common->useucp)
2196  else  else
2197  #endif  #endif
2198    {    {
2199  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2200      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2201    #elif defined SUPPORT_UTF
2202    /* Here LOCALS1 has already been zeroed. */    /* Here LOCALS1 has already been zeroed. */
2203    jump = NULL;    jump = NULL;
2204    if (common->utf8)    if (common->utf)
2205      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2206  #endif  #endif /* COMPILE_PCRE8 */
2207    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes);
2208    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */);
2209    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
2210    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, TMP1, 0);
2211  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2212      JUMPHERE(jump);
2213    #elif defined SUPPORT_UTF
2214    if (jump != NULL)    if (jump != NULL)
2215      JUMPHERE(jump);      JUMPHERE(jump);
2216  #endif  #endif /* COMPILE_PCRE8 */
2217    }    }
2218  JUMPHERE(beginend);  JUMPHERE(beginend);
2219    
# Line 2082  peek_char(common); Line 2223  peek_char(common);
2223    
2224  /* Testing char type. This is a code duplication. */  /* Testing char type. This is a code duplication. */
2225  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2226  if (common->useucp)  if (common->use_ucp)
2227    {    {
2228    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1);
2229    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);    jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE);
# Line 2098  if (common->useucp) Line 2239  if (common->useucp)
2239  else  else
2240  #endif  #endif
2241    {    {
2242  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2243      /* TMP2 may be destroyed by peek_char. */
2244      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2245      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2246    #elif defined SUPPORT_UTF
2247    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);    OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0);
2248    jump = NULL;    jump = NULL;
2249    if (common->utf8)    if (common->utf)
2250      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2251  #endif  #endif
2252    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);    OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(TMP1), common->ctypes);
2253    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);    OP2(SLJIT_LSHR, TMP2, 0, TMP2, 0, SLJIT_IMM, 4 /* ctype_word */);
2254    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);    OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 1);
2255  #ifdef SUPPORT_UTF8  #ifndef COMPILE_PCRE8
2256      JUMPHERE(jump);
2257    #elif defined SUPPORT_UTF
2258    if (jump != NULL)    if (jump != NULL)
2259      JUMPHERE(jump);      JUMPHERE(jump);
2260  #endif  #endif /* COMPILE_PCRE8 */
2261    }    }
2262  JUMPHERE(beginend);  JUMPHERE(beginend);
2263    
# Line 2129  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2276  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2276  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);
2277  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2278  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);
2279  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2280  if (common->utf8)  #ifdef COMPILE_PCRE8
2281    if (common->utf)
2282    {    {
2283    #endif
2284    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2285    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2286    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);
2287    #ifdef COMPILE_PCRE8
2288    }    }
2289  #endif  #endif
2290    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2291  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2292  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
2293  }  }
# Line 2153  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E Line 2304  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_E
2304  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);
2305  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2306  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);
2307  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2308  if (common->utf8)  #ifdef COMPILE_PCRE8
2309    if (common->utf)
2310    {    {
2311    #endif
2312    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2313    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);
2314    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
# Line 2169  if (common->utf8) Line 2322  if (common->utf8)
2322    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);
2323    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR, TMP2, 0, SLJIT_C_EQUAL);
2324    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);
2325    #ifdef COMPILE_PCRE8
2326    }    }
2327  #endif  #endif
2328    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2329  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2330    
2331  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2187  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I Line 2342  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_I
2342  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);
2343  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);  COND_VALUE(SLJIT_MOV, TMP2, 0, SLJIT_C_LESS_EQUAL);
2344  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);
2345  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
2346  if (common->utf8)  #ifdef COMPILE_PCRE8
2347    if (common->utf)
2348    {    {
2349    #endif
2350    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);    COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2351    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);    OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x1);
2352    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);
2353    #ifdef COMPILE_PCRE8
2354    }    }
2355  #endif  #endif
2356    #endif /* SUPPORT_UTF || COMPILE_PCRE16 */
2357  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);  COND_VALUE(SLJIT_OR | SLJIT_SET_E, TMP2, 0, SLJIT_C_EQUAL);
2358    
2359  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2213  sljit_emit_fast_enter(compiler, RETURN_A Line 2372  sljit_emit_fast_enter(compiler, RETURN_A
2372  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);  OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0);
2373  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);  OP1(SLJIT_MOV, TMP3, 0, CHAR1, 0);
2374  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR2, 0);
2375  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2376  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));
2377    
2378  label = LABEL();  label = LABEL();
2379  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2380  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2381  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2382  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));
2383  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2384    
2385  JUMPHERE(jump);  JUMPHERE(jump);
2386  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));
2387  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);  OP1(SLJIT_MOV, CHAR1, 0, TMP3, 0);
2388  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2389  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);  sljit_emit_fast_return(compiler, RETURN_ADDR, 0);
# Line 2245  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0); Line 2404  OP1(SLJIT_MOV, TMP3, 0, LCC_TABLE, 0);
2404  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, CHAR1, 0);
2405  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, CHAR2, 0);
2406  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);  OP1(SLJIT_MOV, LCC_TABLE, 0, SLJIT_IMM, common->lcc);
2407  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);  OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, IN_UCHARS(1));
2408  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));
2409    
2410  label = LABEL();  label = LABEL();
2411  OP1(SLJIT_MOVU_UB, CHAR1, 0, SLJIT_MEM1(TMP1), 1);  OP1(MOVU_UCHAR, CHAR1, 0, SLJIT_MEM1(TMP1), IN_UCHARS(1));
2412  OP1(SLJIT_MOVU_UB, CHAR2, 0, SLJIT_MEM1(STR_PTR), 1);  OP1(MOVU_UCHAR, CHAR2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
2413    #ifndef COMPILE_PCRE8
2414    jump = CMP(SLJIT_C_GREATER, CHAR1, 0, SLJIT_IMM, 255);
2415    #endif
2416  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);  OP1(SLJIT_MOV_UB, CHAR1, 0, SLJIT_MEM2(LCC_TABLE, CHAR1), 0);
2417    #ifndef COMPILE_PCRE8
2418    JUMPHERE(jump);
2419    jump = CMP(SLJIT_C_GREATER, CHAR2, 0, SLJIT_IMM, 255);
2420    #endif
2421  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);  OP1(SLJIT_MOV_UB, CHAR2, 0, SLJIT_MEM2(LCC_TABLE, CHAR2), 0);
2422    #ifndef COMPILE_PCRE8
2423    JUMPHERE(jump);
2424    #endif
2425  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);  jump = CMP(SLJIT_C_NOT_EQUAL, CHAR1, 0, CHAR2, 0);
2426  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));
2427  JUMPTO(SLJIT_C_NOT_ZERO, label);  JUMPTO(SLJIT_C_NOT_ZERO, label);
2428    
2429  JUMPHERE(jump);  JUMPHERE(jump);
2430  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));
2431  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);  OP1(SLJIT_MOV, LCC_TABLE, 0, TMP3, 0);
2432  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);  OP1(SLJIT_MOV, CHAR1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
2433  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);  OP1(SLJIT_MOV, CHAR2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1);
# Line 2269  sljit_emit_fast_return(compiler, RETURN_ Line 2438  sljit_emit_fast_return(compiler, RETURN_
2438  #undef CHAR1  #undef CHAR1
2439  #undef CHAR2  #undef CHAR2
2440    
2441  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
 #ifdef SUPPORT_UCP  
2442    
2443  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)
2444  {  {
2445  /* This function would be ineffective to do in JIT level. */  /* This function would be ineffective to do in JIT level. */
2446  int c1, c2;  int c1, c2;
2447  uschar *src2 = args->ptr;  const pcre_uchar *src2 = args->ptr;
2448  uschar *end2 = (uschar*)args->end;  const pcre_uchar *end2 = args->end;
2449    
2450  while (src1 < end1)  while (src1 < end1)
2451    {    {
# Line 2290  while (src1 < end1) Line 2458  while (src1 < end1)
2458  return src2;  return src2;
2459  }  }
2460    
2461  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
2462    
2463  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,
2464      compare_context* context, jump_list **fallbacks)      compare_context* context, jump_list **fallbacks)
2465  {  {
2466  DEFINE_COMPILER;  DEFINE_COMPILER;
2467  unsigned int othercasebit = 0;  unsigned int othercasebit = 0;
2468  uschar *othercasebyte = NULL;  pcre_uchar *othercasechar = NULL;
2469  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2470  int utf8length;  int utflength;
2471  #endif  #endif
2472    
2473  if (caseless && char_has_othercase(common, cc))  if (caseless && char_has_othercase(common, cc))
# Line 2308  if (caseless && char_has_othercase(commo Line 2475  if (caseless && char_has_othercase(commo
2475    othercasebit = char_get_othercase_bit(common, cc);    othercasebit = char_get_othercase_bit(common, cc);
2476    SLJIT_ASSERT(othercasebit);    SLJIT_ASSERT(othercasebit);
2477    /* Extracting bit difference info. */    /* Extracting bit difference info. */
2478    othercasebyte = cc + (othercasebit >> 8);  #ifdef COMPILE_PCRE8
2479      othercasechar = cc + (othercasebit >> 8);
2480    othercasebit &= 0xff;    othercasebit &= 0xff;
2481    #else
2482    #ifdef COMPILE_PCRE16
2483      othercasechar = cc + (othercasebit >> 9);
2484      if ((othercasebit & 0x100) != 0)
2485        othercasebit = (othercasebit & 0xff) << 8;
2486      else
2487        othercasebit &= 0xff;
2488    #endif
2489    #endif
2490    }    }
2491    
2492  if (context->sourcereg == -1)  if (context->sourcereg == -1)
2493    {    {
2494    #ifdef COMPILE_PCRE8
2495  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2496    if (context->length >= 4)    if (context->length >= 4)
2497      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2498    else if (context->length >= 2)    else if (context->length >= 2)
2499      OP1(SLJIT_MOV_SH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2500    else    else
2501  #endif  #endif
2502      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2503    #else
2504    #ifdef COMPILE_PCRE16
2505    #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2506      if (context->length >= 4)
2507        OP1(SLJIT_MOV_SI, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2508      else
2509    #endif
2510        OP1(SLJIT_MOV_UH, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length);
2511    #endif
2512    #endif /* COMPILE_PCRE8 */
2513    context->sourcereg = TMP2;    context->sourcereg = TMP2;
2514    }    }
2515    
2516  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2517  utf8length = 1;  utflength = 1;
2518  if (common->utf8 && *cc >= 0xc0)  if (common->utf && HAS_EXTRALEN(*cc))
2519    utf8length += _pcre_utf8_table4[*cc & 0x3f];    utflength += GET_EXTRALEN(*cc);
2520    
2521  do  do
2522    {    {
2523  #endif  #endif
2524    
2525    context->length--;    context->length -= IN_UCHARS(1);
2526  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
2527    
2528    /* Unaligned read is supported. */    /* Unaligned read is supported. */
2529    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2530      {      {
2531      context->c.asbytes[context->byteptr] = *cc | othercasebit;      context->c.asuchars[context->ucharptr] = *cc | othercasebit;
2532      context->oc.asbytes[context->byteptr] = othercasebit;      context->oc.asuchars[context->ucharptr] = othercasebit;
2533      }      }
2534    else    else
2535      {      {
2536      context->c.asbytes[context->byteptr] = *cc;      context->c.asuchars[context->ucharptr] = *cc;
2537      context->oc.asbytes[context->byteptr] = 0;      context->oc.asuchars[context->ucharptr] = 0;
2538      }      }
2539    context->byteptr++;    context->ucharptr++;
2540    
2541    if (context->byteptr >= 4 || context->length == 0 || (context->byteptr == 2 && context->length == 1))  #ifdef COMPILE_PCRE8
2542      if (context->ucharptr >= 4 || context->length == 0 || (context->ucharptr == 2 && context->length == 1))
2543    #else
2544      if (context->ucharptr >= 2 || context->length == 0)
2545    #endif
2546      {      {
2547      if (context->length >= 4)      if (context->length >= 4)
2548        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);
2549    #ifdef COMPILE_PCRE8
2550      else if (context->length >= 2)      else if (context->length >= 2)
2551        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);
2552      else if (context->length >= 1)      else if (context->length >= 1)
2553        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);
2554    #else
2555        else if (context->length >= 2)
2556          OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2557    #endif
2558      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;      context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2559    
2560      switch(context->byteptr)      switch(context->ucharptr)
2561        {        {
2562        case 4:        case 4 / sizeof(pcre_uchar):
2563        if (context->oc.asint != 0)        if (context->oc.asint != 0)
2564          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);
2565        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));
2566        break;        break;
2567    
2568        case 2:        case 2 / sizeof(pcre_uchar):
2569        if (context->oc.asshort != 0)        if (context->oc.asushort != 0)
2570          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);
2571        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));
2572        break;        break;
2573    
2574    #ifdef COMPILE_PCRE8
2575        case 1:        case 1:
2576        if (context->oc.asbyte != 0)        if (context->oc.asbyte != 0)
2577          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);
2578        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));
2579        break;        break;
2580    #endif
2581    
2582        default:        default:
2583        SLJIT_ASSERT_STOP();        SLJIT_ASSERT_STOP();
2584        break;        break;
2585        }        }
2586      context->byteptr = 0;      context->ucharptr = 0;
2587      }      }
2588    
2589  #else  #else
2590    
2591    /* Unaligned read is unsupported. */    /* Unaligned read is unsupported. */
2592    #ifdef COMPILE_PCRE8
2593    if (context->length > 0)    if (context->length > 0)
2594      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);
2595    #else
2596      if (context->length > 0)
2597        OP1(SLJIT_MOV_UH, context->sourcereg, 0, SLJIT_MEM1(STR_PTR), -context->length);
2598    #endif
2599    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;    context->sourcereg = context->sourcereg == TMP1 ? TMP2 : TMP1;
2600    
2601    if (othercasebit != 0 && othercasebyte == cc)    if (othercasebit != 0 && othercasechar == cc)
2602      {      {
2603      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);      OP2(SLJIT_OR, context->sourcereg, 0, context->sourcereg, 0, SLJIT_IMM, othercasebit);
2604      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 2405  do Line 2609  do
2609  #endif  #endif
2610    
2611    cc++;    cc++;
2612  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2613    utf8length--;    utflength--;
2614    }    }
2615  while (utf8length > 0);  while (utflength > 0);
2616  #endif  #endif
2617    
2618  return cc;  return cc;
2619  }  }
2620    
2621  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
2622    
2623  #define SET_TYPE_OFFSET(value) \  #define SET_TYPE_OFFSET(value) \
2624    if ((value) != typeoffset) \    if ((value) != typeoffset) \
# Line 2436  return cc; Line 2640  return cc;
2640      } \      } \
2641    charoffset = (value);    charoffset = (value);
2642    
2643  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)
2644  {  {
2645  DEFINE_COMPILER;  DEFINE_COMPILER;
2646  jump_list *found = NULL;  jump_list *found = NULL;
# Line 2444  jump_list **list = (*cc & XCL_NOT) == 0 Line 2648  jump_list **list = (*cc & XCL_NOT) == 0
2648  unsigned int c;  unsigned int c;
2649  int compares;  int compares;
2650  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
2651  uschar *ccbegin;  pcre_uchar *ccbegin;
2652  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2653  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;  BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE;
2654  BOOL charsaved = FALSE;  BOOL charsaved = FALSE;
2655  int typereg = TMP1, scriptreg = TMP1, typeoffset;  int typereg = TMP1, scriptreg = TMP1;
2656    unsigned int typeoffset;
2657  #endif  #endif
2658  int charoffset, invertcmp, numberofcmps;  int invertcmp, numberofcmps;
2659    unsigned int charoffset;
2660    
2661  /* 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. */
2662  check_input_end(common, fallbacks);  check_input_end(common, fallbacks);
2663  read_char(common);  read_char(common);
2664    
2665  if ((*cc++ & XCL_MAP) != 0)  if ((*cc++ & XCL_MAP) != 0)
2666    {    {
2667    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);    OP1(SLJIT_MOV, TMP3, 0, TMP1, 0);
2668    if (common->utf8)  #ifndef COMPILE_PCRE8
2669      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2670    #elif defined SUPPORT_UTF
2671      if (common->utf)
2672      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
2673    #endif
2674    
2675    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
2676    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
# Line 2469  if ((*cc++ & XCL_MAP) != 0) Line 2679  if ((*cc++ & XCL_MAP) != 0)
2679    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);
2680    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));    add_jump(compiler, list, JUMP(SLJIT_C_NOT_ZERO));
2681    
2682    if (common->utf8)  #ifndef COMPILE_PCRE8
2683      JUMPHERE(jump);
2684    #elif defined SUPPORT_UTF
2685      if (common->utf)
2686      JUMPHERE(jump);      JUMPHERE(jump);
2687    #endif
2688    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);    OP1(SLJIT_MOV, TMP1, 0, TMP3, 0);
2689  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2690    charsaved = TRUE;    charsaved = TRUE;
2691  #endif  #endif
2692    cc += 32;    cc += 32 / sizeof(pcre_uchar);
2693    }    }
2694    
2695  /* Scanning the necessary info. */  /* Scanning the necessary info. */
# Line 2487  while (*cc != XCL_END) Line 2701  while (*cc != XCL_END)
2701    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2702      {      {
2703      cc += 2;      cc += 2;
2704  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2705      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]);
2706  #endif  #endif
2707  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2708      needschar = TRUE;      needschar = TRUE;
# Line 2497  while (*cc != XCL_END) Line 2711  while (*cc != XCL_END)
2711    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2712      {      {
2713      cc += 2;      cc += 2;
2714  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2715      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]);
2716  #endif  #endif
2717      cc++;      cc++;
2718  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2719      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]);
2720  #endif  #endif
2721  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2722      needschar = TRUE;      needschar = TRUE;
# Line 2572  if (needstype || needsscript) Line 2786  if (needstype || needsscript)
2786      {      {
2787      if (scriptreg == TMP1)      if (scriptreg == TMP1)
2788        {        {
2789        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));
2790        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM2(scriptreg, TMP2), 3);
2791        }        }
2792      else      else
2793        {        {
2794        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);        OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 3);
2795        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));
2796        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);        OP1(SLJIT_MOV_UB, scriptreg, 0, SLJIT_MEM1(TMP2), 0);
2797        }        }
2798      }      }
# Line 2602  while (*cc != XCL_END) Line 2816  while (*cc != XCL_END)
2816    if (*cc == XCL_SINGLE)    if (*cc == XCL_SINGLE)
2817      {      {
2818      cc ++;      cc ++;
2819  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2820      if (common->utf8)      if (common->utf)
2821        {        {
2822        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2823        }        }
# Line 2633  while (*cc != XCL_END) Line 2847  while (*cc != XCL_END)
2847    else if (*cc == XCL_RANGE)    else if (*cc == XCL_RANGE)
2848      {      {
2849      cc ++;      cc ++;
2850  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2851      if (common->utf8)      if (common->utf)
2852        {        {
2853        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2854        }        }
# Line 2642  while (*cc != XCL_END) Line 2856  while (*cc != XCL_END)
2856  #endif  #endif
2857        c = *cc++;        c = *cc++;
2858      SET_CHAR_OFFSET(c);      SET_CHAR_OFFSET(c);
2859  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2860      if (common->utf8)      if (common->utf)
2861        {        {
2862        GETCHARINC(c, cc);        GETCHARINC(c, cc);
2863        }        }
# Line 2699  while (*cc != XCL_END) Line 2913  while (*cc != XCL_END)
2913        break;        break;
2914    
2915        case PT_GC:        case PT_GC:
2916        c = _pcre_ucp_typerange[(int)cc[1] * 2];        c = PRIV(ucp_typerange)[(int)cc[1] * 2];
2917        SET_TYPE_OFFSET(c);        SET_TYPE_OFFSET(c);
2918        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);
2919        break;        break;
2920    
2921        case PT_PC:        case PT_PC:
# Line 2763  if (found != NULL) Line 2977  if (found != NULL)
2977    
2978  #endif  #endif
2979    
2980  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)
2981  {  {
2982  DEFINE_COMPILER;  DEFINE_COMPILER;
2983  int length;  int length;
2984  unsigned int c, oc, bit;  unsigned int c, oc, bit;
2985  compare_context context;  compare_context context;
2986  struct sljit_jump *jump[4];  struct sljit_jump *jump[4];
2987  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
2988  struct sljit_label *label;  struct sljit_label *label;
2989  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
2990  uschar propdata[5];  pcre_uchar propdata[5];
2991  #endif  #endif
2992  #endif  #endif
2993    
# Line 2828  switch(type) Line 3042  switch(type)
3042      {      {
3043      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);
3044      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);
3045      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3046      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));
3047      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3048      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
# Line 2839  switch(type) Line 3053  switch(type)
3053    
3054    case OP_ALLANY:    case OP_ALLANY:
3055    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3056  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3057    if (common->utf8)    if (common->utf)
3058      {      {
3059      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3060      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));
3061    #ifdef COMPILE_PCRE8
3062        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3063        OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3064        OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3065    #else /* COMPILE_PCRE8 */
3066    #ifdef COMPILE_PCRE16
3067        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xd800);
3068        OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00);
3069        OP2(SLJIT_SUB | SLJIT_SET_E, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800);
3070        COND_VALUE(SLJIT_MOV, TMP1, 0, SLJIT_C_EQUAL);
3071        OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1);
3072      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3073    #endif /* COMPILE_PCRE16 */
3074    #endif /* COMPILE_PCRE8 */
3075        JUMPHERE(jump[0]);
3076      return cc;      return cc;
3077      }      }
3078  #endif  #endif
3079    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));
3080      return cc;
3081    
3082      case OP_ANYBYTE:
3083      check_input_end(common, fallbacks);
3084      OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3085    return cc;    return cc;
3086    
3087  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3088  #ifdef SUPPORT_UCP  #ifdef SUPPORT_UCP
3089    case OP_NOTPROP:    case OP_NOTPROP:
3090    case OP_PROP:    case OP_PROP:
# Line 2870  switch(type) Line 3103  switch(type)
3103    read_char(common);    read_char(common);
3104    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);
3105    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);
3106    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);    OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);
3107    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);
3108    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));
3109    jump[3] = JUMP(SLJIT_JUMP);    jump[3] = JUMP(SLJIT_JUMP);
3110    JUMPHERE(jump[0]);    JUMPHERE(jump[0]);
3111    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);    check_newlinechar(common, common->bsr_nltype, fallbacks, FALSE);
# Line 2922  switch(type) Line 3155  switch(type)
3155    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);
3156    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3157      {      {
3158      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3159      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3160      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));
3161      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3162      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));
3163      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));
3164      }      }
3165    else if (common->nltype == NLTYPE_FIXED)    else if (common->nltype == NLTYPE_FIXED)
3166      {      {
3167      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3168      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3169      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));
3170      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));
3171      }      }
3172    else    else
3173      {      {
3174      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3175      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);
3176      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3177      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);
3178      jump[2] = JUMP(SLJIT_C_GREATER);      jump[2] = JUMP(SLJIT_C_GREATER);
3179      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));      add_jump(compiler, fallbacks, JUMP(SLJIT_C_LESS));
3180      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 1);      /* Equal. */
3181        OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3182      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);      jump[3] = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_NL);
3183      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));      add_jump(compiler, fallbacks, JUMP(SLJIT_JUMP));
3184    
3185      JUMPHERE(jump[1]);      JUMPHERE(jump[1]);
3186      if (common->nltype == NLTYPE_ANYCRLF)      if (common->nltype == NLTYPE_ANYCRLF)
3187        {        {
3188        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 1);        OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1));
3189        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));
3190        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));
3191        }        }
# Line 2991  switch(type) Line 3225  switch(type)
3225    jump[0] = JUMP(SLJIT_JUMP);    jump[0] = JUMP(SLJIT_JUMP);
3226    JUMPHERE(jump[1]);    JUMPHERE(jump[1]);
3227    
3228    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));  
   
3229    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3230      {      {
3231      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3232      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));      add_jump(compiler, fallbacks, CMP(SLJIT_C_LESS, TMP2, 0, TMP1, 0));
3233      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), -2);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2));
3234      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), -1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1));
3235      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));
3236      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));
3237      }      }
# Line 3033  switch(type) Line 3265  switch(type)
3265    
3266    if (common->nltype == NLTYPE_FIXED && common->newline > 255)    if (common->nltype == NLTYPE_FIXED && common->newline > 255)
3267      {      {
3268      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, 2);      OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2));
3269      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));
3270      OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(STR_PTR), 0);      OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0));
3271      OP1(SLJIT_MOV_UB, TMP2, 0, SLJIT_MEM1(STR_PTR), 1);      OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1));
3272      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));
3273      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));
3274      }      }
# Line 3051  switch(type) Line 3283  switch(type)
3283    case OP_CHAR:    case OP_CHAR:
3284    case OP_CHARI:    case OP_CHARI:
3285    length = 1;    length = 1;
3286  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3287    if (common->utf8 && *cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc);
3288  #endif  #endif
3289    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)
3290      {      {
3291      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));
3292      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));
3293    
3294      context.length = length;      context.length = IN_UCHARS(length);
3295      context.sourcereg = -1;      context.sourcereg = -1;
3296  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3297      context.byteptr = 0;      context.ucharptr = 0;
3298  #endif  #endif
3299      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);      return byte_sequence_compare(common, type == OP_CHARI, cc, &context, fallbacks);
3300      }      }
3301    add_jump(compiler, fallbacks, CMP(SLJIT_C_GREATER_EQUAL, STR_PTR, 0, STR_END, 0));    check_input_end(common, fallbacks);
3302    read_char(common);    read_char(common);
3303  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3304    if (common->utf8)    if (common->utf)
3305      {      {
3306      GETCHAR(c, cc);      GETCHAR(c, cc);
3307      }      }
# Line 3085  switch(type) Line 3317  switch(type)
3317    
3318    case OP_NOT:    case OP_NOT:
3319    case OP_NOTI:    case OP_NOTI:
3320      check_input_end(common, fallbacks);
3321    length = 1;    length = 1;
3322  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3323    if (common->utf8)    if (common->utf)
3324      {      {
3325      if (*cc >= 0xc0) length += _pcre_utf8_table4[*cc & 0x3f];  #ifdef COMPILE_PCRE8
3326        c = *cc;
3327      check_input_end(common, fallbacks);      if (c < 128)
     GETCHAR(c, cc);  
   
     if (c <= 127)  
3328        {        {
3329        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);  
3330        if (type == OP_NOT || !char_has_othercase(common, cc))        if (type == OP_NOT || !char_has_othercase(common, cc))
3331          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));
3332        else        else
3333          {          {
3334          /* 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. */
3335          OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x20);          OP2(SLJIT_OR, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x20);
3336          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));
3337          }          }
3338        /* Skip the variable-length character. */        /* Skip the variable-length character. */
3339        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));
3340        return cc + length;        jump[0] = CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, 0xc0);
3341          OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)PRIV(utf8_table4) - 0xc0);
3342          OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0);
3343          JUMPHERE(jump[0]);
3344          return cc + 1;
3345        }        }
3346      else      else
3347    #endif /* COMPILE_PCRE8 */
3348          {
3349          GETCHARLEN(c, cc, length);
3350        read_char(common);        read_char(common);
3351          }
3352      }      }
3353    else    else
3354  #endif  #endif /* SUPPORT_UTF */
3355      {      {
3356      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);  
3357      c = *cc;      c = *cc;
3358      }      }
3359    
# Line 3139  switch(type) Line 3374  switch(type)
3374        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));
3375        }        }
3376      }      }
3377    return cc + length;    return cc + 1;
3378    
3379    case OP_CLASS:    case OP_CLASS:
3380    case OP_NCLASS:    case OP_NCLASS:
3381    check_input_end(common, fallbacks);    check_input_end(common, fallbacks);
3382    read_char(common);    read_char(common);
3383  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3384    jump[0] = NULL;    jump[0] = NULL;
3385    if (common->utf8)  #ifdef COMPILE_PCRE8
3386      /* This check only affects 8 bit mode. In other modes, we
3387      always need to compare the value with 255. */
3388      if (common->utf)
3389    #endif /* COMPILE_PCRE8 */
3390      {      {
3391      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);      jump[0] = CMP(SLJIT_C_GREATER, TMP1, 0, SLJIT_IMM, 255);
3392      if (type == OP_CLASS)      if (type == OP_CLASS)
# Line 3156  switch(type) Line 3395  switch(type)
3395        jump[0] = NULL;        jump[0] = NULL;
3396        }        }
3397      }      }
3398  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3399    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);    OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7);
3400    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);    OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 3);
3401    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);    OP1(SLJIT_MOV_UB, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_w)cc);
3402    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);    OP2(SLJIT_SHL, TMP2, 0, SLJIT_IMM, 1, TMP2, 0);
3403    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);
3404    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));    add_jump(compiler, fallbacks, JUMP(SLJIT_C_ZERO));
3405  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || !defined COMPILE_PCRE8
3406    if (jump[0] != NULL)    if (jump[0] != NULL)
3407      JUMPHERE(jump[0]);      JUMPHERE(jump[0]);
3408  #endif  #endif /* SUPPORT_UTF || !COMPILE_PCRE8 */
3409    return cc + 32;    return cc + 32 / sizeof(pcre_uchar);
3410    
3411  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
3412    case OP_XCLASS:    case OP_XCLASS:
3413    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);    compile_xclass_hotpath(common, cc + LINK_SIZE, fallbacks);
3414    return cc + GET(cc, 0) - 1;    return cc + GET(cc, 0) - 1;
# Line 3179  switch(type) Line 3418  switch(type)
3418    length = GET(cc, 0);    length = GET(cc, 0);
3419    SLJIT_ASSERT(length > 0);    SLJIT_ASSERT(length > 0);
3420    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0);
3421    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));  #ifdef SUPPORT_UTF
3422  #ifdef SUPPORT_UTF8    if (common->utf)
   if (common->utf8)  
3423      {      {
3424        OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin));
3425      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);      OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length);
3426      label = LABEL();      label = LABEL();
3427      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));
3428      skip_char_back(common);      skip_char_back(common);
3429      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);
3430      JUMPTO(SLJIT_C_NOT_ZERO, label);      JUMPTO(SLJIT_C_NOT_ZERO, label);
3431      return cc + LINK_SIZE;      return cc + LINK_SIZE;
3432      }      }
3433  #endif  #endif
3434    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));
3435      OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length));
3436    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));
3437    return cc + LINK_SIZE;    return cc + LINK_SIZE;
3438    }    }
# Line 3200  SLJIT_ASSERT_STOP(); Line 3440  SLJIT_ASSERT_STOP();
3440  return cc;  return cc;
3441  }  }
3442    
3443  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)
3444  {  {
3445  /* This function consumes at least one input character. */  /* This function consumes at least one input character. */
3446  /* 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. */
3447  DEFINE_COMPILER;  DEFINE_COMPILER;
3448  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3449  compare_context context;  compare_context context;
3450  int size;  int size;
3451    
# Line 3218  do Line 3458  do
3458    if (*cc == OP_CHAR)    if (*cc == OP_CHAR)
3459      {      {
3460      size = 1;      size = 1;
3461  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3462      if (common->utf8 && cc[1] >= 0xc0)      if (common->utf && HAS_EXTRALEN(cc[1]))
3463        size += _pcre_utf8_table4[cc[1] & 0x3f];        size += GET_EXTRALEN(cc[1]);
3464  #endif  #endif
3465      }      }
3466    else if (*cc == OP_CHARI)    else if (*cc == OP_CHARI)
3467      {      {
3468      size = 1;      size = 1;
3469  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
3470      if (common->utf8)      if (common->utf)
3471        {        {
3472        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)
3473          size = 0;          size = 0;
3474        else if (cc[1] >= 0xc0)        else if (HAS_EXTRALEN(cc[1]))
3475          size += _pcre_utf8_table4[cc[1] & 0x3f];          size += GET_EXTRALEN(cc[1]);
3476        }        }
3477      else      else
3478  #endif  #endif
# Line 3243  do Line 3483  do
3483      size = 0;      size = 0;
3484    
3485    cc += 1 + size;    cc += 1 + size;
3486    context.length += size;    context.length += IN_UCHARS(size);
3487    }    }
3488  while (size > 0 && context.length <= 128);  while (size > 0 && context.length <= 128);
3489    
# Line 3256  if (context.length > 0) Line 3496  if (context.length > 0)
3496    
3497    context.sourcereg = -1;    context.sourcereg = -1;
3498  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED  #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED
3499    context.byteptr = 0;    context.ucharptr = 0;
3500  #endif  #endif
3501    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);
3502    return cc;    return cc;
# Line 3266  if (context.length > 0) Line 3506  if (context.length > 0)
3506  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);  return compile_char1_hotpath(common, *cc, cc + 1, fallbacks);
3507  }  }
3508    
3509  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)
3510  {  {
3511  DEFINE_COMPILER;  DEFINE_COMPILER;
3512  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3288  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT Line 3528  return CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT
3528  }  }
3529    
3530  /* Forward definitions. */  /* Forward definitions. */
3531  static void compile_hotpath(compiler_common *, uschar *, uschar *, fallback_common *);  static void compile_hotpath(compiler_common *, pcre_uchar *, pcre_uchar *, fallback_common *);
3532  static void compile_fallbackpath(compiler_common *, struct fallback_common *);  static void compile_fallbackpath(compiler_common *, struct fallback_common *);
3533    
3534  #define PUSH_FALLBACK(size, ccstart, error) \  #define PUSH_FALLBACK(size, ccstart, error) \
# Line 3319  static void compile_fallbackpath(compile Line 3559  static void compile_fallbackpath(compile
3559    
3560  #define FALLBACK_AS(type) ((type*)fallback)  #define FALLBACK_AS(type) ((type*)fallback)
3561    
3562  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)
3563  {  {
3564  DEFINE_COMPILER;  DEFINE_COMPILER;
3565  int offset = GET2(cc, 1) << 1;  int offset = GET2(cc, 1) << 1;
# Line 3329  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT Line 3569  OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT
3569  if (withchecks && !common->jscript_compat)  if (withchecks && !common->jscript_compat)
3570    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)));
3571    
3572  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF && defined SUPPORT_UCP
3573  #ifdef SUPPORT_UCP  if (common->utf && *cc == OP_REFI)
 if (common->utf8 && *cc == OP_REFI)  
3574    {    {
3575    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);
3576    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 3342  if (common->utf8 && *cc == OP_REFI) Line 3581  if (common->utf8 && *cc == OP_REFI)
3581    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, STACK_TOP, 0);
3582    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);    OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, ARGUMENTS, 0);
3583    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);
3584    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));
3585    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);    OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0);
3586    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));
3587    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);    OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0);
3588    }    }
3589  else  else
3590  #endif  #endif /* SUPPORT_UTF && SUPPORT_UCP */
 #endif  
3591    {    {
3592    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);
3593    if (withchecks)    if (withchecks)
# Line 3368  if (jump != NULL) Line 3606  if (jump != NULL)
3606    else    else
3607      JUMPHERE(jump);      JUMPHERE(jump);
3608    }    }
3609  return cc + 3;  return cc + 1 + IMM2_SIZE;
3610  }  }
3611    
3612  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)
3613  {  {
3614  DEFINE_COMPILER;  DEFINE_COMPILER;
3615  fallback_common *fallback;  fallback_common *fallback;
3616  uschar type;  pcre_uchar type;
3617  struct sljit_label *label;  struct sljit_label *label;
3618  struct sljit_jump *zerolength;  struct sljit_jump *zerolength;
3619  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
3620  uschar *ccbegin = cc;  pcre_uchar *ccbegin = cc;
3621  int min = 0, max = 0;  int min = 0, max = 0;
3622  BOOL minimize;  BOOL minimize;
3623    
3624  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);  PUSH_FALLBACK(sizeof(iterator_fallback), cc, NULL);
3625    
3626  type = cc[3];  type = cc[1 + IMM2_SIZE];
3627  minimize = (type & 0x1) != 0;  minimize = (type & 0x1) != 0;
3628  switch(type)  switch(type)
3629    {    {
# Line 3393  switch(type) Line 3631  switch(type)
3631    case OP_CRMINSTAR:    case OP_CRMINSTAR:
3632    min = 0;    min = 0;
3633    max = 0;    max = 0;
3634    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3635    break;    break;
3636    case OP_CRPLUS:    case OP_CRPLUS:
3637    case OP_CRMINPLUS:    case OP_CRMINPLUS:
3638    min = 1;    min = 1;
3639    max = 0;    max = 0;
3640    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3641    break;    break;
3642    case OP_CRQUERY:    case OP_CRQUERY:
3643    case OP_CRMINQUERY:    case OP_CRMINQUERY:
3644    min = 0;    min = 0;
3645    max = 1;    max = 1;
3646    cc += 4;    cc += 1 + IMM2_SIZE + 1;
3647    break;    break;
3648    case OP_CRRANGE:    case OP_CRRANGE:
3649    case OP_CRMINRANGE:    case OP_CRMINRANGE:
3650    min = GET2(cc, 3 + 1);    min = GET2(cc, 1 + IMM2_SIZE + 1);
3651    max = GET2(cc, 3 + 3);    max = GET2(cc, 1 + IMM2_SIZE + 1 + IMM2_SIZE);
3652    cc += 8;    cc += 1 + IMM2_SIZE + 1 + 2 * IMM2_SIZE;
3653    break;    break;
3654    default:    default:
3655    SLJIT_ASSERT_STOP();    SLJIT_ASSERT_STOP();
# Line 3515  decrease_call_count(common); Line 3753  decrease_call_count(common);
3753  return cc;  return cc;
3754  }  }
3755    
3756  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)
3757  {  {
3758  DEFINE_COMPILER;  DEFINE_COMPILER;
3759  fallback_common *fallback;  fallback_common *fallback;
# Line 3561  add_jump(compiler, &fallback->topfallbac Line 3799  add_jump(compiler, &fallback->topfallbac
3799  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
3800  }  }
3801    
3802  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)
3803  {  {
3804  DEFINE_COMPILER;  DEFINE_COMPILER;
3805  int framesize;  int framesize;
3806  int localptr;  int localptr;
3807  fallback_common altfallback;  fallback_common altfallback;
3808  uschar *ccbegin;  pcre_uchar *ccbegin;
3809  uschar opcode;  pcre_uchar opcode;
3810  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
3811  jump_list *tmp = NULL;  jump_list *tmp = NULL;
3812  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;  jump_list **target = (conditional) ? &fallback->condfailed : &fallback->common.topfallbacks;
3813  jump_list **found;  jump_list **found;
# Line 3585  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 3823  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
3823    bra = *cc;    bra = *cc;
3824    cc++;    cc++;
3825    }    }
3826  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
3827  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
3828  framesize = get_framesize(common, cc, FALSE);  framesize = get_framesize(common, cc, FALSE);
3829  fallback->framesize = framesize;  fallback->framesize = framesize;
# Line 3644  while (1) Line 3882  while (1)
3882    if (common->accept != NULL)    if (common->accept != NULL)
3883      set_jumps(common->accept, common->acceptlabel);      set_jumps(common->accept, common->acceptlabel);
3884    
3885      /* Reset stack. */
3886    if (framesize < 0)    if (framesize < 0)
3887      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);      OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3888      else {
3889        if ((opcode != OP_ASSERT_NOT && opcode != OP_ASSERTBACK_NOT) || conditional)
3890          {
3891          /* We don't need to keep the STR_PTR, only the previous localptr. */
3892          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (framesize + 1) * sizeof(sljit_w));
3893          }
3894        else
3895          {
3896          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
3897          add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
3898          }
3899      }
3900    
3901    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)    if (opcode == OP_ASSERT_NOT || opcode == OP_ASSERTBACK_NOT)
3902      {      {
3903      /* 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. */
3904      if (conditional)      if (conditional)
3905        {        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));  
         }  
       }  
3906      else if (bra == OP_BRAZERO)      else if (bra == OP_BRAZERO)
3907        {        {
3908        if (framesize < 0)        if (framesize < 0)
3909          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3910        else        else
3911          {          {
         OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
         add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));  
3912          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));
3913          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));
3914          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP1, 0);
# Line 3675  while (1) Line 3916  while (1)
3916        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));
3917        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), SLJIT_IMM, 0);
3918        }        }
3919      else if (bra == OP_BRAMINZERO)      else if (framesize >= 0)
3920        {        {
3921        if (framesize >= 0)        /* For OP_BRA and OP_BRAMINZERO. */
3922          {        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));  
         }  
3923        }        }
3924      }      }
3925    add_jump(compiler, found, JUMP(SLJIT_JUMP));    add_jump(compiler, found, JUMP(SLJIT_JUMP));
# Line 3709  if (opcode == OP_ASSERT || opcode == OP_ Line 3946  if (opcode == OP_ASSERT || opcode == OP_
3946    /* Assert is failed. */    /* Assert is failed. */
3947    if (conditional || bra == OP_BRAZERO)    if (conditional || bra == OP_BRAZERO)
3948      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
3949    
3950    if (framesize < 0)    if (framesize < 0)
3951      {      {
3952      /* The topmost item should be 0. */      /* The topmost item should be 0. */
# Line 3720  if (opcode == OP_ASSERT || opcode == OP_ Line 3958  if (opcode == OP_ASSERT || opcode == OP_
3958    else    else
3959      {      {
3960      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));  
3961      /* The topmost item should be 0. */      /* The topmost item should be 0. */
3962      if (bra == OP_BRAZERO)      if (bra == OP_BRAZERO)
3963        {        {
# Line 3731  if (opcode == OP_ASSERT || opcode == OP_ Line 3967  if (opcode == OP_ASSERT || opcode == OP_
3967      else      else
3968        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
3969      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);  
3970      }      }
3971    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
3972    if (bra != OP_BRAZERO)    if (bra != OP_BRAZERO)
# Line 3755  if (opcode == OP_ASSERT || opcode == OP_ Line 3989  if (opcode == OP_ASSERT || opcode == OP_
3989      }      }
3990    else    else
3991      {      {
3992      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)  
3993        {        {
3994        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
3995        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));
3996          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), 0);
3997        }        }
3998      else if (bra == OP_BRAMINZERO)      else
3999        {        {
4000        allocate_stack(common, 1);        /* We don't need to keep the STR_PTR, only the previous localptr. */
4001        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));
4002          OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4003          OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), bra == OP_BRAZERO ? STR_PTR : SLJIT_IMM, 0);
4004        }        }
4005      }      }
4006    
# Line 3802  else Line 4037  else
4037      {      {
4038      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4039      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));  
4040      /* The topmost item should be 0. */      /* The topmost item should be 0. */
4041      if (bra != OP_BRA)      if (bra != OP_BRA)
4042        {        {
# Line 3813  else Line 4046  else
4046      else      else
4047        free_stack(common, framesize + 2);        free_stack(common, framesize + 2);
4048      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);  
4049      }      }
4050    
4051    if (bra == OP_BRAZERO)    if (bra == OP_BRAZERO)
# Line 3838  common->accept = save_accept; Line 4069  common->accept = save_accept;
4069  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4070  }  }
4071    
4072    static sljit_w SLJIT_CALL do_searchovector(sljit_w refno, sljit_w* locals, pcre_uchar *name_table)
4073    {
4074    int condition = FALSE;
4075    pcre_uchar *slotA = name_table;
4076    pcre_uchar *slotB;
4077    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4078    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4079    sljit_w no_capture;
4080    int i;
4081    
4082    locals += OVECTOR_START / sizeof(sljit_w);
4083    no_capture = locals[1];
4084    
4085    for (i = 0; i < name_count; i++)
4086      {
4087      if (GET2(slotA, 0) == refno) break;
4088      slotA += name_entry_size;
4089      }
4090    
4091    if (i < name_count)
4092      {
4093      /* Found a name for the number - there can be only one; duplicate names
4094      for different numbers are allowed, but not vice versa. First scan down
4095      for duplicates. */
4096    
4097      slotB = slotA;
4098      while (slotB > name_table)
4099        {
4100        slotB -= name_entry_size;
4101        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4102          {
4103          condition = locals[GET2(slotB, 0) << 1] != no_capture;
4104          if (condition) break;
4105          }
4106        else break;
4107        }
4108    
4109      /* Scan up for duplicates */
4110      if (!condition)
4111        {
4112        slotB = slotA;
4113        for (i++; i < name_count; i++)
4114          {
4115          slotB += name_entry_size;
4116          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4117            {
4118            condition = locals[GET2(slotB, 0) << 1] != no_capture;
4119            if (condition) break;
4120            }
4121          else break;
4122          }
4123        }
4124      }
4125    return condition;
4126    }
4127    
4128    static sljit_w SLJIT_CALL do_searchgroups(sljit_w recno, sljit_w* locals, pcre_uchar *name_table)
4129    {
4130    int condition = FALSE;
4131    pcre_uchar *slotA = name_table;
4132    pcre_uchar *slotB;
4133    sljit_w name_count = locals[LOCALS0 / sizeof(sljit_w)];
4134    sljit_w name_entry_size = locals[LOCALS1 / sizeof(sljit_w)];
4135    sljit_w group_num = locals[POSSESSIVE0 / sizeof(sljit_w)];
4136    int i;
4137    
4138    for (i = 0; i < name_count; i++)
4139      {
4140      if (GET2(slotA, 0) == recno) break;
4141      slotA += name_entry_size;
4142      }
4143    
4144    if (i < name_count)
4145      {
4146      /* Found a name for the number - there can be only one; duplicate
4147      names for different numbers are allowed, but not vice versa. First
4148      scan down for duplicates. */
4149    
4150      slotB = slotA;
4151      while (slotB > name_table)
4152        {
4153        slotB -= name_entry_size;
4154        if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4155          {
4156          condition = GET2(slotB, 0) == group_num;
4157          if (condition) break;
4158          }
4159        else break;
4160        }
4161    
4162      /* Scan up for duplicates */
4163      if (!condition)
4164        {
4165        slotB = slotA;
4166        for (i++; i < name_count; i++)
4167          {
4168          slotB += name_entry_size;
4169          if (STRCMP_UC_UC(slotA + IMM2_SIZE, slotB + IMM2_SIZE) == 0)
4170            {
4171            condition = GET2(slotB, 0) == group_num;
4172            if (condition) break;
4173            }
4174          else break;
4175          }
4176        }
4177      }
4178    return condition;
4179    }
4180    
4181  /*  /*
4182    Handling bracketed expressions is probably the most complex part.    Handling bracketed expressions is probably the most complex part.
4183    
# Line 3847  return cc + 1 + LINK_SIZE; Line 4187  return cc + 1 + LINK_SIZE;
4187      A - Push the current STR_PTR. Needed for restoring the STR_PTR      A - Push the current STR_PTR. Needed for restoring the STR_PTR
4188          before the next alternative. Not pushed if there are no alternatives.          before the next alternative. Not pushed if there are no alternatives.
4189      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.
4190      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.
4191      L - Push the previous local (pointed by localptr) to the stack      L - Push the previous local (pointed by localptr) to the stack
4192     () - opional values stored on the stack     () - opional values stored on the stack
4193    ()* - optonal, can be stored multiple times    ()* - optonal, can be stored multiple times
# Line 3885  return cc + 1 + LINK_SIZE; Line 4225  return cc + 1 + LINK_SIZE;
4225      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.
4226    
4227    The next list shows the possible content of a bracket:    The next list shows the possible content of a bracket:
4228    (|)     OP_*BRA  | OP_ALT ...         M A    (|)     OP_*BRA    | OP_ALT ...         M A
4229    (?()|)  OP_*COND | OP_ALT             M A    (?()|)  OP_*COND   | OP_ALT             M A
4230    (?>|)   OP_ONCE  | OP_ALT ...         [stack trace] M A    (?>|)   OP_ONCE    | OP_ALT ...         [stack trace] M A
4231                                          Or nothing, if trace is unnecessary    (?>|)   OP_ONCE_NC | OP_ALT ...         [stack trace] M A
4232                                              Or nothing, if trace is unnecessary
4233  */  */
4234    
4235  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)
4236  {  {
4237  DEFINE_COMPILER;  DEFINE_COMPILER;
4238  fallback_common *fallback;  fallback_common *fallback;
4239  uschar opcode;  pcre_uchar opcode;
4240  int localptr = 0;  int localptr = 0;
4241  int offset = 0;  int offset = 0;
4242  int stacksize;  int stacksize;
4243  uschar *ccbegin;  pcre_uchar *ccbegin;
4244  uschar *hotpath;  pcre_uchar *hotpath;
4245  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
4246  uschar ket;  pcre_uchar ket;
4247  assert_fallback *assert;  assert_fallback *assert;
4248  BOOL has_alternatives;  BOOL has_alternatives;
4249  struct sljit_jump *jump;  struct sljit_jump *jump;
# Line 3921  if (*cc == OP_BRAZERO || *cc == OP_BRAMI Line 4262  if (*cc == OP_BRAZERO || *cc == OP_BRAMI
4262    
4263  opcode = *cc;  opcode = *cc;
4264  ccbegin = cc;  ccbegin = cc;
4265    hotpath = ccbegin + 1 + LINK_SIZE;
4266    
4267  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)
4268    {    {
4269    /* Drop this bracket_fallback. */    /* Drop this bracket_fallback. */
# Line 3932  ket = *(bracketend(cc) - 1 - LINK_SIZE); Line 4275  ket = *(bracketend(cc) - 1 - LINK_SIZE);
4275  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);  SLJIT_ASSERT(ket == OP_KET || ket == OP_KETRMAX || ket == OP_KETRMIN);
4276  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)));
4277  cc += GET(cc, 1);  cc += GET(cc, 1);
4278  has_alternatives = *cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND;  
4279    has_alternatives = *cc == OP_ALT;
4280    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
4281      {
4282      has_alternatives = (*hotpath == OP_RREF) ? FALSE : TRUE;
4283      if (*hotpath == OP_NRREF)
4284        {
4285        stacksize = GET2(hotpath, 1);
4286        if (common->currententry == NULL || stacksize == RREF_ANY)
4287          has_alternatives = FALSE;
4288        else if (common->currententry->start == 0)
4289          has_alternatives = stacksize != 0;
4290        else
4291          has_alternatives = stacksize != GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4292        }
4293      }
4294    
4295  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
4296    opcode = OP_SCOND;    opcode = OP_SCOND;
4297    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
4298      opcode = OP_ONCE;
4299    
4300  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
4301    {    {
# Line 3943  if (opcode == OP_CBRA || opcode == OP_SC Line 4304  if (opcode == OP_CBRA || opcode == OP_SC
4304    localptr = OVECTOR_PRIV(offset);    localptr = OVECTOR_PRIV(offset);
4305    offset <<= 1;    offset <<= 1;
4306    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4307      hotpath += IMM2_SIZE;
4308    }    }
4309  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_ONCE || opcode == OP_SBRA || opcode == OP_SCOND)
4310    {    {
4311    /* Other brackets simply allocate the next entry. */    /* Other brackets simply allocate the next entry. */
4312    localptr = PRIV(ccbegin);    localptr = PRIV_DATA(ccbegin);
4313    SLJIT_ASSERT(localptr != 0);    SLJIT_ASSERT(localptr != 0);
4314    FALLBACK_AS(bracket_fallback)->localptr = localptr;    FALLBACK_AS(bracket_fallback)->localptr = localptr;
4315    if (opcode == OP_ONCE)    if (opcode == OP_ONCE)
# Line 4074  if (opcode == OP_ONCE) Line 4436  if (opcode == OP_ONCE)
4436  else if (opcode == OP_CBRA || opcode == OP_SCBRA)  else if (opcode == OP_CBRA || opcode == OP_SCBRA)
4437    {    {
4438    /* Saving the previous values. */    /* Saving the previous values. */
4439    allocate_stack(common, 4);    allocate_stack(common, 3);
4440    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4441    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));
4442    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
4443    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(1), TMP2, 0);
4444    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
   OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4445    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, STR_PTR, 0);
4446    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(2), TMP1, 0);
   OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(3), TMP2, 0);  
   /* Update MAX_INDEX if necessary. */  
   add_stub(common, max_index, (offset >> 1) + 1, CMP(SLJIT_C_LESS, TMP1, 0, SLJIT_IMM, (offset >> 1) + 1));  
4447    }    }
4448  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
4449    {    {
# Line 4103  else if (has_alternatives) Line 4461  else if (has_alternatives)
4461    }    }
4462    
4463  /* Generating code for the first alternative. */  /* Generating code for the first alternative. */
 hotpath = ccbegin + 1 + LINK_SIZE;  
 if (offset != 0)  
   hotpath += 2;  
4464  if (opcode == OP_COND || opcode == OP_SCOND)  if (opcode == OP_COND || opcode == OP_SCOND)
4465    {    {
4466    if (*hotpath == OP_CREF)    if (*hotpath == OP_CREF)
4467      {      {
4468        SLJIT_ASSERT(has_alternatives);
4469      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),      add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed),
4470        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)));
4471      hotpath += 3;      hotpath += 1 + IMM2_SIZE;
4472        }
4473      else if (*hotpath == OP_NCREF)
4474        {
4475        SLJIT_ASSERT(has_alternatives);
4476        stacksize = GET2(hotpath, 1);
4477        jump = CMP(SLJIT_C_NOT_EQUAL, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(stacksize << 1), SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(1));
4478    
4479        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4480        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4481        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4482        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4483        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4484        OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4485        sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchovector));
4486        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4487        add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4488    
4489        JUMPHERE(jump);
4490        hotpath += 1 + IMM2_SIZE;
4491        }
4492      else if (*hotpath == OP_RREF || *hotpath == OP_NRREF)
4493        {
4494        /* Never has other case. */
4495        FALLBACK_AS(bracket_fallback)->u.condfailed = NULL;
4496    
4497        stacksize = GET2(hotpath, 1);
4498        if (common->currententry == NULL)
4499          stacksize = 0;
4500        else if (stacksize == RREF_ANY)
4501          stacksize = 1;
4502        else if (common->currententry->start == 0)
4503          stacksize = stacksize == 0;
4504        else
4505          stacksize = stacksize == GET2(common->start, common->currententry->start + 1 + LINK_SIZE);
4506    
4507        if (*hotpath == OP_RREF || stacksize || common->currententry == NULL)
4508          {
4509          SLJIT_ASSERT(!has_alternatives);
4510          if (stacksize != 0)
4511            hotpath += 1 + IMM2_SIZE;
4512          else
4513            {
4514            if (*cc == OP_ALT)
4515              {
4516              hotpath = cc + 1 + LINK_SIZE;
4517              cc += GET(cc, 1);
4518              }
4519            else
4520              hotpath = cc;
4521            }
4522          }
4523        else
4524          {
4525          SLJIT_ASSERT(has_alternatives);
4526    
4527          stacksize = GET2(hotpath, 1);
4528          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1, STACK_TOP, 0);
4529          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS0, SLJIT_IMM, common->name_count);
4530          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS1, SLJIT_IMM, common->name_entry_size);
4531          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE0, SLJIT_IMM, GET2(common->start, common->currententry->start + 1 + LINK_SIZE));
4532          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, stacksize);
4533          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG2, 0, SLJIT_LOCALS_REG, 0);
4534          OP1(SLJIT_MOV, SLJIT_TEMPORARY_REG3, 0, SLJIT_IMM, common->name_table);
4535          sljit_emit_ijump(compiler, SLJIT_CALL3, SLJIT_IMM, SLJIT_FUNC_OFFSET(do_searchgroups));
4536          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), POSSESSIVE1);
4537          add_jump(compiler, &(FALLBACK_AS(bracket_fallback)->u.condfailed), CMP(SLJIT_C_EQUAL, SLJIT_TEMPORARY_REG1, 0, SLJIT_IMM, 0));
4538          hotpath += 1 + IMM2_SIZE;
4539          }
4540      }      }
4541    else    else
4542      {      {
4543      SLJIT_ASSERT(*hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);      SLJIT_ASSERT(has_alternatives && *hotpath >= OP_ASSERT && *hotpath <= OP_ASSERTBACK_NOT);
4544      /* Similar code as PUSH_FALLBACK macro. */      /* Similar code as PUSH_FALLBACK macro. */
4545      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));      assert = sljit_alloc_memory(compiler, sizeof(assert_fallback));
4546      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))      if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler)))
# Line 4146  if (opcode == OP_ONCE) Line 4570  if (opcode == OP_ONCE)
4570        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);
4571        }        }
4572      }      }
4573    else if (ket == OP_KETRMAX)    else
4574      {      {
4575      /* TMP2 which is set here used by OP_KETRMAX below. */      stacksize = (ket == OP_KETRMIN || ket == OP_KETRMAX || has_alternatives) ? 2 : 1;
4576      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));
4577      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (FALLBACK_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));      if (ket == OP_KETRMAX)
4578          {
4579          /* TMP2 which is set here used by OP_KETRMAX below. */
4580          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
4581          }
4582      }      }
4583    }    }
4584    
# Line 4243  cc += 1 + LINK_SIZE; Line 4671  cc += 1 + LINK_SIZE;
4671  return cc;  return cc;
4672  }  }
4673    
4674  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)
4675  {  {
4676  DEFINE_COMPILER;  DEFINE_COMPILER;
4677  fallback_common *fallback;  fallback_common *fallback;
4678  uschar opcode;  pcre_uchar opcode;
4679  int localptr;  int localptr;
4680  int cbraprivptr = 0;  int cbraprivptr = 0;
4681  int framesize;  int framesize;
4682  int stacksize;  int stacksize;
4683  int offset = 0;  int offset = 0;
4684  BOOL zero = FALSE;  BOOL zero = FALSE;
4685  uschar *ccbegin = NULL;  pcre_uchar *ccbegin = NULL;
4686  int stack;  int stack;
4687  struct sljit_label *loop = NULL;  struct sljit_label *loop = NULL;
4688  struct jump_list *emptymatch = NULL;  struct jump_list *emptymatch = NULL;
# Line 4267  if (*cc == OP_BRAPOSZERO) Line 4695  if (*cc == OP_BRAPOSZERO)
4695    }    }
4696    
4697  opcode = *cc;  opcode = *cc;
4698  localptr = PRIV(cc);  localptr = PRIV_DATA(cc);
4699  SLJIT_ASSERT(localptr != 0);  SLJIT_ASSERT(localptr != 0);
4700  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;  FALLBACK_AS(bracketpos_fallback)->localptr = localptr;
4701  switch(opcode)  switch(opcode)
# Line 4282  switch(opcode) Line 4710  switch(opcode)
4710    offset = GET2(cc, 1 + LINK_SIZE);    offset = GET2(cc, 1 + LINK_SIZE);
4711    cbraprivptr = OVECTOR_PRIV(offset);    cbraprivptr = OVECTOR_PRIV(offset);
4712    offset <<= 1;    offset <<= 1;
4713    ccbegin = cc + 1 + LINK_SIZE + 2;    ccbegin = cc + 1 + LINK_SIZE + IMM2_SIZE;
4714    break;    break;
4715    
4716    default:    default:
# Line 4294  framesize = get_framesize(common, cc, FA Line 4722  framesize = get_framesize(common, cc, FA
4722  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;  FALLBACK_AS(bracketpos_fallback)->framesize = framesize;
4723  if (framesize < 0)  if (framesize < 0)
4724    {    {
4725    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 3 : 1;    stacksize = (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS) ? 2 : 1;
4726    if (!zero)    if (!zero)
4727      stacksize++;      stacksize++;
4728    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;    FALLBACK_AS(bracketpos_fallback)->stacksize = stacksize;
# Line 4306  if (framesize < 0) Line 4734  if (framesize < 0)
4734      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset));
4735      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));
4736      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4737      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), TMP1, 0);  
4738      }      }
4739    else    else
4740      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 4365  while (*cc != OP_KETRPOS) Line 4791  while (*cc != OP_KETRPOS)
4791      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4792        {        {
4793        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4794        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, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));  
4795        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4796          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4797        }        }
4798      else      else
4799        {        {
# Line 4388  while (*cc != OP_KETRPOS) Line 4812  while (*cc != OP_KETRPOS)
4812      {      {
4813      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4814        {        {
4815          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, stacksize * sizeof(sljit_w));
4816        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr);
       OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
4817        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, TMP2, 0, SLJIT_IMM, (offset >> 1) + 1));  
       if (!zero)  
         OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);  
4818        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);        OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), cbraprivptr, STR_PTR, 0);
4819          OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
4820        }        }
4821      else      else
4822        {        {
4823        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);        OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4824          OP2(SLJIT_ADD, STACK_TOP, 0, TMP2, 0, SLJIT_IMM, stacksize * sizeof(sljit_w));
4825        if (opcode == OP_SBRAPOS)        if (opcode == OP_SBRAPOS)
4826          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));
4827        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 4408  while (*cc != OP_KETRPOS) Line 4830  while (*cc != OP_KETRPOS)
4830      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_SBRAPOS || opcode == OP_SCBRAPOS)
4831        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));
4832    
     /* TMP2 must be set above. */  
4833      if (!zero)      if (!zero)
4834        {        {
4835        if (framesize < 0)        if (framesize < 0)
4836          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);
4837        else        else
4838          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);
4839        }        }
4840      }      }
4841    JUMPTO(SLJIT_JUMP, loop);    JUMPTO(SLJIT_JUMP, loop);
# Line 4436  while (*cc != OP_KETRPOS) Line 4857  while (*cc != OP_KETRPOS)
4857      {      {
4858      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)      if (opcode == OP_CBRAPOS || opcode == OP_SCBRAPOS)
4859        {        {
4860          /* Last alternative. */
4861        if (*cc == OP_KETRPOS)        if (*cc == OP_KETRPOS)
4862          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
4863        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 4467  decrease_call_count(common); Line 4889  decrease_call_count(common);
4889  return cc + 1 + LINK_SIZE;  return cc + 1 + LINK_SIZE;
4890  }  }
4891    
4892  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)
4893  {  {
4894  int class_len;  int class_len;
4895    
# Line 4506  else Line 4928  else
4928    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);    SLJIT_ASSERT(*opcode >= OP_CLASS || *opcode <= OP_XCLASS);
4929    *type = *opcode;    *type = *opcode;
4930    cc++;    cc++;
4931    class_len = (*type < OP_XCLASS) ? 33 : GET(cc, 0);    class_len = (*type < OP_XCLASS) ? (1 + (32 / sizeof(pcre_uchar))) : GET(cc, 0);
4932    *opcode = cc[class_len - 1];    *opcode = cc[class_len - 1];
4933    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)    if (*opcode >= OP_CRSTAR && *opcode <= OP_CRMINQUERY)
4934      {      {
# Line 4517  else Line 4939  else
4939    else    else
4940      {      {
4941      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);      SLJIT_ASSERT(*opcode == OP_CRRANGE || *opcode == OP_CRMINRANGE);
4942      *arg1 = GET2(cc, (class_len + 2));      *arg1 = GET2(cc, (class_len + IMM2_SIZE));
4943      *arg2 = GET2(cc, class_len);      *arg2 = GET2(cc, class_len);
4944    
4945      if (*arg2 == 0)      if (*arg2 == 0)
# Line 4529  else Line 4951  else
4951        *opcode = OP_EXACT;        *opcode = OP_EXACT;
4952    
4953      if (end != NULL)      if (end != NULL)
4954        *end = cc + class_len + 4;        *end = cc + class_len + 2 * IMM2_SIZE;
4955      }      }
4956    return cc;    return cc;
4957    }    }
# Line 4537  else Line 4959  else
4959  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)
4960    {    {
4961    *arg1 = GET2(cc, 0);    *arg1 = GET2(cc, 0);
4962    cc += 2;    cc += IMM2_SIZE;
4963    }    }
4964    
4965  if (*type == 0)  if (*type == 0)
# Line 4552  if (*type == 0) Line 4974  if (*type == 0)
4974  if (end != NULL)  if (end != NULL)
4975    {    {
4976    *end = cc + 1;    *end = cc + 1;
4977  #ifdef SUPPORT_UTF8  #ifdef SUPPORT_UTF
4978    if (common->utf8 && *cc >= 0xc0) *end += _pcre_utf8_table4[*cc & 0x3f];    if (common->utf && HAS_EXTRALEN(*cc)) *end += GET_EXTRALEN(*cc);
4979  #endif  #endif
4980    }    }
4981  return cc;  return cc;
4982  }  }
4983    
4984  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)
4985  {  {
4986  DEFINE_COMPILER;  DEFINE_COMPILER;
4987  fallback_common *fallback;  fallback_common *fallback;
4988  uschar opcode;  pcre_uchar opcode;
4989  uschar type;  pcre_uchar type;
4990  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
4991  uschar* end;  pcre_uchar* end;
4992  jump_list *nomatch = NULL;  jump_list *nomatch = NULL;
4993  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
4994  struct sljit_label *label;  struct sljit_label *label;
# Line 4728  decrease_call_count(common); Line 5150  decrease_call_count(common);
5150  return end;  return end;
5151  }  }
5152    
5153  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)
5154  {  {
5155  DEFINE_COMPILER;  DEFINE_COMPILER;
5156  fallback_common *fallback;  fallback_common *fallback;
# Line 4772  add_jump(compiler, &fallback->topfallbac Line 5194  add_jump(compiler, &fallback->topfallbac
5194  return cc + 1;  return cc + 1;
5195  }  }
5196    
5197  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)
5198  {  {
5199  DEFINE_COMPILER;  DEFINE_COMPILER;
 struct sljit_jump *jump;  
5200  int offset = GET2(cc, 1);  int offset = GET2(cc, 1);
5201    
5202  /* Data will be discarded anyway... */  /* Data will be discarded anyway... */
5203  if (common->currententry != NULL)  if (common->currententry != NULL)
5204    return cc + 3;    return cc + 1 + IMM2_SIZE;
5205    
5206  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));
 OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX);  
5207  offset <<= 1;  offset <<= 1;
5208  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);
5209  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5210  offset = (offset >> 1) + 1;  return cc + 1 + IMM2_SIZE;
 jump = CMP(SLJIT_C_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, offset);  
 OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, SLJIT_IMM, offset);  
 JUMPHERE(jump);  
 return cc + 3;  
5211  }  }
5212    
5213  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)
5214  {  {
5215  DEFINE_COMPILER;  DEFINE_COMPILER;
5216  fallback_common *fallback;  fallback_common *fallback;
# Line 4815  while (cc < ccend) Line 5231  while (cc < ccend)
5231      case OP_WORDCHAR:      case OP_WORDCHAR:
5232      case OP_ANY:      case OP_ANY:
5233      case OP_ALLANY:      case OP_ALLANY:
5234        case OP_ANYBYTE:
5235      case OP_NOTPROP:      case OP_NOTPROP:
5236      case OP_PROP:      case OP_PROP:
5237      case OP_ANYNL:      case OP_ANYNL:
# Line 4919  while (cc < ccend) Line 5336  while (cc < ccend)
5336    
5337      case OP_CLASS:      case OP_CLASS:
5338      case OP_NCLASS:      case OP_NCLASS:
5339      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)
5340        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
5341      else      else
5342        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);
5343      break;      break;
5344    
5345  #ifdef SUPPORT_UTF8  #if defined SUPPORT_UTF || defined COMPILE_PCRE16
5346      case OP_XCLASS:      case OP_XCLASS:
5347      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)
5348        cc = compile_iterator_hotpath(common, cc, parent);        cc = compile_iterator_hotpath(common, cc, parent);
# Line 4936  while (cc < ccend) Line 5353  while (cc < ccend)
5353    
5354      case OP_REF:      case OP_REF:
5355      case OP_REFI:      case OP_REFI:
5356      if (cc[3] >= OP_CRSTAR && cc[3] <= OP_CRMINRANGE)      if (cc[1 + IMM2_SIZE] >= OP_CRSTAR && cc[1 + IMM2_SIZE] <= OP_CRMINRANGE)
5357        cc = compile_ref_iterator_hotpath(common, cc, parent);        cc = compile_ref_iterator_hotpath(common, cc, parent);
5358      else      else
5359        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 4974  while (cc < ccend) Line 5391  while (cc < ccend)
5391      break;      break;
5392    
5393      case OP_ONCE:      case OP_ONCE:
5394        case OP_ONCE_NC:
5395      case OP_BRA:      case OP_BRA:
5396      case OP_CBRA:      case OP_CBRA:
5397      case OP_COND:      case OP_COND:
# Line 5043  SLJIT_ASSERT(cc == ccend); Line 5461  SLJIT_ASSERT(cc == ccend);
5461  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_iterator_fallbackpath(compiler_common *common, struct fallback_common *current)
5462  {  {
5463  DEFINE_COMPILER;  DEFINE_COMPILER;
5464  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5465  uschar opcode;  pcre_uchar opcode;
5466  uschar type;  pcre_uchar type;
5467  int arg1 = -1, arg2 = -1;  int arg1 = -1, arg2 = -1;
5468  struct sljit_label *label = NULL;  struct sljit_label *label = NULL;
5469  struct sljit_jump *jump = NULL;  struct sljit_jump *jump = NULL;
# Line 5170  switch(opcode) Line 5588  switch(opcode)
5588  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)
5589  {  {
5590  DEFINE_COMPILER;  DEFINE_COMPILER;
5591  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5592  uschar type;  pcre_uchar type;
5593    
5594  type = cc[3];  type = cc[1 + IMM2_SIZE];
5595  if ((type & 0x1) == 0)  if ((type & 0x1) == 0)
5596    {    {
5597    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
# Line 5202  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R Line 5620  OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_R
5620  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)  static void compile_assert_fallbackpath(compiler_common *common, struct fallback_common *current)
5621  {  {
5622  DEFINE_COMPILER;  DEFINE_COMPILER;
5623  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5624  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
 struct sljit_jump *jump;  
5625  struct sljit_jump *brajump = NULL;  struct sljit_jump *brajump = NULL;
5626    
5627  SLJIT_ASSERT(*cc != OP_BRAMINZERO);  SLJIT_ASSERT(*cc != OP_BRAMINZERO);
# Line 5250  if (*cc == OP_ASSERT || *cc == OP_ASSERT Line 5667  if (*cc == OP_ASSERT || *cc == OP_ASSERT
5667    {    {
5668    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);
5669    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));    add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
5670      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));
5671    
5672    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5673    }    }
5674  else  else
   {  
   jump = JUMP(SLJIT_JUMP);  
   
5675    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));  
5676    
5677  if (bra == OP_BRAZERO)  if (bra == OP_BRAZERO)
5678    {    {
# Line 5282  int offset = 0; Line 5692  int offset = 0;
5692  int localptr = CURRENT_AS(bracket_fallback)->localptr;  int localptr = CURRENT_AS(bracket_fallback)->localptr;
5693  int stacksize;  int stacksize;
5694  int count;  int count;
5695  uschar *cc = current->cc;  pcre_uchar *cc = current->cc;
5696  uschar *ccbegin;  pcre_uchar *ccbegin;
5697  uschar *ccprev;  pcre_uchar *ccprev;
5698  jump_list *jumplist = NULL;  jump_list *jumplist = NULL;
5699  jump_list *jumplistitem = NULL;  jump_list *jumplistitem = NULL;
5700  uschar bra = OP_BRA;  pcre_uchar bra = OP_BRA;
5701  uschar ket;  pcre_uchar ket;
5702  assert_fallback *assert;  assert_fallback *assert;
5703    BOOL has_alternatives;
5704  struct sljit_jump *brazero = NULL;  struct sljit_jump *brazero = NULL;
5705  struct sljit_jump *once = NULL;  struct sljit_jump *once = NULL;
5706  struct sljit_jump *cond = NULL;  struct sljit_jump *cond = NULL;
# Line 5305  opcode = *cc; Line 5716  opcode = *cc;
5716  ccbegin = cc;  ccbegin = cc;
5717  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);  ket = *(bracketend(ccbegin) - 1 - LINK_SIZE);
5718  cc += GET(cc, 1);  cc += GET(cc, 1);
5719    has_alternatives = *cc == OP_ALT;
5720    if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5721      has_alternatives = (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT) || CURRENT_AS(bracket_fallback)->u.condfailed != NULL;
5722  if (opcode == OP_CBRA || opcode == OP_SCBRA)  if (opcode == OP_CBRA || opcode == OP_SCBRA)
5723    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;    offset = (GET2(ccbegin, 1 + LINK_SIZE)) << 1;
5724  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))  if (SLJIT_UNLIKELY(opcode == OP_COND) && (*cc == OP_KETRMAX || *cc == OP_KETRMIN))
5725    opcode = OP_SCOND;    opcode = OP_SCOND;
5726    if (SLJIT_UNLIKELY(opcode == OP_ONCE_NC))
5727      opcode = OP_ONCE;
5728    
5729  if (ket == OP_KETRMAX)  if (ket == OP_KETRMAX)
5730    {    {
# Line 5351  else if (bra == OP_BRAZERO) Line 5767  else if (bra == OP_BRAZERO)
5767    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);    brazero = CMP(SLJIT_C_NOT_EQUAL, TMP1, 0, SLJIT_IMM, 0);
5768    }    }
5769    
5770  if (opcode == OP_ONCE)  if (SLJIT_UNLIKELY(opcode == OP_ONCE))
5771    {    {
5772    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)    if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)
5773      {      {
# Line 5360  if (opcode == OP_ONCE) Line 5776  if (opcode == OP_ONCE)
5776      }      }
5777    once = JUMP(SLJIT_JUMP);    once = JUMP(SLJIT_JUMP);
5778    }    }
5779    else if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5780      {
5781      if (has_alternatives)
5782        {
5783        /* Always exactly one alternative. */
5784        OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5785        free_stack(common, 1);
5786    
5787        jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));
5788        if (SLJIT_UNLIKELY(!jumplistitem))
5789          return;
5790        jumplist = jumplistitem;
5791        jumplistitem->next = NULL;
5792        jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);
5793        }
5794      }
5795  else if (*cc == OP_ALT)  else if (*cc == OP_ALT)
5796    {    {
5797    /* Build a jump list. Get the last successfully matched branch index. */    /* Build a jump list. Get the last successfully matched branch index. */
# Line 5391  else if (*cc == OP_ALT) Line 5823  else if (*cc == OP_ALT)
5823    
5824    cc = ccbegin + GET(ccbegin, 1);    cc = ccbegin + GET(ccbegin, 1);
5825    }    }
 else if (opcode == OP_COND || opcode == OP_SCOND)  
   {  
   /* Always one. */  
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));  
   free_stack(common, 1);  
   
   jumplistitem = sljit_alloc_memory(compiler, sizeof(jump_list));  
   if (SLJIT_UNLIKELY(!jumplistitem))  
     return;  
   jumplist = jumplistitem;  
   jumplistitem->next = NULL;  
   jumplistitem->jump = CMP(SLJIT_C_EQUAL, TMP1, 0, SLJIT_IMM, 1);  
   }  
5826    
5827  COMPILE_FALLBACKPATH(current->top);  COMPILE_FALLBACKPATH(current->top);
5828  if (current->topfallbacks)  if (current->topfallbacks)
5829    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
5830    
5831  if (opcode == OP_COND || opcode == OP_SCOND)  if (SLJIT_UNLIKELY(opcode == OP_COND) || SLJIT_UNLIKELY(opcode == OP_SCOND))
5832    {    {
5833    /* Conditional block always has at most one alternative. */    /* Conditional block always has at most one alternative. */
5834    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)    if (ccbegin[1 + LINK_SIZE] >= OP_ASSERT && ccbegin[1 + LINK_SIZE] <= OP_ASSERTBACK_NOT)
5835      {      {
5836        SLJIT_ASSERT(has_alternatives);
5837      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5838      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK))
5839        {        {
# Line 5424  if (opcode == OP_COND || opcode == OP_SC Line 5844  if (opcode == OP_COND || opcode == OP_SC
5844      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5845      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.assert->condfailed, LABEL());
5846      }      }
5847    else    else if (CURRENT_AS(bracket_fallback)->u.condfailed != NULL)
5848      {      {
5849        SLJIT_ASSERT(has_alternatives);
5850      cond = JUMP(SLJIT_JUMP);      cond = JUMP(SLJIT_JUMP);
5851      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());      set_jumps(CURRENT_AS(bracket_fallback)->u.condfailed, LABEL());
5852      }      }
5853      else
5854        SLJIT_ASSERT(!has_alternatives);
5855    }    }
5856    
5857  if (*cc == OP_ALT || opcode == OP_COND || opcode == OP_SCOND)  if (has_alternatives)
5858    {    {
5859    count = 1;    count = 1;
5860    do    do
# Line 5459  if (*cc == OP_ALT || opcode == OP_COND | Line 5882  if (*cc == OP_ALT || opcode == OP_COND |
5882      /* There is a similar code in compile_bracket_hotpath. */      /* There is a similar code in compile_bracket_hotpath. */
5883      if (opcode == OP_ONCE)      if (opcode == OP_ONCE)
5884        {        {
5885        if (CURRENT_AS(bracket_fallback)->u.framesize >= 0)        if (CURRENT_AS(bracket_fallback)->u.framesize < 0)
5886          {          {
5887            OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);
5888            /* TMP2 which is set here used by OP_KETRMAX below. */
5889          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5890              OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);
5891            else if (ket == OP_KETRMIN)
5892            {            {
5893            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);            /* Move the STR_PTR to the localptr. */
5894            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), (CURRENT_AS(bracket_fallback)->u.framesize + 1) * sizeof(sljit_w));            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);
5895            }            }
5896          }          }
5897        else        else
5898          {          {
5899          OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr);          OP2(SLJIT_ADD, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_IMM, (CURRENT_AS(bracket_fallback)->u.framesize + 2) * sizeof(sljit_w));
         /* The register which is set here used by OP_KETRMAX below. */  
5900          if (ket == OP_KETRMAX)          if (ket == OP_KETRMAX)
5901            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), 0);            {
5902          else if (ket == OP_KETRMIN)            /* TMP2 which is set here used by OP_KETRMAX below. */
5903            OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), 0);            OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
5904              }
5905          }          }
5906        }        }
5907    
# Line 5536  if (*cc == OP_ALT || opcode == OP_COND | Line 5963  if (*cc == OP_ALT || opcode == OP_COND |
5963      {      {
5964      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);      SLJIT_ASSERT(opcode == OP_COND || opcode == OP_SCOND);
5965      assert = CURRENT_AS(bracket_fallback)->u.assert;      assert = CURRENT_AS(bracket_fallback)->u.assert;
5966      if (assert->framesize >= 0 && (ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT))      if ((ccbegin[1 + LINK_SIZE] == OP_ASSERT_NOT || ccbegin[1 + LINK_SIZE] == OP_ASSERTBACK_NOT) && assert->framesize >= 0)
5967    
5968        {        {
5969        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);        OP1(SLJIT_MOV, STACK_TOP, 0, SLJIT_MEM1(SLJIT_LOCALS_REG), assert->localptr);
5970        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));        add_jump(compiler, &common->revertframes, JUMP(SLJIT_FAST_CALL));
# Line 5557  if (offset != 0) Line 5985  if (offset != 0)
5985    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
5986    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
5987    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
5988    OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));    OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, SLJIT_MEM1(STACK_TOP), STACK(2));
5989    OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(3));    free_stack(common, 3);
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0);  
   OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), localptr, TMP2, 0);  
   free_stack(common, 4);  
5990    }    }
5991  else if (opcode == OP_SBRA || opcode == OP_SCOND)  else if (opcode == OP_SBRA || opcode == OP_SCOND)
5992    {    {
# Line 5575  else if (opcode == OP_ONCE) Line 6000  else if (opcode == OP_ONCE)
6000      {      {
6001      /* Reset head and drop saved frame. */      /* Reset head and drop saved frame. */
6002      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;      stacksize = (ket == OP_KETRMAX || ket == OP_KETRMIN || *cc == OP_ALT) ? 2 : 1;
     if (CURRENT_AS(bracket_fallback)->u.framesize > 0)  
       OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(stacksize));  
6003      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);      free_stack(common, CURRENT_AS(bracket_fallback)->u.framesize + stacksize);
     if (CURRENT_AS(bracket_fallback)->u.framesize > 0)  
       OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), LOCALS_HEAD, TMP1, 0);  
6004      }      }
6005    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))    else if (ket == OP_KETRMAX || (*cc == OP_ALT && ket != OP_KETRMIN))
6006      {      {
# Line 5649  if (CURRENT_AS(bracketpos_fallback)->fra Line 6070  if (CURRENT_AS(bracketpos_fallback)->fra
6070      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));      OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(0));
6071      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));      OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), STACK(1));
6072      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset), TMP1, 0);
     OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(2));  
6073      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);      OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), OVECTOR(offset + 1), TMP2, 0);
     OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_LOCALS_REG), MAX_INDEX, TMP1, 0);  
6074      }      }
6075    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
6076    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);    free_stack(common, CURRENT_AS(bracketpos_fallback)->stacksize);
# Line 5665  if (current->topfallbacks) Line 6084  if (current->topfallbacks)
6084    {    {
6085    jump = JUMP(SLJIT_JUMP);    jump = JUMP(SLJIT_JUMP);
6086    set_jumps(current->topfallbacks, LABEL());    set_jumps(current->topfallbacks, LABEL());
6087    /* Drop the stack frame and restore LOCALS_HEAD. */    /* Drop the stack frame. */
   OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(STACK_TOP), STACK(CURRENT_AS(bracketpos_fallback)->stacksize - CURRENT_AS(bracketpos_fallback)->framesize));  
6088    free_stack(common, CURRENT_AS(bracket